← 返回教程库

回测跑通了,实盘还差五件事没写

最后更新 2026-08-19
📚 量化与 AI 投研 📖 E 线 · 实盘边界 ⏱ 约 26 分钟 R2 · 注意风险
你将学到
  • 说得出回测里被「免费送」的五个前提各是什么,以及它们在实盘里分别退化成什么样的不确定性
  • 对行情断线、订单悬空、持仓对不上、异常分级、留痕这五块,各说得出「不写会以什么形式出事」
  • 看懂一个真实交易框架为什么要在启动时重新拉一遍未完成订单、为什么对账差额大就拒绝自动修正

回测那条曲线终于向上了。你把参数定住,把代码整理干净,写了几个测试,心里那句话已经冒出来了:接上券商接口,让它自己跑。

然后你会发现一件挺尴尬的事:回测那份代码里,有一大半在实盘里根本用不上;而实盘要用的那一大半,你一行都还没写。

不是「优化」的那种没写,是「没有它整个东西就不能上线」的那种没写。

这一篇要做的,就是把这批缺口一块块摊开。不讲怎么调接口——那是券商文档的事;讲的是每一块在解决什么问题、不写会以什么形式出事。至于跑起来之后延迟和容量怎么把策略吃掉,那是延迟和容量的话题;跑起来之后该盯哪几个数,是实盘跑起来之后该盯什么的话题;什么情况下必须拔电源,是什么情况下必须立刻停手的话题。这一篇只管一件事:上线之前,代码上还缺哪几块。

回测送了你五个前提,实盘一个都不送

先把差异讲清楚,后面五块才不是零散的清单。

回测本质上是在一个已经写完的世界里做题。 历史行情是一张完整的表,你要哪一行有哪一行,不会缺、不会晚、不会重复推送两遍。你说买,它就成交;你记下持仓是多少股,那就永远是多少股,不会有人在你不知道的时候动它。整个过程里,你的程序是这个小世界唯一的主体。

实盘不是做题,是和一个你控制不了的对手方持续通信。 你的程序只是这段关系里的一端,另一端是券商或交易所的系统,中间隔着一条会断的网线。这一下变化,把回测里默认成立的五个前提全部打破了:

  • 数据一定到 → 数据可能不来、来晚、来重复
  • 下单等于成交 → 发出去只是发出去了,成没成、成了多少,得你自己去问
  • 我记的持仓就是真持仓 → 真持仓在对面那台机器上,你手上的只是一份副本
  • 出错就停 → 实盘里大部分错误停机才是灾难,得分级
  • 结果可复现 → 实盘每一秒都是一次性的,事后想复盘只能靠你当时留下的记录

这五条,正好对应你要补的五块代码。下面一块块说。

一个用词先约定:下面反复出现的回测,指用历史行情把一套交易规则重放一遍,看看按这套规则操作会是什么结果——它是模拟,不下真单。

第一块:行情订阅,以及断线之后怎么办

先说人话

你在外地,靠一个朋友每隔几分钟给你报一次某个数。有一天他手机没信号了。

问题不在于他没报,问题在于:你怎么知道他没报? 你手上最后那个数是十分钟前的,可它看起来和刚发来的数长得一模一样——都是一个数字,上面没写「我已经过期了」。你会拿着这个陈数继续做判断,而且做得理直气壮。

这就是行情断线最坏的地方:它不是「没数据」,它是「有一个看起来很正常的旧数据」。

投资层:陈旧的价格比没有价格危险得多

没有价格,你至少知道自己瞎了,会停手。拿着一个陈价格,你会:

按十分钟前的价算出「现在偏离均线多少」,得出一个当下根本不成立的判断;按陈价格算持仓市值,于是止损线也是陈的——市场早就跌穿了,你的程序还觉得安全;更糟的是重连之后行情一次性补齐,几十根 K 线瞬间涌进来,你的信号逻辑在几秒钟之内被触发好多次,程序以为那是几十个连续的交易机会。

所以行情这一块要补的不只是「订阅」,是三件事:订阅、判断新鲜度、断了怎么恢复。

系统层:一个框架是怎么处理的

freqtrade 里有一个专门的行情订阅模块,它的做法值得拆开看(以下均为对源码快照的阅读)。

第一,订阅是有生命周期的,不是订了就一直订。 它维护着一份「正在盯的品种」清单,并且有一个定期清理动作:某个品种如果在超过一根 K 线的时长(再加一小段余量)里没有被上层代码问过,就从清单里摘掉,同时把已经收到的那段历史一起丢弃。注释写明了丢弃的理由——避免拿到过期数据。这个取舍方向很关键:宁可承认自己现在没数据,也不留一段说不清有多旧的数据在手上。

