← 返回教程库

实盘跑起来之后,该盯着什么

最后更新 2026-08-19
📚 量化与 AI 投研 📖 E 线 · 实盘边界 ⏱ 约 23 分钟 R2 · 注意风险
你将学到
  • 说得出实盘监控为什么必须分成系统层、执行层、策略层三层,以及为什么下面一层不干净时上面一层的数字全是假的
  • 对每一层各说出三个具体该盯的量,并知道它在真实系统里通常靠什么东西留下痕迹
  • 用「后果的不可逆性」而不是「感觉有多严重」给报警分级,并知道为什么「没有消息」本身必须是一条可被检测的异常

上线第一周,你大概每隔十分钟就要看一眼日志。第二周,改成早晚各看一次。第三周,你开始觉得这事挺无聊的——日志滚得很稳,没什么可看的。

然后某个周四晚上你随手点开,发现最后一条记录停在周二下午。

程序已经死了两天,而你完全不知道。更糟的一种版本是:程序好好地活着,循环一秒不落地在转,只是它读到的行情三天前就不再更新了——它每一轮都在拿同一份陈旧数据认认真真地做判断,日志漂亮得不得了。

这两件事在终端窗口里长得几乎一样。没有报错,不等于没出事;有日志在滚,也不等于事情在正确地发生。

这一篇要给的就是一份清单:跑起来之后,具体该盯哪些东西,以及盯到什么程度才算真的盯住了。至于上线之前代码上要补哪些东西,那是回测走到实盘,代码上要补哪些的活;延迟和成交容量这两个约束单独占一篇,见延迟和容量;而「盯出问题之后要不要停手」是另一个完全不同的决策,放在什么情况下必须立刻停手。这一篇只管一件事:盯什么,怎么盯,什么时候喊你。

先说人话:值班室墙上该挂三块表

想象你把一间小店托管给了一个雇来的店员,自己出差在外。你要通过电话确认这家店是不是在正常运转,你会问哪几个问题?

第一个问题:人还在店里吗。 这是最基本的一层。店员如果压根没来上班,或者来了但是在后厨睡着了,后面所有问题都不用问了。

第二个问题:他今天办的那几件事,都办成了吗。 你交代他去进货,他去了,钱也付了——货真的到了吗?入库单上的数量和你账本上的对得上吗?他说进了二十斤,仓库里到底是不是二十斤?

第三个问题:这家店最近的生意,和以前一样吗。 人在、事也办成了,可这个月的流水比上个月少了一半,客人来的频率明显变了。这一层和前两层完全不同——前两层是「有没有坏」,这一层是「还灵不灵」

三个问题对应三块表,挂在同一面墙上,但读法完全不同。搞混它们,是实盘监控里最常见、也最贵的一个错误。

为什么必须分三层:下面脏了,上面的数字全是假的

这三层不是并列关系,是叠罗汉的关系。上面一层的所有数字,都建立在下面一层没出问题这个前提上。

举一个具体的串法。行情源静默地停止更新了(系统层坏了)。你的程序不知道,它继续用最后一根有效数据算指标,算出来的判断当然是稳定的——因为输入根本没变。于是它一整天不发出任何信号(执行层看起来一切正常,没有失败的委托,没有异常的成交),而你的策略层报表显示:今天零交易、零回撤、收益持平。

这三个数字每一个都是真的,合起来却在说一个彻底错误的故事。 你打开报表看到「一切平稳」,实际情况是你的系统已经躺平了一天。

反过来也一样。执行层出了问题——比如有几笔委托一直没成交,而你的程序以为成交了——那么策略层算出来的持仓、收益、回撤,全都是照着一个不存在的账户算的。你会对着一条虚构的净值曲线去做「要不要减仓」这种真金白银的决定。

所以监控清单的读法有一条硬顺序:先确认系统层干净,再看执行层,最后才有资格讨论策略层的数字意味着什么。 顺序反了,你就是在拿假数据做真决策。

下面一层一层拆。

第一层:系统层——它还活着吗

「活着」这个词有三个意思

先把这个词拆开,因为绝大多数人的监控只查到了最外面那一层。

进程存在:操作系统里还有这个程序,你 ps 一下能看到它。这是最弱的一种活着——一个卡死在网络请求上、什么也不干的进程,同样满足这个条件。

