mirror of
https://ghfast.top/https://github.com/aeroxw/easy_tdx_max.git
synced 2026-09-12 20:24:19 +08:00
fix(client): 历史资金流当日行全零 + 主力净额列缺失(issue #52)
三个根因(全部实测核实): 1. Category 22 直连接口为虚构协议——52 台已知服务器中 46 台可达的 全部仅回 2 字节空包,从未成功过;移除死代码与臆造解析格式。 2. 历史逐笔接口当日数据要收盘清算后才有,日 K 盘中已含当日 bar, 故 start=0 的最新一行恒为全 0——当日 bar 改走当日实时逐笔接口。 3. main_net_inflow 此前仅为 dataclass property,asdict 静默丢弃, 返回 DataFrame 无主力净额列——新增 _fund_flow_df_with_net 物化 (history 紧随 date 列、当日快照放首列)。 sync + async 双客户端同步修改;更新示例与三份文档;重写/新增回归 测试(当日实时逐笔路径、主力净额列断言)。
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
"""协议底层修复验证(针对 2026-04-15 审查结论)。"""
|
||||
|
||||
import struct
|
||||
from unittest.mock import patch
|
||||
|
||||
from easy_tdx.codec.price_rules import compute_price_limits
|
||||
from easy_tdx.commands.fund_flow import GetHistoryFundFlowCmd
|
||||
from easy_tdx.commands.security_bars import GetSecurityBarsCmd
|
||||
from easy_tdx.commands.security_list import GetSecurityListCmd
|
||||
from easy_tdx.commands.security_quotes import GetSecurityQuotesCmd
|
||||
@@ -38,33 +36,6 @@ def test_security_bars_exact_layout():
|
||||
assert len(req) == 38
|
||||
|
||||
|
||||
def test_history_fund_flow_exact_layout():
|
||||
"""验证历史资金流请求包布局与 K 线一致,只差 category=22。"""
|
||||
cmd = GetHistoryFundFlowCmd(Market.SH, "600000", 0, 10)
|
||||
req = cmd.build_request()
|
||||
# Header: 0x010C, 0x01016408, 0x1C, 0x1C
|
||||
# Payload: 0x052D, 1 (Market.SH), "600000", 22, 1, 0, 10, 0, 0, 0
|
||||
expected = struct.pack(
|
||||
"<HIHHHH6sHHHHIIH",
|
||||
0x010C,
|
||||
0x01016408,
|
||||
0x001C,
|
||||
0x001C,
|
||||
0x052D,
|
||||
1,
|
||||
b"600000",
|
||||
22,
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
assert req == expected
|
||||
assert len(req) == 38
|
||||
|
||||
|
||||
def test_security_list_request_length():
|
||||
"""验证证券列表请求包载荷长度为 6 字节。"""
|
||||
cmd = GetSecurityListCmd(Market.SH, 0)
|
||||
@@ -157,32 +128,3 @@ def test_compute_price_limits_for_newly_listed_stocks():
|
||||
109.67,
|
||||
59.05,
|
||||
)
|
||||
|
||||
|
||||
def test_history_fund_flow_uses_uint32_volume_words():
|
||||
"""历史资金流金额字段必须按 uint32 传给 _decode_volume。"""
|
||||
raw_words = [
|
||||
0x80000001,
|
||||
0xFFFFFFFF,
|
||||
0x7FFFFFFF,
|
||||
0x90000000,
|
||||
0xA0000000,
|
||||
0xB0000000,
|
||||
0xC0000000,
|
||||
0xD0000000,
|
||||
]
|
||||
body = bytearray(9)
|
||||
body.extend(struct.pack("<H", 1))
|
||||
body.extend(struct.pack("<IIIIIIIII", 20250108, *raw_words))
|
||||
|
||||
seen: list[int] = []
|
||||
|
||||
def fake_decode(raw: int) -> float:
|
||||
seen.append(raw)
|
||||
return float(raw)
|
||||
|
||||
with patch("easy_tdx.commands.fund_flow._decode_volume", side_effect=fake_decode):
|
||||
records = GetHistoryFundFlowCmd(Market.SH, "600000", 0, 1).parse_response(bytes(body))
|
||||
|
||||
assert seen == raw_words
|
||||
assert records[0].small_out == float(raw_words[-1])
|
||||
|
||||
Reference in New Issue
Block a user