第二,每次取数据都同时告诉你「这份数据上次刷新是什么时候」。 取行情的接口返回的不是一个数组,而是数组加上一个刷新时间戳。这意味着上层每一次用数据,都有机会顺手判断一句「这还新鲜吗」。把新鲜度和数据本身绑在一起返回,比让调用方自己去猜,可靠一个量级。

第三,连接断了不当成致命错误。 订阅是在一个独立的后台线程里跑的,某个品种的订阅任务挂掉,框架会记一条日志、把它从清单里摘掉、把它的历史清空,然后主循环该干嘛干嘛——下次上层再问这个品种,它会被重新排上订阅。断线被设计成一个可以反复发生的常态,而不是一次需要人来处理的事故。

顺带说一句,实盘里主循环醒得比 K 线频率密得多,这是交易机器人开机之后在忙什么那篇讲过的事:醒得勤是为了不漏掉状态变化,不是为了多想。而行情断线正是「状态变化」里最常见的一种。

不做会怎样

你的策略会在一段陈旧的价格上正常运行,并且不给任何提示。 因为陈价格不会抛异常,均线照算,信号照发,日志照样干净。等你发现的时候,通常是因为账户里多了一笔莫名其妙的单子,而你去翻当时的行情,发现那一刻的真实价格和程序看到的差着一大截。

最低限度该补的:每个品种记一个「最后更新时刻」;用数据之前先看这个时刻离现在多远;超过你自己定的容忍值就不发新信号(注意是不发新信号,不是清仓——清仓需要的恰恰是可靠行情)。容忍值多大取决于你的持仓周期,日线策略和分钟级策略差着两三个数量级,这里不给数。

第二块:订单状态跟踪——发出去和成交了是两件事

先说人话

你把一封信投进邮筒。投进去那一刻,你唯一知道的事情是「信离开了我的手」。

它有没有送到、是不是被退回、地址是不是写错了——这些信息不会自己回来找你,你得去查。 而回测里的世界是这样的:你把信塞进邮筒,同一秒钟对方就把回执递到你手上。

投资层:中间那段「悬空态」是实盘独有的

你挂一个限价单出去,从这一刻到它有确定结果之间,存在一段时间。这段时间里,这笔单子可能是:完全没成交、成交了一部分、全部成交、被交易所拒绝、被自己撤掉、或者——最讨厌的一种——你不知道它是哪种,因为你发出去的那一刻网络刚好断了,你连它到底有没有到对面都不确定。

回测里没有这段。信号一出,成交价按某个规则算出来,仓位立刻变。所以回测代码里通常压根没有「订单」这个东西,只有「仓位」。而实盘代码里,订单是一个必须独立存在、有自己状态、能被反复查询的对象。这是回测代码和实盘代码结构上最大的一处差异,也是信号和订单是两回事那篇讲的核心;这里只补工程侧。

尤其要留意部分成交。你打算买一万股,成了三千,剩七千还挂着。这时候你的持仓是三千不是一万,你的止损该按三千算,你的可用资金也不是你以为的那个数。如果你的代码里只有「有仓/没仓」两种状态,这种情况会把它彻底搞乱。不同订单类型在这件事上的行为差别,订单类型那篇有系统的说法。

系统层:三个动作,缺一不可

看 freqtrade 的实现,围绕订单状态有三个动作是绕不过去的。

动作一:每一轮都去问一遍还没结束的单子。 主循环里有一个专门处理未完成订单的环节,逻辑是——遍历所有还开着的订单,逐个去交易所查最新状态,用返回结果更新本地记录;然后判断这单是不是超时了,超时就撤,或者按策略给的新价格改单。注意这里的顺序:先更新状态,再做决策。 不先问一遍就直接判断超时,你可能撤掉一笔其实刚刚成交的单。

动作二:查不到的时候不能当成没有。 这段代码里查询失败的处理是记一条日志然后跳过这一单,继续处理下一单——不是假设它被取消了。 这个细节很重要:网络查询失败,唯一能确定的事情是「我不知道」,而「我不知道」绝不能被当成「它不存在」。

动作三:启动时必须把未完成订单全部重新拉一遍。 框架有一个专门的启动步骤,从本地库里取出所有还开着的订单,逐个去交易所查最新状态并回写。这一步的必要性很直白:你的程序停机的那段时间,市场没有停。 你崩溃前挂着的三笔单,重启后可能已经成了两笔。