循环在转:程序不只是存在,它还在按节奏一轮一轮地醒来、干活、睡下。这一层比上一层强得多,但仍然不够:一个每轮都拿到空数据、每轮都静默失败的循环,转得和正常时一模一样。

循环在做有效的事:每一轮不但跑完了,而且拿到了新鲜的输入、产生了合理的输出。这才是你真正关心的「活着」。

三个层次对应三种检查手段,成本递增,价值也递增。只查第一层,等于花钱买了个心理安慰。

投资层:一次「假死」值多少钱

对做判断的人来说,系统层故障有一个很特殊的性质:它的代价高度依赖你的策略类型,而且往往是不对称的。

如果你的规则本质上是「持有为主、偶尔调仓」,那么程序死掉两天,多半什么也不会发生——你的仓位还在那里,市场该怎么走怎么走,你只是少调了一次仓。

但如果你的规则里有止损,情况完全反过来。止损是一个必须由程序主动执行的动作。 程序死了,止损就不存在了。你的账户从「一套有下限保护的持仓」变成了「一套裸的持仓」,而这个转变没有任何人通知你。你以为自己有安全带,实际上安全带在两天前就断了。

这就是为什么系统层监控的优先级,取决于你的规则里有多少「必须主动做的动作」。被动持有的容错高,主动风控的容错为零。

系统层:真实系统里靠什么留痕

心跳文件。 Vibe-Trading 的实盘运行时里有一个专门的存活模块,它的做法很朴素:每个运行器每一轮都往一个固定目录写一个文件,内容就是当前时间戳;外面的人只要读这个文件、比一下和现在差了多久,就知道它是不是还在转。写入是原子的(先写临时文件再替换),这样读的人永远不会读到写了一半的时间戳。

这个模块的文档注释里有几句话,值得单独抄下来:

  • 心跳过期意味着进程没有走正常清理流程就死了——被强杀、宿主机崩了、变成僵尸进程。也就是说,心跳能抓到的恰恰是那些「死得不体面、来不及说再见」的情况,而这些正是最容易被漏掉的。
  • 读不到心跳、心跳格式坏了,一律当作「不活着」——失败时倒向保守的那一边。这个取舍方向在监控里几乎总是对的:宁可误报一次已经死了,不要漏报一次还活着。
  • 过期阈值被刻意设得远大于一轮的间隔,理由写在注释里:避免一次偶发的慢循环被误判成死亡。这是所有阈值型监控都要面对的取舍——灵敏度和误报率是一根跷跷板,你只能选自己更怕哪一边。

最要紧的是这一句:一个看起来已经死了的运行器,绝对不能盲目重启。 那个模块只负责「报告」和「清理过期的标记文件」,它从不启动或杀死任何进程。原因下一层会讲到——重启之前必须先对账,否则你可能把一笔已经下出去的单子再下一遍。

看门狗与心跳日志。 freqtrade 走的是另一条路:主循环每一轮结束后,如果距离上次记录超过了一个配置的间隔,就往日志里写一条心跳,内容包含进程号、版本和当前状态。同时,如果开启了 systemd 通知,它在每次进入等待之前都会给系统的看门狗发一次信号——这等于把「我还活着」这件事交给了操作系统层面的一个独立监督者,而不是靠你自己盯日志。

这个设计有个细节值得注意:无论程序当前是运行状态还是被暂停状态,看门狗信号都照发,只是附带的状态字符串不同。也就是说它区分了「我死了」和「我活着但停着」——这两件事的处理方式完全不同,混在一起报警等于自找麻烦。

外部可查的最后一轮时间。 freqtrade 还开了一个专门的健康查询接口,返回的核心就是一个字段:上一轮处理是什么时候完成的。这比日志好用的地方在于,它是可以被别的程序定时去问的——你可以拿它接到任意一个通用的监控系统上,而不必去解析日志文本。

这一层的三个具体检查项

进程活着吗。 最低要求:有一个和你的交易程序无关的、独立的东西在检查它。自己检查自己是无效的——程序整个卡死时,它自己写的检查代码也一起卡死了。心跳文件加一个外部的定时读取,或者交给系统的看门狗,是两条常见路子。

