feat(trader): 科创板200股最小手数(分期项切片)—lot_size_for+matcher板块取整

科创板(688/689)最小200股1股递增(不整倍); 主板/创业/北交100整倍; 卖出不取整。
- limit.py 加 lot_size_for(symbol)
- matcher cross_order 买入取整按板块(star≥200不取整, 其余100整倍)
- routes_paper cta size=lot_size_for(symbol)
- test: 688981 买150拒/买250不取整; 主板用例不变; 63/63通过
This commit is contained in:
2026-07-07 23:37:50 +08:00
parent 1ed7b72aca
commit 05dba7fe46
4 changed files with 47 additions and 9 deletions
+23
View File
@@ -174,6 +174,29 @@ def test_sell_odd_lot_allowed():
assert isinstance(t, PaperTrade) and t.volume == 50
# ---- 科创板 200 股最小手数(分期项)----
def test_star_buy_below_200_rejected():
"""科创板 688981 买 150 股 < 200 → 拒单(200 股起)。"""
r = cross_order(
PaperOrder("s1", "688981", OrderSide.BUY, 0, 150, True),
mkbar(10, 10, 10, 10),
PREV,
CFG,
)
assert isinstance(r, PaperReject) and r.reason == "volume_below_min_lot"
def test_star_buy_250_not_rounded_to_200():
"""科创板 688981 买 250 股 → ≥200,1 股递增不取整,成交 250(非主板 100 整倍)。"""
t = cross_order(
PaperOrder("s1", "688981", OrderSide.BUY, 0, 250, True),
mkbar(10, 10, 10, 10),
PREV,
CFG,
)
assert isinstance(t, PaperTrade) and t.volume == 250
# ---- 费用 ----
def test_commission_uses_min_5_yuan():
# 100 股 × 10 元 × 0.0003 = 0.3 → 不足 5 元,收 5