mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 18:04:16 +08:00
release: v1.17.6 — 港股逐笔成交全量取数 + start 倒序语义文档
回应 issue #14 后用户反馈:默认 count=2000 取回的成交时间全集中在尾盘。 根因是通达信逐笔协议(A 股 0x122F 与港股 ex 0x23FC/0x2406 一致)的 start 为 倒序语义——start=0 指向最新一笔(收盘方向),并非 bug。02715 全天成交 13327 笔,count=2000 只取最近 2000 笔故集中在尾盘。 新增: - goods_transaction_all(MacExClient 同步+异步)—— 港股股票类市场自动按 1800/页 翻页取全天全部逐笔成交,安全上限 50 页(90000 条)。返回协议原生倒序,需正序 由调用方 df.iloc[::-1]。market 非港股时抛 ValueError。 - _fetch_all_hk_transactions_sync/async(_hk_transaction.py)底层实现。 变更: - goods_transaction docstring 补 start 倒序语义说明,引导需全天数据用 goods_transaction_all。 修复: - 1.17.5 的 test_hk_transaction.py 未过 CI ruff format --check(注释对齐、 MacTransaction 单行化、文末空行)。 867 单测全绿(+5 全量取数测试),ruff format/check / mypy strict 通过。
This commit is contained in:
@@ -333,3 +333,101 @@ async def test_async_goods_transaction_non_hk_keeps_0x122f():
|
||||
assert isinstance(captured[0], SymbolTransactionCmd)
|
||||
assert len(df) == 1
|
||||
assert df["price"].iloc[0] == pytest.approx(3850.0)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 6. goods_transaction_all 全量取数(mock _execute,离线)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_goods_transaction_all_paginates_until_short_page():
|
||||
"""全量取数:翻页直到某页返回不足 page_size(末页)即停。"""
|
||||
from easy_tdx.ex.mac_client import MacExClient
|
||||
|
||||
page_calls: list[int] = [] # 记录每页的 start
|
||||
|
||||
def fake_execute(cmd):
|
||||
page_calls.append(cmd.start)
|
||||
# 前 3 页满页(1800),第 4 页返回 500(末页)
|
||||
if cmd.start < 1800 * 3:
|
||||
return _build_fake_records(cmd.count)
|
||||
return _build_fake_records(500)
|
||||
|
||||
client = object.__new__(MacExClient)
|
||||
client._execute = fake_execute # type: ignore[method-assign]
|
||||
|
||||
df = client.goods_transaction_all(31, "00700", date(2026, 7, 3))
|
||||
|
||||
assert len(page_calls) == 4 # 3 满页 + 1 末页
|
||||
assert page_calls == [0, 1800, 3600, 5400]
|
||||
assert len(df) == 1800 * 3 + 500
|
||||
|
||||
|
||||
def test_goods_transaction_all_stops_on_empty():
|
||||
"""全量取数:第一页空(休市日/无数据)应立即返回空。"""
|
||||
from easy_tdx.ex.mac_client import MacExClient
|
||||
|
||||
call_count = 0
|
||||
|
||||
def fake_execute(cmd):
|
||||
nonlocal call_count
|
||||
call_count += 1
|
||||
return []
|
||||
|
||||
client = object.__new__(MacExClient)
|
||||
client._execute = fake_execute # type: ignore[method-assign]
|
||||
|
||||
df = client.goods_transaction_all(31, "00700", date(2026, 7, 1))
|
||||
|
||||
assert call_count == 1
|
||||
assert len(df) == 0
|
||||
|
||||
|
||||
def test_goods_transaction_all_rejects_non_hk_market():
|
||||
"""全量取数仅限港股股票类市场;其他市场应报 ValueError。"""
|
||||
from easy_tdx.ex.mac_client import MacExClient
|
||||
|
||||
client = object.__new__(MacExClient)
|
||||
client._execute = lambda cmd: [] # type: ignore[method-assign]
|
||||
|
||||
with pytest.raises(ValueError, match="港股股票类市场"):
|
||||
client.goods_transaction_all(47, "IFL0") # CFFEX 期货
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_goods_transaction_all_paginates():
|
||||
"""异步全量取数也按页翻到末页停止。"""
|
||||
from easy_tdx.ex.mac_client import AsyncMacExClient
|
||||
|
||||
page_calls: list[int] = []
|
||||
|
||||
async def fake_execute(cmd):
|
||||
page_calls.append(cmd.start)
|
||||
# 前 1 页满页,第 2 页返回 100(末页)
|
||||
if cmd.start == 0:
|
||||
return _build_fake_records(cmd.count)
|
||||
return _build_fake_records(100)
|
||||
|
||||
client = object.__new__(AsyncMacExClient)
|
||||
client._execute = fake_execute # type: ignore[method-assign]
|
||||
|
||||
df = await client.goods_transaction_all(31, "00700", date(2026, 7, 3))
|
||||
|
||||
assert page_calls == [0, 1800]
|
||||
assert len(df) == 1800 + 100
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_goods_transaction_all_rejects_non_hk():
|
||||
"""异步全量取数:非港股市场报 ValueError。"""
|
||||
from easy_tdx.ex.mac_client import AsyncMacExClient
|
||||
|
||||
client = object.__new__(AsyncMacExClient)
|
||||
|
||||
async def fake_execute(cmd):
|
||||
return []
|
||||
|
||||
client._execute = fake_execute # type: ignore[method-assign]
|
||||
|
||||
with pytest.raises(ValueError, match="港股股票类市场"):
|
||||
await client.goods_transaction_all(74, "AAPL") # 美股
|
||||
|
||||
Reference in New Issue
Block a user