行情在更新吗。 这是最容易被漏掉的一项,因为它和「程序活着」看起来太像了。具体查法:拿你手上最新一根数据的时间戳,减去当前时间,看这个差值是不是超过了合理范围(合理范围由你的数据周期决定,日线和分钟线完全不是一个量级)。这个差值必须被当成一个持续监控的量,而不是出问题时才去查的东西。

还有一个更隐蔽的版本:数据在更新,但更新的是垃圾。成交量全零、价格纹丝不动、某几个品种整段缺失。这类问题在数据管道那一层有系统的查法,这里只提醒一句:上线之后的数据质量检查,不能只在上线那天做一次。

时钟对不对。 这一项听起来像是运维的事,但它会以很难查的方式咬到你。你的机器时间和交易对手方的时间如果差得多,会有一串连锁反应:你算出来的「这根K线走完了没有」是错的,你判断「这个委托超时了没有」是错的,带时间戳签名的请求可能直接被拒绝。而这些症状看起来全都不像时钟问题——它们看起来像是随机的、偶发的、复现不了的怪毛病。

查法很简单:定期比对本地时间和一个权威时间源的差值,把这个差值也当成一个被监控的量。它平时是个无聊的常数,而它变得不无聊的那天,你会很庆幸自己在看它。

第二层:执行层——你交代的事,办成了吗

先说人话:委托单不是收据

你在饭馆点了菜,服务员在本子上记下来了。这时候你有的是一张点单记录,不是一盘菜。中间可能发生的事情包括:后厨没收到、原料没了、做出来的和你点的不是一个东西、菜上了但份量不对。

自动交易里对应的是同一件事:你发出去的是委托,你想要的是成交,这两者之间隔着一整个别人的系统。

投资层:三种「以为」,每一种都会毒化你的账本

以为下出去了,其实没下出去。 网络抖了一下、接口返回了个错、你的重试逻辑吞掉了异常。结果是你的账本上有一笔仓位,现实里没有。你后面所有基于这个仓位的决定——止损、加仓、平衡——全是对着空气做的。

以为成交在这个价,其实成交在那个价。 你按某个价格算的仓位大小、算的止损位置,而实际成交价和它差了一截。单笔看不出什么,几百笔累积下来,你的实际风险敞口和你以为的已经是两回事。这个差就是滑点,它在回测里通常是一个你拍脑袋设的常数,而在实盘里它是一个可以每天被测量的真实数字——滑点那篇讲的是这个量本身的机制,这里要说的是:上线之后,它从一个假设变成了一个观测值,你有责任去观测它。

以为持仓是这样,其实是那样。 你在别的地方手工操作了一笔、对手方那边触发了强制平仓、有一笔委托在你程序没运行的时候成交了。你的本地记录和对方的真实记录,分叉了。

系统层:对账这件事,正确的产物是「暴露歧义」而不是「自动纠正」

Vibe-Trading 的实盘运行时里有一个专门做崩溃恢复与持仓对账的模块,它开头那段设计说明,我认为是这一整篇里最值得逐句读的东西。

它先把问题定死了:启动时以及每一轮交易之前,运行器必须先回答一个问题才有资格继续交易——对手方那边的真实状态,和我们崩溃前持久化下来的最后已知状态,对得上吗?

然后它点出了为什么这件事不能用常规的「失败就重试」来解决:交易不是幂等的。 天真的「恢复现场然后重发」补上了一个洞(工作丢了),却捅开了一个大得多的洞(真金白银下了两遍)。

最危险的情形它单独拎出来说了:下单过程中崩溃。我们已经把委托发给了对方,进程死了,我们永远不知道它成没成。这笔单子可能还挂着、可能已经成交、也可能压根没到对方那边。因为整套系统有一条「改变状态的调用绝不自动重试」的规则,所以对账的职责被明确限定成:分类并暴露这个不确定性,而不是自动纠正它、更不是自动重发。

具体做法上,它把每一处对不上的地方归成四类:

  • 对得上的:双方一致,不用管。
  • 凭空多出来的成交:对方那边显示有一笔成交,我们没有任何记录。注释里的原话意思是——真金白银动了,而我们的审计记录里没有它。这一类强制触发停机
  • 孤儿委托:我们记着有一笔挂单,对方那边没有。它可能被撤了、被拒了,也可能是成交完清掉了。
  • 下单中途的歧义状态:上面说的那种最危险的情况。同样强制触发停机