这个启动步骤里有个处理值得单独说:如果查询时对面明确回答「这个订单不合法」,框架会看这单挂了多久——超过一个较长的天数阈值,就假定它已经被彻底取消,走取消流程;没超过,就只记一条警告。 时间跨度长到一定程度,「不知道」才被允许坍缩成一个结论。这是一条你可以直接抄的处理原则:不确定的东西不要立刻下结论,但也不能永远悬着,给它一个明确的时限。(具体阈值以你手上版本为准,本文不给数。)

不做会怎样

最典型的事故是重复下单。 你发了单,网络超时没拿到回执,程序判定失败,下一轮又发一遍——结果两笔都成了,你的实际仓位是计划的两倍。这类事故在震荡行情里可能只是多亏一点手续费,在单边行情里能直接把你的风控设定作废。

第二典型的是幽灵持仓。 程序以为有仓,实际上单子被拒了;或者反过来,程序以为空仓,实际上挂单成交了。前者会让你的止损保护一个不存在的仓位,后者会让一笔真金白银的持仓完全脱离风控。

最低限度该补的:本地存一张订单表,每笔订单有唯一标识和明确状态;每一轮循环把所有未终结的订单查一遍;发单前带上一个你自己生成的客户端订单号(这是防重复下单最有效的一招——对面靠它去重);启动时先对未完成订单做一次全量刷新,刷完之前不做任何交易决策

第三块:持仓对账——你以为的持仓,和券商的可能不一样

先说人话

你和记账软件里记的余额是三千二,去银行一查,是三千一百八。

差二十块。这二十块本身不重要,重要的是你现在不知道该信谁。可能是某笔小额扣费你没记,也可能是你记错了一笔大的、又碰巧记错了另一笔小的,两个错误互相抵掉了大部分。一个小差额背后,可能是一个小问题,也可能是两个大问题。

投资层:真持仓永远在对面那台机器上

这一条要刻在脑子里:你程序里那份持仓记录是副本,权威版本在券商那边。

副本会和权威版本分叉,原因多得很——你手动在手机 App 上卖了一半忘了跟程序说;对面的风控替你强平了一部分;分红送股改变了股数;某笔成交的回报你的程序没收到;程序崩溃期间发生的成交,重启时你只对了订单没对持仓。

分叉本身不可怕,可怕的是分叉之后程序继续按副本行动:你以为有一万股,下了个卖一万股的单,实际只有八千,这个单会被拒;或者更糟,在支持卖空的市场里,它不会被拒,你直接开了两千股的反向仓位。

系统层:对账不是「谁对听谁的」,是分档处理

freqtrade 在这块的处理很有参考价值,因为它明确区分了「差多少」。

平仓之前先验一次余额。 有一个专门的检查:要平掉某笔持仓时,先看钱包里这个币种的实际数量够不够。不够就主动刷新一次钱包再验一遍,还不够才认账。这个「先刷新再判断」的两步,避免了因为本地缓存过期而误判。

差额小就调整,差额大就拒绝调整。 这是我认为最值得抄的一处设计。框架里有一段处理「持仓和钱包对不上」的逻辑,它的分支是这样的:如果钱包里的实际数量比记录的略少、但仍在一个很小的容忍范围内,就把交易记录里的数量下调成实际数量,并打一条警告说明「这可能引发后续问题」;如果差得太多,它明确拒绝调整,只记一条警告说「差异过大,拒绝调整」。

为什么差得多反而不改?因为小差额大概率是精度、手续费扣减这类已知原因,而大差额意味着你对系统状态的理解本身就是错的——这时候自动「修正」成一个你并不理解的数字,只是把错误洗白成正常。留着差异、留着警告,让人来看,是更诚实的选择。

还有一处:找回不在记录里的订单。 框架里有一个动作,是拿着某笔持仓的开仓时间去交易所拉这段时间的全部订单,逐个比对——本地已知的就更新,本地不知道的就作为新订单补进来,并把这笔持仓标记成「在交易所被卖掉了」。这是在处理「有人在程序之外动了这个账户」的情况。而如果比对之后发现这笔持仓其实只有一堆全部被取消的开仓单,框架会把这条记录直接删掉——因为它从头到尾就没真正建立过。

最后:停机时如果还有持仓,明确告诉人。 框架在进入停止状态时会检查有没有未平仓的交易,有就推一条消息,内容大意是「还有几笔持仓,请手动处理,或者重启后用只出不进的方式收尾」。这句话的价值在于它没有假装能替你解决——它只是保证这件事不会被你忘掉。

