ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

纸面交易与订单预检:从回测到实盘的最后一公里

纸面交易与订单预检:从回测到实盘的最后一公里 纸面交易与订单预检从回测到实盘的最后一公里魔码量化实战 #28作者魔码数服 系列魔码量化工程实战进阶一、回测到实盘之间隔着一道鸿沟前面 27 篇我们把数据管道、因子、回测、组合优化一路打通。但一个有经验的量化研究员都清楚回测曲线越漂亮实盘越要小心。回测和实盘之间隔着一道由延迟、废单、流动性、账户状态共同构成的鸿沟。回测假设的是上帝视角信号出现就能以快照价 instant 成交、历史数据永远干净连续、资金无限、不会断网。实盘面对的是废单与拒单数量不是整手、价格超出涨跌停、停牌期间下单交易所直接拒单部分成交你想买 10 万股盘口只有 3 万剩下 7 万根本没撮合到账户状态不同步回测里想卖多少卖多少实盘可用持仓可能不够资金不足回测不检查现金实盘一笔买盘就可能超余额时间错位定时任务没触发、行情回调晚到信号和订单对不上。这道鸿沟必须先用**纸面交易Paper Trading和订单预检Order Pre-check**填平再上真金白银。本文带你搭一个带预检的纸面账户全程用魔码量化行情 API 的纯 HTTP 实时接口取价零 SDK 依赖。二、本文你将得到什么一段可直接运行的代码用魔码 HTTP 实时接口拉取真实行情含昨收、涨跌幅一个PaperAccount类下单前先做六项预检预检实测结果六种典型错误订单如何被逐一拦截盘中市值标记与收盘结算的最小实现把纸面交易接成日常流水线的工程建议与避坑清单。三、数据魔码真实接入先用纯 HTTP GET 拉取实时快照确认接口与字段实时接口成交额字段是cje昨收是yc涨跌幅是zf和历史接口的a/pc命名不同写代码时别混importrequests BASEhttps://api.momaapi.com# 演示证书请换成你自己的正式证书https://www.momaapi.com/certificate-apply.htmlLICTEST-API-TOKEN-MOMA-836089C22111drequests.get(f{BASE}/hsstock/real/time/600519/{LIC},timeout20).json()print(最新价 p ,d[p], 昨收 yc ,d[yc], 涨跌幅 zf ,d[zf],%)真实返回演示证书返回样本行情价格形态与真实一致换正式证书即真实盘口最新价 p 11.72 昨收 yc 11.65 涨跌幅 zf 1.29%zf为正表示当日上涨红与我们取到的p yc一致。据此可算涨跌停区间A 股 ±10%跌停 11.65 × 0.90 10.49 涨停 11.65 × 1.10 12.82四、为什么必须做订单预检很多策略不是死在逻辑而是死在执行。把下单前该拦的错拦在本地比等交易所拒单再补救便宜一百倍。一个最小可用预检至少覆盖六项数量为正且为整手A 股 1 手 100 股非 100 整数倍直接拒价格为正负价或零价属于程序 bug价格在涨跌停区间内超出[昨收×0.9, 昨收×1.1]的委托无效标的存在代码不在关注列表 / 已退市应提前拦截买入资金充足价格×数量×(1佣金) ≤ 可用现金卖出持仓充足数量 ≤ 该标的可用持仓。五、纸面账户与预检逻辑下面这段代码是本文的核心一个PaperAccountsubmit之前先跑precheck任何一项不过直接返回违规清单绝不发出假成交。importrequests BASEhttps://api.momaapi.comLICTEST-API-TOKEN-MOMA-836089C22111LOT,COMMISSION100,0.0003defrtime(code):returnrequests.get(f{BASE}/hsstock/real/time/{code}/{LIC},timeout20).json()SNAPS{c:rtime(c)forcin[600519,600036,000001,600276]}defband(code):ycfloat(SNAPS[code][yc])returnround(yc*0.90,2),round(yc*1.10,2)classPaperAccount:def__init__(self,cash):self.cashcash self.positions{}defprecheck(self,side,code,price,qty):v[]ifqty0:v.append(数量必须为正)ifqty%LOT!0:v.append(f数量必须是{LOT}的整数倍A股1手{LOT}股)ifprice0:v.append(价格必须为正数)ifcodenotinSNAPS:v.append(f标的{code}不在关注列表/标的不存在)else:dlo,dhiband(code)ifpricedhiorpricedlo:v.append(f价格超出涨跌停区间[{dlo},{dhi}])ifsidebuy:costprice*qty*(1COMMISSION)ifcostself.cash:v.append(f可用资金不足需{cost:.2f} 余额{self.cash:.2f})elifsidesell:ifself.positions.get(code,0)qty:v.append(f持仓不足持有{self.positions.get(code,0)} 卖出{qty})returnvdefsubmit(self,side,code,price,qty):vself.precheck(side,code,price,qty)ifv:returnFalse,vifsidebuy:self.cash-price*qty*(1COMMISSION)self.positions[code]self.positions.get(code,0)qtyelse:self.cashprice*qty*(1-COMMISSION)self.positions[code]-qtyreturnTrue,[f{side}{code}{qty}{price}成交]六、预检实测六种订单的结局用上面真实拉到的锚价600519 最新 11.72、涨跌停 [10.49, 12.82]跑六笔订单看预检如何逐一拦截acctPaperAccount(cash100000.0)Pfloat(SNAPS[600519][p])print(1) 合法买入 600519 100股,P,acct.submit(buy,600519,P,100))print(2) 非整手 买入 600519 150股,P,acct.submit(buy,600519,P,150))print(3) 超涨停 买入 600519 100股,13.82,acct.submit(buy,600519,13.82,100))print(4) 无持仓卖出 600036 100股,P,acct.submit(sell,600036,P,100))print(5) 资金不足 买入 600519 1000000股,P,acct.submit(buy,600519,P,1000000))print(6) 合法卖出已有 600519 100股,P,acct.submit(sell,600519,P,100))真实返回1) 合法买入 600519 100股11.72 - (True, [buy 600519 10011.72 成交]) 2) 非整手 买入 600519 150股11.72 - (False, [数量必须是100的整数倍A股1手100股]) 3) 超涨停 买入 600519 100股13.82 - (False, [价格超出涨跌停区间[10.49, 12.82]]) 4) 无持仓卖出 600036 100股11.72 - (False, [持仓不足持有0 卖出100]) 5) 资金不足 买入 600519 1000000股11.72 - (False, [可用资金不足需11723516.00 余额98827.65]) 6) 合法卖出已有 600519 100股11.72 - (True, [sell 600519 10011.72 成交])第 1 笔合法买入成交后账户里有了 600519 持仓于是第 6 笔卖出才能通过其余四笔分别被非整手 / 超涨跌停 / 无持仓 / 资金不足精准拦截。这正是实盘前最该拦住的四类低级错误。七、盘中市值标记与收盘结算成交后用实时价把持仓标记到市值得到组合总资产涨用红、跌用绿mvacct.cashforc,qinacct.positions.items():mvfloat(SNAPS[c][p])*qprint(组合市值 ,round(mv,2),初始 100000.00)真实返回本例先买后卖、净持仓归零仅扣少量佣金组合市值 99999.30 初始 100000.00净额少了 0.70就是两笔交易的佣金万三。这一点也提醒你成本模型必须进纸面账户否则纸面盈利会虚高。八、把纸面交易接成日常流水线真正有用的纸面交易不是跑一次而是一个每天自动转的闭环盘前拉/hslt/list更新关注列表校准每只标的的昨收与涨跌停信号策略产出当日目标持仓可接第 27 篇的优化器输出预检每只目标订单先过precheck拦掉的写进日志告警撮合纸面账户按实时价魔码/hsstock/real/time模拟成交记录成交价与滑点假设标记收盘用实时/收盘快照重估市值计算当日 PnL、换手、与基准如沪深300的相对收益复盘连续跑 20–60 个交易日后对比纸面 PnL 与回测 PnL 的衰减再决定是否上实盘。关键认知纸面交易的价值不在于模拟赚钱而在于暴露执行链路上的 bug——信号没触发、订单没生成、状态没持久化、重启后重复下单。这些问题在回测里永远看不见却在实盘第一天就给你上课。九、避坑清单预检在前撮合在后任何一笔订单必须过预检绝不允许先发再查。涨跌停用昨收算每只标的独立计算[yc×0.9, yc×1.1]别用全局一个价。持久化订单状态实盘会重启、断线订单与持仓必须落库否则重启后重复下单。成本模型要真实佣金、印花税、滑点、冲击成本全部计入纸面 PnL 才不虚高。部分成交要处理实盘常只成交一部分账户要支持部分持仓状态而非全有全无。渐进部署纸面跑顺 → 1%–5% 资金实盘 → 逐步加仓不要一步到位。前视偏差标记市值只能用 t 时刻及之前的快照不能用未来价格。十、下篇预告纸面交易跑顺了但还有一个隐患你训练因子用的数据分布可能早已悄悄漂移。下一篇【魔码量化工程实战进阶 #29】数据漂移监控当历史不再预示未来我会带你用魔码日线接口做训练集与近期数据的分布对比给策略装一个变质报警器。免责声明本文所有代码示例与数据均用于技术方法演示不构成任何投资建议。市场有风险投资需谨慎。文中预检逻辑与回测结论不预示未来收益据此操作风险自担。本文出自魔码云服官方技术博客原文持续更新于https://www.momaapi.com/blog/ 转载请注明出处。
返回列表