只要出现后两类里的危险项,整个报告的「是否安全」标志就会翻掉,运行器停下来把问题摆到人面前,绝不静默重试。而只有在一次完全干净的对账之后,新的状态才会被原子地写回去。

还有一处结构上的设计特别值得学:这个对账模块拿到的,只有对手方的只读能力(读持仓、读余额、读挂单),它在结构上就拿不到任何下单能力。这不是靠开发者自觉不写下单代码,而是靠依赖注入的边界,让「对账过程中不小心下了一笔单」这件事在物理上不可能发生。 用结构来保证纪律,永远比用注释和自觉可靠。

freqtrade 那边处理同一类问题的思路可以对照着看。它在启动时会专门把数据库里所有还开着的委托拿出来,逐个去对手方那边查最新状态,然后回写。它还有一个用来找回「不在数据库里的委托」的函数,注释写明了触发场景:余额莫名其妙消失了,导致平不了仓。 它会去把这个品种的历史委托拉回来比对,如果发现了一笔自己完全不认识的委托,就把它补记进来,并且给这笔交易打上一个专门的离场原因——「在对手方那边被卖掉了」

这个离场原因的存在本身就是一条重要信息:框架作者知道这种事会发生,而且发生得足够频繁,值得给它一个专门的标签。 你自己搭系统时,也该给这类「不是我干的但确实发生了」的事件留一个专门的类别,而不是让它们混进正常成交里。

还有一处细节:freqtrade 的交易记录里,开仓价和开仓请求价是两个分开存的字段,平仓那边同样如此。两个字段分开存,意味着「我想要的价」和「我实际拿到的价」这个差,是可以随时被算出来的。很多自建系统只存了实际成交价,于是从第一天起就永久地失去了度量自己滑点的能力。

这一层的三个具体检查项

下单成功率。 分母是你发出去的委托数,分子是最终确认成交的数。这个比例本身是多少不重要(不同市场、不同委托方式差别巨大),重要的是它的变化。它昨天是一个数,今天突然掉了一半,那是一个非常强的信号——可能是网络、可能是对方接口变了、可能是你的资金不够了。

顺带说一个容易被忽略的量:被拒绝的委托要单独统计,而且要按拒绝原因分类。 「余额不足」「价格不合法」「品种不可交易」是三种完全不同的病,混在一个「失败次数」里,你什么也诊断不出来。

实际成交价与预期的偏离。 每一笔都记下来:我下单时打算的价、最终成交的价、两者的差。然后看它的分布而不是平均值——平均滑点看起来很小,可能是因为大部分笔很小、少数几笔离谱地大,而恰恰是那少数几笔会吃掉你的收益。

这个量还有一个额外用途:它是你的回测有多离谱的实测证据。你在回测里假设的那个成本数字,和上线一个月后量出来的真实分布,差多少?这个对比,比任何理论讨论都有说服力。

持仓与对手方对不对得上。 至少在每天开盘前做一次全量比对:品种、数量、方向,逐项对。发现对不上时,正确的动作是停下来让人看,不是自动去改成一致——因为你不知道该以哪边为准,而猜错的代价是又下一笔真单。

第三层:策略层——这套办法还灵吗

先说人话:机器没坏,不代表这门生意还行

前两层查的都是「有没有坏」,答案是是非题。这一层不一样——它没有正确答案,只有「和以前比,变了没有」。

而且这一层有个很讨厌的性质:它的信号天生模糊。一套完全正常的策略也会连亏几次,一套已经失效的策略也可能刚好连赢几次。你在这一层看到的任何东西,都不是证据,只是需要被解释的现象

投资层:为什么盯「当前」比盯「历史最大」有用

回测报告告诉你的是历史最大回撤——那是一个已经翻篇的故事。实盘要盯的是另一个数:此时此刻,我在水面下多深。

这两个数完全不同。历史最大回撤是一个静态的评估参数,你在决定要不要用这套方法时看它;当前回撤是一个动态的位置信息,它回答「我现在站在哪」。freqtrade 的回撤结果对象里专门有一组以「当前」开头的字段,就是为这件事准备的。