不做会怎样

对不上账的系统,风控是假的。 止损、仓位上限、单笔最大金额,全部建立在「我知道自己持有多少」这个前提上。前提一破,上面所有约束同时失效,而且不报错。

更阴的是这种失效会累积。今天差一点,你没发现;明天在这个错误的基数上又算了一次仓位,差得更多。等到某天一笔委托被拒,你回头去查,会发现差异已经存在好几周了。

最低限度该补的:每轮循环(至少每天开盘前和收盘后)拉一次券商的真实持仓和资金,和本地记录逐项比对;差额分两档处理,小差额可自动对齐但必须留警告,大差额立刻停止开新仓并告警;每次比对的结果都落盘,别只打印在屏幕上。

第四块:异常处理与降级——不是所有错误都该停机

先说人话

家里的电器出问题,处理方式是分级的。灯泡闪一下,你不会拉总闸;插座冒烟,你会。中间还有一档:某个房间跳闸了,你会先看看是不是那台老空调的问题,不影响别的房间就先这样。

同一个反应对应所有故障,本身就是一种设计缺陷。 全停太脆,全忽略太险。

投资层:交易系统里最贵的两种错误反应

第一种:该停不停。 数据源出问题了,程序继续按错误数据交易;对面接口返回异常,程序把异常当成正常结果继续走下去。这类会直接烧钱。

第二种:不该停却停了。 一次网络抖动导致程序退出,而这时候你手上还有持仓。没人看着的持仓,比没有持仓危险得多——止损逻辑跟着程序一起死了。很多人第一次实盘翻车不是因为策略错,是因为凌晨程序崩了、没人知道、早上打开电脑发现单子还在那儿趴着。

所以异常处理这块要回答的核心问题是:哪些错误该重试,哪些该降级,哪些该停机并叫人。

系统层:一棵异常树,加一个状态机

freqtrade 的做法是两层。

第一层是把异常按处理方式分类,做成一棵继承树。 树的根是框架自己的基础异常,往下分出几支,每一支的注释直接写明了「遇到它该怎么办」:

  • 一支是需要人工介入并且会停止程序的,注释说明这类多半由配置错误引起;配置错误还单独细分了一类;
  • 一支是依赖没被满足的,比如账上钱不够;它下面还挂着几个更细的:价格取不到的、交易所返回错误的、订单不合法的、**订单找不到(可重试,并且会按退避策略递增等待)**的、余额不足的;
  • 一支是临时性错误,注释写明这可能是交易所拥塞、不可用或者你的网络有问题,通常过一会儿自己就好了;它下面挂着一类专门对应对面限流的,处理方式是等一下再试;
  • 还有一支是策略代码自己抛的错

这棵树最有价值的地方不在于分了几类,而在于:类名和注释直接编码了处理策略。 一个新来的人读到「临时性错误」这个名字,不需要看调用点就知道该重试;读到「需要人工介入」,就知道这里不能自动恢复。把「该怎么办」写进类型系统,而不是散落在各处的 if 里,是这块最值得抄的思路。

第二层是主循环里按类型分头处理。 跑一轮的那个包装函数里只有两个 except 分支:临时性错误,记一条警告,睡一小会儿再来;需要人工介入的错误,把完整调用栈推送出去、提示人确认安全后再手动启动、然后把状态置为停止

注意这里的关键:停机是一个状态转换,不是进程退出。 程序还活着,还在跑循环,只是不再交易;这样你的通知通道还通着,随时可以远程把它重新拉起来。而且状态机里还有一条:进入停止状态时会去检查有没有未平仓的持仓并告警(就是上一块说的那件事)。

再加一个细节:循环里会定期往系统的看门狗发心跳,并且隔一段时间打一条包含进程号、版本、当前状态的心跳日志。「程序还活着」这件事本身,是需要主动证明的——没有心跳,进程卡死和进程正常空闲在外面看起来完全一样。至于心跳断了之后该怎么反应,属于监控的范畴。

不做会怎样

只写 try/except pass 的系统,会安静地跑在错误状态里。 这是所有反应模式里最坏的一种:错误被吞掉,程序不停,日志不红,而每一轮循环都在用错误的输入做真实的下单。

只写「出错就 exit」的系统,会在最不该退出的时候退出。 你的持仓在市场里,你的程序在停尸房。