但真正会把人熬走的,是回撤持续的时长而不是深度——这一点回撤恢复期那篇讲得很细,包括一个反直觉的发现:主流回测报告默认根本不算「爬回来要多久」。放到实盘监控里,这意味着你得自己维护一个数:我已经连续多少天没有创新高了。 这个数在任何默认报表里都不会有。

连亏次数是另一个必须实时维护的量。它的价值不在于「连亏 N 次说明策略失效了」——统计上这几乎证明不了任何事,连续亏损这件事那篇把这个误区拆得很清楚。它的价值在于触发一次人工复核:不是让你据此下判断,是让你据此去看一眼。

信号频率的变化是我认为最被低估的一项。原因是它比收益类指标早得多就会露出破绽。收益要积累几十上百笔才能说明点什么,而「这套规则每周本该产生三五个信号,最近两周一个都没有」这件事,第三天你就能看出来。频率异常通常指向的是机制层面的东西——数据源变了、市场状态变了、你的过滤条件在新的行情下把一切都过滤掉了。

系统层:这些量在框架里长什么样

freqtrade 有一组叫「保护」的插件,本质上就是把上面这几个量做成了自动刹车。其中一个专门盯止损次数:在一个回看窗口内,如果因为止损(含移动止损、对手方端止损、强制平仓)而结束、且收益低于某个下限的交易笔数达到了设定值,就锁住不再开新仓。另一个盯的是回撤:窗口内回撤超过阈值就全局停止开仓。

看它的实现方式比看参数有用。它取的是窗口内已平仓的交易,按离场原因过滤,再按收益过滤,最后数个数。这三道过滤每一道都在表达一个判断:只有真正结束的交易才算数;只有因为止损而结束的才算数;只有真的亏了的才算数。你自己维护「连亏次数」时,这三个判断你也得做,只是多数人做的时候没意识到自己在做。

阈值和窗口长度都是可配置的,具体默认值以你手上那个版本的文档为准。但有一个机制层面的盲区改参数改不掉:判断只在窗口内做,一段比窗口更长的慢性阴跌,每一个窗口切片看起来都很温和,于是它一次也不会触发。

Vibe-Trading 那边有一个每日下单计数器,按自然日统计每个对手方的下单笔数,写入是加了文件锁的原子操作。它的注释里有一句定位说得很好:这个计数是建议性的纵深防御,真正的上限由对手方那边强制执行,所以读取失败时按零处理。

这句话值得展开一下。监控和风控是两件事:风控是硬拦截,必须可靠,失败时要倒向保守;监控是观测,它的失败不应该阻断正常业务。把两者混在一起,你会得到一个「监控挂了导致交易停了」的系统——听起来很安全,实际上你会因为受不了误报而把监控关掉。

同一套系统里还有一个东西很值得抄:一个纯靠文件存在与否生效的全局停机开关。它被刻意做成了不依赖任何进程配合的形式——不管模型在不在循环里绕圈、不管消息通道通不通,只要那个文件在,所有下单动作在最外层就被挡掉。文件内容是一小段说明是谁、什么时候、为什么触发的,但判据是文件的存在本身,内容坏了也照样算触发

这个设计的思路可以直接迁移到你自己的系统上:你的紧急停止手段,不能依赖你要停的那个东西还正常工作。

报警该怎么设:三挡,判据是「不可逆性」

清单列完了,接下来是那个真正决定成败的问题:这些东西里,哪些该在半夜把你叫醒?

先说结论:报警太多等于没有报警。 这不是一句劝告,是一个可以预测的过程。你每收到一条不需要行动的通知,对下一条通知的敏感度就下降一点。两周之后,你会养成一个非常危险的习惯——看到推送先滑掉,回头再说。而那条真正要命的通知,恰好也在被滑掉的那一批里。

现成的分级模型:三挡,不是两挡

freqtrade 的通知配置给了一个很好的骨架:每一类事件可以设成三种状态之一——响、静默、不发。「静默」这一挡是关键,它的意思是消息照样发到你的记录里,但不会发出声音、不会点亮屏幕。

三挡比两挡(开/关)好在哪?因为绝大多数事件属于「我需要它被记下来,但我不需要现在知道」。只有开关两挡时,这类事件要么污染你的报警通道,要么干脆消失。一个只有开关两档的通知系统,会逼着你在「被噪音淹没」和「什么都不知道」之间二选一。

那份配置里还有个细节值得拿出来说:它允许按离场原因分别配置。同样是平仓,因为止盈平的可以静默,因为止损平的、因为紧急情况平的、因为人工强制平的,全都要响。这是分级的正确颗粒度——不是按「事件类型」分,是按「这件事意味着什么」分。

以及一个坑:文档里明确写着,「成交确认」这一类通知默认是关的,必须显式打开。这意味着如果你没改配置,你收到的是「委托发出去了」,而不是「委托成交了」——而这两件事之间的差,恰恰是执行层监控最想抓的那个东西。 默认配置从来不是为你的场景调的,它只是为「大部分人不会被烦到」调的。

分级判据:问「不处理会怎样」,别问「这事严不严重」

给报警分级时,最容易走的歪路是按「感觉有多严重」排。这条路会失败,因为几乎所有异常感觉起来都挺严重的。

换一个判据:如果我现在不管它,等到明天早上再管,代价会变大吗?

该立刻叫醒你的,只有一类:不可逆的、或者代价随时间增长的。具体来说——

  • 持仓和对手方对不上,尤其是出现了你没有记录的成交。真金白银已经动了,而你的账本不知道。每多一分钟,你基于错误账本做的决定就多一个。
  • 下单过程中崩溃留下的歧义状态。这笔单可能挂在那里持续暴露风险,也可能已经成交,你必须尽快弄清楚,而且弄清楚之前不能让系统继续交易
  • 止损相关的任何异常,包括程序整体死亡。前面说过,止损是必须主动执行的动作,程序不在,保护就不在。
  • 停机开关被触发。不管是谁触发的、为什么触发的,你都得知道。

该记下来第二天看的,是绝大多数东西——

  • 单笔委托失败、单次网络超时、单次接口报错。这些东西的正常发生率不是零,单次发生不说明任何问题。该报警的是它们的比例发生了变化,不是它们发生了。
  • 正常的开仓、平仓、止盈成交。这些是系统在按你的设计干活的证据,属于「记录」不属于「事件」。
  • 连亏达到你设定的次数、当前回撤到了某个位置。这些需要的是你坐下来想一想,不是你从床上跳起来。在半夜做需要判断力的决定,是所有实盘故事里最糟糕的桥段。 什么时候真的该停手,判据在什么情况下必须立刻停手到什么程度该停用一套方法里,那是需要清醒的头脑和完整数据才能做的事。

该完全不报的,判据只有一条:我从来不会因为这条消息做任何事。 如果连续两周你对某一类通知的反应都是「哦」,那它就该被降级或者关掉。定期做这个清理,比一开始就设计得完美更现实。

还有一条最容易漏掉的:沉默必须是可检测的

上面所有的报警都是「出事了才响」。这套机制有一个结构性的洞:如果整个系统死透了,包括发报警的那部分,你会收到完美的静默。

而静默恰好和「一切正常」长得一模一样。

所以监控体系里必须有一条反向的规则:规定一个时间窗口,如果窗口内没有收到任何心跳,就报警。 这条报警的触发条件是「什么都没发生」,它是唯一一条能抓到「系统整体消失」的规则。前面说的心跳文件、看门狗信号、可外部查询的最后一轮时间,最终都是为这一条服务的。

判断这条规则有没有配好,有个很简单的自测:把你的程序直接强杀掉,然后什么也不做。 多久之后你会收到通知?如果答案是「不会」,那你前面所有的监控都建在沙子上。

三层放在一起

盯什么 系统里通常靠什么留痕 出问题的典型表现
系统层 进程活着吗 心跳文件、看门狗信号、外部可查的上一轮时间 日志停在某个时刻,而你毫无察觉
系统层 行情在更新吗 最新数据时间戳与当前时间的差 循环照转,判断稳定,因为输入根本没变
系统层 时钟对不对 与权威时间源的偏差 一串复现不了的怪毛病,看起来全都不像时钟问题
执行层 下单成功率 委托记录与最终状态的比对、按原因分类的拒绝统计 比例突然变化,而单笔看起来都正常
执行层 成交价偏离 请求价与成交价分开存的两个字段 平均值好看,少数几笔离谱地大
执行层 持仓对得上吗 定期全量对账,分类为对得上/多出的成交/孤儿单/歧义 你的账本和现实分叉,而两边都不报错
策略层 当前回撤 「当前」开头的那组字段,以及自己维护的未创新高天数 只看历史最大回撤,不知道自己此刻站在哪
策略层 连亏次数 按离场原因+收益过滤后的窗口计数 拿它当判据而不是当复核触发器
策略层 信号频率 每日下单计数、每周信号数 变化比收益指标早得多,却最少被人盯