最低限度该补的:把你会遇到的错误分成至少三档——可重试的(网络抖动、限流)、需要降级的(数据源异常、行情陈旧:停止开新仓但保留平仓能力)、必须停机叫人的(配置错误、对账严重不符、连续下单失败);任何一档都不要用「进程直接退出」实现,用状态标志;单独写一条「无论如何都要告警」的通道,并且这条通道不能依赖出问题的那个组件。

第五块:日志与留痕——事后你要能回答「它当时为什么这么干」

先说人话

孩子说昨天下午在同学家写作业。你想核实,不是不信任,是想搞清楚事情的先后。

如果没有任何记录——没有聊天记录、没有通话时间、没有谁提过一句——那这件事就永远只能停留在各执一词。不是谁在撒谎,是这段时间根本没有留下可核对的痕迹。

投资层:实盘的每一秒都只发生一次

回测最舒服的一点是可复现:同样的输入跑一百遍,结果一模一样,出了问题重跑一遍加个断点就行。

实盘没有这个奢侈。 昨天下午两点十七分那一刻的盘口,永远不会再出现第二次。你的程序在那一刻看到了什么、算出了什么、决定做什么、实际做成了什么——如果当时没记,之后就再也拿不到了。

而你几乎一定会需要它。因为实盘一定会出现这种情况:账户里出现一笔你看不懂的交易。 这时候你要回答的问题链条是:那一刻的行情是什么?信号触发了吗?触发之后为什么下的是这个价、这个量?单子发出去之后发生了什么?——这条链上任何一环没记,你的排查就断在那儿。

这也是从研究到可用那篇里反复讲的那条工程原则在交易系统上的具体形态:能不能复现,是靠当时留下的记录,不是靠事后回忆。

系统层:留痕不只是打日志

freqtrade 在留痕上做了三层,值得分开看。

第一层是结构化的交易记录落库。 每一笔交易、每一笔订单都是数据库里的一条记录,有开仓时间、成交明细、状态。这和「打一行日志」的本质区别是:日志是给人读的,落库的记录是能被程序反查的。 前面说的启动时刷新未完成订单、找回不在记录里的订单、对账,全都依赖这张表存在——没有结构化记录,恢复逻辑根本无从写起。

第二层是账户状态的定期快照。 有一个专门的动作把每天的钱包总额记进数据库,并且注释里明确写着只在实盘模式记,回测模式跳过。这个区分本身就说明了留痕是实盘专属的需求:回测想要哪天的状态,重跑一遍就有了;实盘不重跑,所以必须当时就存。

第三层是关键事件的主动推送。 出现需要人工介入的异常时,框架把完整调用栈和一句操作建议一起推出去,而不是只写进日志文件。区别在于日志是「你想看的时候去看」,推送是「它主动来找你」。 需要人来做决定的事情,必须走第二种。

还有一处很小但很实在的:几处警告消息里带着「这可能引发后续问题」这样的措辞——比如自动下调持仓数量之后那条。这是在给未来的自己留线索:如果三天后出现了别的怪事,翻日志看到这条,你就知道该从哪儿开始查。

不做会怎样

没有留痕的系统,每一次异常都是一次悬案。 你会花整个周末去猜,猜完还是不确定,最后往往只能做一件事——把参数改小一点然后继续跑,寄希望于它别再犯。这不是修复,这是拖延。

更实际的伤害是:你没法判断策略是不是失效了。 亏损到底是因为市场变了,还是因为某个组件悄悄坏了一个月?没有记录,这两件事在你眼里长得一模一样。而它们对应的处理完全相反——一个该停手,一个该修 bug。这个判断具体怎么做,是什么情况下必须立刻停手那篇的事,但它的前提是你手上得有料可查。

最低限度该补的:每一笔订单的完整生命周期落结构化存储(不是文本日志);每个交易日的账户快照落盘;每一次「决定不做某件事」也要记——没成交、没触发、被跳过的原因,比成交记录更容易被漏掉,也更常是排查的关键;关键事件主动推送到一个你手机上能收到的地方;日志里带上时间戳、品种、决策依据的那几个数值,别只写「已下单」。

五块放在一起看

补的是什么 回测里为什么不需要 不做的典型事故 最小可用版本
行情订阅与断线重连 历史数据是完整的表,不会缺不会晚 拿着陈价格正常运行,不报错 每份数据带更新时刻,超时就停发新信号
订单状态跟踪 信号即成交,没有中间态 重复下单、幽灵持仓、部分成交被当成全成交 订单落表 + 每轮全量刷新 + 客户端订单号
持仓对账 只有一个主体,没人在你背后动账户 风控建立在错误基数上,静默失效 定期比对,小差额对齐留警告,大差额停手告警
异常分级与降级 出错就停是对的,反正没有真仓位 该停不停在烧钱,不该停却停了留下裸奔的持仓 至少三档:重试 / 降级不开新仓 / 停机叫人
日志与留痕 可复现,重跑一遍就有了 每次异常都是悬案,分不清市场变了还是代码坏了 订单落库 + 每日快照 + 关键事件主动推送

摆在一起,共性就出来了:这五块没有一块是在提高收益,全部是在处理「我对系统状态的认知,和真实状态不一致」这一件事。

行情断线,是你对市场的认知过期了;订单悬空,是你对自己动作的认知不确定;持仓分叉,是你对自己资产的认知错了;异常处理,是决定认知不可靠时该怎么办;留痕,是保住事后重建认知的能力。

回测之所以不需要它们,是因为回测里认知和真实永远相等。 这就是那条分界线的真正位置——它不在「历史数据 vs 实时数据」,它在**「你的程序是不是这个世界唯一的主体」**。

还有一句要提醒:这五块之间是有依赖顺序的。没有留痕,你查不出对账差异从哪来;没有对账,你不知道该不该降级;没有订单跟踪,你的对账基准本身就是错的;没有行情新鲜度判断,前面全部白搭。 所以如果你打算分批做,别从「最有意思」的那块开始,从最底下那块开始。

这五块和成交假设的关系也值得说一句:回测里那些关于「你凭什么成交了」的假设(滑点、撮合价、可交易性),在实盘里全部变成了真实发生的事实。假设那一侧的机制在回测里的成交假设滑点里已经讲透,这一篇补的是事实那一侧——把假设换成事实,代价就是上面这五块代码。

⚠️ 风险提示

本文讲的是交易系统从回测走向实盘时的工程缺口与常见失效模式,不构成任何投资建议、交易信号、软件使用建议或收益承诺,不推荐任何券商、交易所、框架或标的。文中关于开源项目的所有描述,均来自对指定源码快照的阅读与概念注解,未实际运行该程序,也不保证在你的版本、你的市场、你的接入方式下同样成立——具体行为请以你手上那个版本的源码与文档,以及你自己的核对为准。文中提到的各类时限、容忍范围、阈值均只讲机制不给数值,因为它们取决于你的策略周期、接入方式和监管环境,并且会变化。把这五块全部补齐,也只是让系统不再以你看不见的方式出错,它既不会提高策略的胜率,也不改变「历史表现不预示未来收益」这一条。 完整风险提示见免责声明

小结

  • 回测免费送你五个前提:数据一定到、下单即成交、我记的持仓就是真持仓、出错就停、结果可复现。实盘一个都不送,这五条正好对应你要补的五块代码。
  • 行情这块的核心不是订阅,是新鲜度。陈旧的价格比没有价格危险得多,因为它不报错。数据和它的更新时刻要绑在一起返回;宁可丢掉一段说不清多旧的数据,也别留着用。
  • 订单这块的核心是承认「悬空态」存在。查询失败只能得出「我不知道」,绝不能当成「它不存在」;启动时必须先把所有未完成订单刷一遍,刷完之前不做任何交易决策。
  • 对账这块的核心是承认真持仓在对面。差额要分档:小差额可自动对齐但必须留警告,大差额拒绝自动修正——把不理解的东西改成一个看着正常的数字,只是把错误洗白。
  • 异常这块的核心是分级。至少三档:可重试、降级不开新仓、停机叫人。而且停机应该是一个状态而不是进程退出,这样通知通道还在,你还能远程把它拉起来。
  • 留痕这块的核心是实盘不可复现。订单落结构化存储、每日账户快照、关键事件主动推送;「决定不做某件事」的记录,比成交记录更容易漏,也更常是排查关键
  • 这五块一分钱收益都不产生,它们全部在处理同一件事:你以为的系统状态,和它真实的状态,可能不一样。

一句话说完这篇:回测里你的程序是那个小世界唯一的主人,说什么就是什么;实盘里它只是一个隔着一根会断的网线、跟另一台你管不着的机器打交道的客人——多出来的这几块代码,全都是在替它不停地问一句「我现在到底知不知道自己在哪」。

内容有错、看不懂、或想看下一篇?告诉我们 →

本文为投资教育整理,不构成任何投资建议;不荐个股/基金、不预测点位、不承诺收益。关键数据与结论请结合权威来源自行验证,并见风险免责声明