摆在一起最该记住的一点:这九项里,只有最后三项和「赚不赚钱」有关,而前六项决定了最后三项的数字是不是真的。

关于这份清单本身

三件事得说清楚。

清单是会长的,而且应该是被事故喂大的。 没有人能一开始就列全。正确的做法是每出一次意外,就问一句「有没有一个我本来能提前看到的量」,然后把它加进清单。一份从来没变过的监控清单,通常说明它从来没被真正用过。

监控本身也会坏。 心跳的写入方、报警的发送方、对账的执行方,都是代码,都会出问题。检查方法就是上面那个自测:定期主动制造一次故障,看报警响不响。 从来没被验证过的报警,和不存在的报警,实际效果是一样的。

盯着不等于要动手。 这份清单的目的是让你知情,不是让你频繁干预。系统层和执行层的异常需要立刻处理,因为那是「坏了」;策略层的波动大多数时候什么也不需要做,因为那是「本来就会这样」。把这两类混起来的人,最后会变成一个盯着屏幕不停改参数的人——而那恰恰是自动化本来要解决的问题。执行循环的意义在于把动作固化成不走样的流程,如果你在旁边随时插手,这个意义就没了。

⚠️ 风险提示

本文讨论的是自动化交易系统上线之后的工程监控方法,不构成任何投资建议、交易信号或收益承诺,不推荐任何框架、平台、服务商或标的。文中对开源项目的所有描述,均来自对上述指定快照版本源码与文档的阅读,不是运行结果,也不保证在你的版本、你的环境、你的市场上同样成立——具体行为请以你手上那个版本和你自己的核对为准,本文不提供任何可以照搬的配置。文中提到的所有阈值、窗口、间隔均只讲机制不给数值,因为合适的取值完全取决于你的数据周期、交易频率和风险承受能力。把这份清单全部落实,也只能让你更早知道出了什么事,它既不能阻止亏损,也不改变任何策略本身的有效性。 完整风险提示见免责声明

小结

  • 监控必须分三层,而且有严格的读法顺序:系统层(还活着吗)→ 执行层(事办成了吗)→ 策略层(还灵吗)。下面一层不干净时,上面一层的数字全是假的,而且看起来一切正常。
  • 「活着」有三个层次:进程存在、循环在转、循环在做有效的事。只查最外层等于没查。行情停止更新时,程序会拿着同一份陈旧数据一轮一轮认真地做判断,日志漂亮得不得了。
  • 检查必须由独立于被检查者的东西来做。自己检查自己,在整体卡死时会一起卡死。
  • 执行层的核心是对账,而对账的正确产物是分类并暴露不确定性,不是自动纠正、更不是自动重发——因为交易不是幂等的,重发一次就是真金白银的第二笔。
  • 「我想要的价」和「我实际拿到的价」必须分两个字段存。只存后者的系统,从第一天起就永久失去了度量自己滑点的能力。
  • 策略层里,信号频率的变化比收益指标早得多就会露出破绽,却最少被人盯;连亏次数的正确用法是触发一次人工复核,不是当判据下结论。
  • 报警分三挡(响/静默/不发),判据是不处理到明天代价会不会变大,不是这件事感觉有多严重。能叫醒你的只有不可逆的那几类;需要判断力的决定,绝不要在半夜做。
  • 必须有一条「没有心跳就报警」的反向规则,因为系统整体死亡的表现,就是完美的静默。自测方法:把程序强杀掉,看多久之后你会收到通知。

一句话说完这篇:你要盯的从来不是那条收益曲线,而是三个更基础的问题——机器还在不在、你交代的事有没有真的办成、这套办法最近是不是变了样;前两个问题不搞清楚,第三个问题上的所有数字都是编出来的。

本文基于开源仓库的源码与文档快照做概念讲解,未实际运行相关程序,也不构成任何投资建议或软件使用建议。想系统看这一卷的其他内容,回到量化与 AI 投研卷

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

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