资讯动态

Trading-as-Git:用版本控制与本地多Agent构建可回滚的风控闭环交易系统

发布时间:2026/10/8 18:02:50 来源:尧图企业网站定制
1. 从手动盯盘到版本化交易OpenAlice 想解决的到底是什么问题做量化交易的人几乎都经历过同一个噩梦策略在回测里跑得漂漂亮亮夏普比率好看得不行一上实盘就开始亏而且亏得莫名其妙。你回头去查发现是某个参数被临时改过、某个止损逻辑在极端行情下没触发、又或者是两套策略的信号打架了。最要命的是你根本说不清楚当时到底跑的是哪个版本的策略。这个问题的本质其实不是策略不行而是交易过程缺乏版本管理和可追溯性。我们写代码有 Git改一行代码都有 commit 记录能 diff、能回滚、能追责。但交易呢大多数人改策略就是直接在脚本里改个数字跑起来就完事没有任何记录。等到出问题只能靠记忆去还原而记忆是最不可靠的东西。OpenAlice 这个项目提出的Trading-as-Git概念就是冲着这个痛点来的。它把交易这件事用 Git 的思维重新组织了一遍每一次策略变更是一次 commit每一个交易决策是一次可追溯的操作每一个风控规则是一道必须通过的 gate。再叠加一个本地化的量化 Agent 架构让整个交易系统变成一个可版本化、可回放、可审计的闭环。我第一眼看到这个标题的时候最感兴趣的不是量化 Agent这个热词而是Trading-as-Git和风控闭环这两个词放在一起。因为市面上讲 AI Agent 做交易的文章太多了大多停留在让大模型帮我选股这种层面真正把工程化、可追溯、风控闭环做扎实的极少。OpenAlice 的价值恰恰在于它试图把交易系统当成一个软件工程项目来管理而不是当成一个玄学调参的游戏。这篇文章我会从架构层面把 OpenAlice 拆开讲清楚它的 Trading-as-Git 到底怎么落地、本地量化 Agent 是怎么组织的、风控闭环是怎么设计的、以及在实际搭建过程中有哪些坑。适合有一定编程基础、正在做量化交易、或者想把自己的交易流程工程化的朋友。哪怕你暂时不打算用 OpenAlice这套思路本身也值得借鉴。2. Trading-as-Git 的核心机制把每次交易决策变成一次可回滚的提交2.1 为什么交易需要版本控制这个隐喻先想清楚一个问题Git 到底解决了什么它解决的是多人协作下代码状态如何被可靠地记录、对比和回滚。交易场景其实高度相似——策略会迭代、参数会调整、市场环境会变化你需要知道当前这个决策是基于哪个版本的逻辑做出来的。传统做法里很多人会用 Excel 记录交易日志或者用数据库存订单。但这些记录的是结果不是决策逻辑。你记录了在 3200 点买入了但没记录为什么买——是因为均线金叉是因为某个 Agent 给出了信号还是因为风控放行了某个原本被拦截的订单这些为什么才是复盘时真正有价值的东西。Trading-as-Git 的思路是把策略配置、参数、风控规则、Agent 决策链全部纳入一个类似 Git 的版本体系。每次你调整策略就相当于一次 commit系统会记录这次变更的 diff。当实盘出现异常你可以直接 checkout 到出问题前的那个版本在历史行情上回放看看问题到底出在哪。提示这里的Git更多是一种设计隐喻和工程范式不一定非要直接调用 git 命令行。核心是快照 差异 可回滚这三个能力。2.2 一次交易提交里到底装了什么要落地 Trading-as-Git首先得定义清楚一次 commit 的粒度是什么OpenAlice 的设计里一次交易提交通常包含以下几类信息我用表格整理一下方便对照理解提交内容具体含义类比 Git 中的概念策略快照当前策略的完整配置、参数、代码版本文件树 snapshot决策上下文触发这次交易的市场数据、指标状态commit message diffAgent 决策链哪个 Agent 给出信号、经过哪些推理步骤提交作者与变更说明风控校验结果每道风控 gate 的通过/拦截记录pre-commit hook 结果执行结果订单是否成交、成交价、滑点合并后的最终状态这个结构的关键在于决策上下文和风控校验结果必须和策略快照绑定在一起。很多人做交易日志只记订单不记上下文导致复盘时完全无法还原当时的决策环境。而把这几样东西打包成一个不可变的提交记录你才能做到真正的可回放。我自己的经验是决策上下文里最容易被忽略、但最有价值的是指标状态的原始值而不是金叉死叉这种结论。因为结论是策略算出来的如果策略本身有 bug你记录结论就等于把 bug 也一起记录进去了。记录原始值你才能在复盘时用不同的策略逻辑重新计算验证到底是策略问题还是市场问题。2.3 回滚与回放Trading-as-Git 最实用的两个能力版本控制真正的价值体现在出问题之后。Trading-as-Git 提供两个核心能力回滚和回放。回滚很好理解当新版本策略在实盘表现异常你可以一键切回上一个稳定版本。但这里有个细节——交易不像代码代码回滚后重新部署就行交易回滚意味着当前持仓状态和策略版本要匹配。如果你在版本 B 下建了仓然后回滚到版本 A版本 A 可能根本不认识这个仓位风控就会失效。所以 OpenAlice 在设计上要求回滚时必须同时处理持仓的归属问题要么平掉不匹配的仓位要么把仓位标记为遗留仓位单独管理。回放则更有意思。它允许你把历史某一段行情数据喂给某个历史版本的策略重新跑一遍看看当时的决策是否合理。这个能力在排查为什么这笔单子会亏的时候特别有用。你可以对比当时实际执行的决策和现在用同样数据重新计算的决策如果两者不一致说明中间有状态污染或者数据问题。注意回放时一定要保证数据的一致性。如果你回放用的是复权后的数据而当时实盘用的是未复权数据那对比结果是没有意义的。数据版本也要纳入 Trading-as-Git 的管理范围。3. 本地量化 Agent 的架构拆解为什么本地和多 Agent是关键3.1 本地化部署背后的现实考量标题里特意强调本地量化 Agent这个本地不是随便加的。量化交易对延迟、数据隐私、系统可控性都有很高要求。把 Agent 跑在本地有几个实打实的好处第一是数据不出本地。你的策略逻辑、持仓信息、资金规模这些都是极度敏感的东西。如果 Agent 依赖云端服务等于把核心机密交给了第三方。本地部署意味着所有计算都在你自己的机器上完成。第二是延迟可控。云端 API 调用有网络往返行情剧烈波动时几百毫秒的延迟可能就是几个点的滑点。本地 Agent 直接读本地行情源决策链路短响应快。第三是可调试性。本地跑意味着你可以随时打断点、看日志、改代码。云端服务出问题你只能干等。对于需要反复迭代的量化策略本地化带来的调试便利是决定性的。当然本地化也有代价你需要自己维护行情数据、自己处理故障恢复、自己保证系统稳定性。这就引出了架构设计上的取舍。3.2 多 Agent 分工信号、风控、执行各司其职OpenAlice 的 Agent 架构不是一个大模型包打天下而是多个职责单一的 Agent 协同工作。这种设计思路在工程上叫关注点分离好处是每个 Agent 逻辑简单、容易测试、出问题容易定位。典型的 Agent 分工是这样的信号 Agent负责读取行情、计算指标、生成交易信号。它只关心要不要交易、往哪个方向交易不关心仓位大小和风控。风控 Agent负责校验信号 Agent 的输出。它手里握着一堆规则单笔最大仓位、单日最大亏损、最大回撤、品种集中度等等。任何一条不满足信号就被拦截。执行 Agent负责把通过风控的订单发到交易接口并处理成交回报、撤单重发等。监控 Agent负责盯着整个系统的健康状态比如行情是否断流、Agent 是否卡死、账户余额是否异常。这种分工的核心价值在于风控 Agent 是独立于信号 Agent 的。如果风控逻辑和信号逻辑写在一起很容易出现信号想交易就顺手把风控绕过去的情况。独立出来之后风控成了一道物理隔离的关卡信号再强也过不去。我见过太多人把止损写在策略里结果策略一改止损逻辑就被覆盖了。把风控独立成 Agent本质上是用架构来保证纪律而不是靠人的自觉。3.3 Agent 之间的通信与状态管理多 Agent 协同绕不开通信和状态两个问题。通信上OpenAlice 这类本地架构通常采用消息队列或事件总线的方式Agent 之间不直接调用而是通过发布/订阅事件来交互。这样做的好处是解耦信号 Agent 不需要知道风控 Agent 在哪、怎么实现的它只管把信号事件发出去。状态管理则更微妙。每个 Agent 都有自己的状态信号 Agent 有指标缓存风控 Agent 有当日盈亏统计执行 Agent 有未成交订单列表。这些状态必须持久化否则系统重启后状态丢失风控就会失效。比如风控 Agent 重启后如果忘了今天已经亏了 5%它就会继续放行订单这是灾难性的。所以本地量化 Agent 架构里状态存储是个必须认真对待的模块。常见做法是用轻量级数据库比如 SQLite存关键状态每次状态变更都落盘。牺牲一点性能换取崩溃后的可恢复性这笔账在交易场景里是划算的。提示状态持久化的粒度要把握好。太粗崩溃后丢失太多太细频繁写盘影响性能。一般建议在每笔订单状态变更和每个风控周期结束这两个节点落盘。4. 风控闭环的设计从事后止损到事前拦截4.1 风控闭环的闭环到底闭在哪里很多人的风控是开环的设一个止损线价格到了就砍仓。这叫事后止损是被动的。而闭环的意思是风控的结果要能反过来影响系统的行为形成一个自我调节的回路。OpenAlice 的风控闭环我理解包含三个层次的反馈第一层是单笔交易级风控拦截了某笔订单这个拦截事件要被记录并且影响后续的信号生成。比如连续拦截 5 笔做多信号系统应该意识到当前市场可能不适合做多而不是傻乎乎地继续发信号。第二层是日内级当日亏损达到阈值风控应该触发当日停止交易的状态并且这个状态要传递给信号 Agent让它停止生成新信号。第三层是策略级如果某个策略版本在实盘中持续触发风控系统应该标记这个版本为高风险在 Trading-as-Git 的版本体系里给它打上标签提醒你回滚或者重新审视。这三层反馈合起来才叫闭环。只做第一层那还是开环止损。4.2 风控规则的优先级与冲突处理风控规则一多冲突就来了。比如单笔最大仓位 10%和必须满仓操作这两条规则在某些情况下会打架。这时候需要一个明确的优先级机制。我的建议是采用分层优先级优先级规则类型处理方式P0资金安全类最大回撤、单日亏损上限绝对优先触发即停止交易P1合规类持仓集中度、品种限制高优先级拦截但不停止系统P2策略类仓位大小、止盈止损可被 P0/P1 覆盖P3偏好类交易时段、手续费优化最低优先级可灵活调整这个分层的关键是P0 规则一旦触发整个系统进入安全模式所有新信号一律拦截直到人工确认或者下一个交易日。这是防止亏红了眼继续加仓这种人性弱点的最后一道防线。4.3 风控参数怎么定从回测到实盘的动态调整风控参数不是拍脑袋定的。最大回撤设 20% 还是 10%单笔仓位设 5% 还是 15%这些都要有依据。我的做法是先用历史回测确定参数的合理区间再用实盘的小资金验证最后逐步放大。具体来说回测阶段跑一遍历史数据统计在不同参数下的最大回撤、夏普比率、胜率找出一个回撤可接受、收益还不错的区间。然后实盘先用最小资金跑观察实际回撤是否和回测接近。如果实盘回撤明显大于回测说明要么策略过拟合要么风控参数太松。这里有个经验实盘的风控参数应该比回测更保守。因为回测是已知历史实盘是未知未来你必须为黑天鹅留出缓冲。回测最大回撤 15%实盘风控线就设 10%给自己留 5% 的容错空间。注意风控参数一旦确定就不要频繁调整。频繁调整风控参数等于没有风控。如果确实需要调整也要通过 Trading-as-Git 走一次正式的 commit留下记录。5. 从零搭建一套 Trading-as-Git 本地 Agent 的实操路径5.1 环境准备与目录结构设计假设你要自己动手搭一套类似的系统第一步是设计目录结构。这个结构要能体现 Trading-as-Git 的版本管理思想。我推荐的结构是这样的trading-system/ ├── strategies/ # 策略代码每个策略一个目录 │ ├── ma_cross/ │ │ ├── strategy.py │ │ └── config.yaml │ └── rsi_reversal/ ├── agents/ # 各 Agent 实现 │ ├── signal_agent.py │ ├── risk_agent.py │ ├── exec_agent.py │ └── monitor_agent.py ├── risk_rules/ # 风控规则配置 │ └── rules.yaml ├── commits/ # 交易提交记录类似 .git │ └── 2024-xx-xx-xxx.json ├── data/ # 行情数据缓存 └── state/ # Agent 状态持久化 └── state.db这个结构里commits/目录是核心每次策略变更或交易决策都往里面写一条记录。state/目录存 Agent 的运行时状态。risk_rules/独立出来方便风控规则单独版本管理。环境上Python 是主流选择依赖几个关键库行情接口比如各家的数据 SDK、数据库SQLite 足够、消息队列本地可以用 Redis 或者简单的进程内队列。不需要一上来就上重型框架先把核心链路跑通。5.2 信号 Agent 的最小实现信号 Agent 的职责很单一读数据、算指标、发信号。一个最小实现大概长这样class SignalAgent: def __init__(self, strategy_config): self.config strategy_config self.indicator_cache {} def on_market_data(self, bar): # 更新指标缓存 self.update_indicators(bar) # 计算信号 signal self.compute_signal() if signal: # 发布信号事件不直接调用风控 self.publish(signal.generated, { symbol: bar.symbol, direction: signal.direction, confidence: signal.confidence, context: self.snapshot_context() })注意这里的关键设计信号 Agent 不直接调用风控 Agent而是发布事件。这样信号 Agent 完全不知道风控的存在职责纯粹。snapshot_context()方法负责把当前的指标状态、市场数据打包作为决策上下文一起发出去这就是 Trading-as-Git 里决策上下文的来源。5.3 风控 Agent 的拦截逻辑风控 Agent 订阅信号事件对每个信号做校验class RiskAgent: def __init__(self, rules, state_store): self.rules rules self.state state_store def on_signal(self, signal): # 按优先级依次校验 for rule in sorted(self.rules, keylambda r: r.priority): result rule.check(signal, self.state) if not result.passed: self.record_rejection(signal, rule, result) if rule.priority P0: self.enter_safe_mode() return # 全部通过转发给执行 Agent self.publish(signal.approved, signal)这段代码里record_rejection就是闭环的第一层反馈——拦截记录会被写入 commits 目录。enter_safe_mode是 P0 规则触发后的安全模式。整个风控逻辑清晰、可测试每条规则独立实现check方法。5.4 执行 Agent 与成交回报处理执行 Agent 收到 approved 信号后负责下单和跟踪class ExecAgent: def on_approved(self, signal): order self.build_order(signal) order_id self.broker.send(order) self.pending_orders[order_id] order self.persist_state() def on_fill(self, fill_event): # 更新持仓、记录成交 self.update_position(fill_event) self.record_commit(order_filled, fill_event)执行 Agent 的难点在于异常处理下单失败怎么办部分成交怎么办撤单重发怎么保证不重复下单这些都需要仔细设计。我的经验是所有订单操作都要有幂等性保证用唯一的 order_id 去重避免网络抖动导致重复下单。5.5 监控 Agent 与系统健康检查监控 Agent 是容易被忽略但极其重要的一环。它定期检查行情数据是否还在更新断流检测各 Agent 的心跳是否正常账户余额和持仓是否与预期一致当日盈亏是否接近风控线一旦发现异常监控 Agent 可以触发告警甚至在严重情况下主动进入安全模式。这是风控闭环的兜底。6. 实盘踩坑实录那些文档里不会写的教训6.1 状态不一致导致的幽灵持仓我自己踩过最狠的一个坑是状态不一致。风控 Agent 记录的持仓和执行 Agent 实际持有的仓位对不上。原因是某次下单后成交回报因为网络问题丢了执行 Agent 以为没成交但实际成交了。结果风控 Agent 按没成交来算仓位放行了一个本该被拦截的大单。这个坑的教训是必须有对账机制。定期比如每分钟从交易接口拉取真实持仓和本地状态对比不一致就告警并修正。不要相信任何单一来源的状态要以交易接口的权威数据为准。6.2 回放时的时间戳陷阱做回放的时候我遇到过时间戳混乱的问题。行情数据的时间戳、系统本地时间、交易接口返回的时间戳三者可能不一致。如果回放逻辑依赖时间戳排序一旦有偏差事件顺序就乱了回放结果完全不可信。解决办法是统一用行情数据的时间戳作为事件时间的唯一标准其他时间戳只作为辅助记录。所有 Agent 在处理事件时都以事件自带的时间戳为准不用系统时间。6.3 风控规则之间的隐性冲突前面提到风控规则会冲突我实际遇到过一个更隐蔽的两条规则单独看都没问题组合起来却导致系统永远无法交易。比如单笔仓位不超过 5%和单笔仓位不低于 8%这两条如果同时存在任何订单都会被拦截。这种冲突在规则少的时候容易发现规则一多就很容易漏掉。我的做法是给风控规则加一个冲突检测环节在加载规则时用一组模拟信号跑一遍看看是否有信号能被所有规则同时满足。如果没有任何信号能通过说明规则集本身有问题。6.4 Agent 卡死与超时处理本地 Agent 架构里Agent 卡死是个现实问题。某个 Agent 因为死循环或者等待资源卡住了整个链路就断了。如果没有超时机制系统会一直等下去。所以每个 Agent 之间的通信都要设超时。信号发出后如果 N 秒内没有收到风控的响应就认为风控异常触发告警。执行 Agent 下单后如果长时间没有成交回报也要主动查询订单状态而不是傻等。提示超时时间要根据实际场景定。行情剧烈波动时可以短一些平静时可以长一些。但一定要有不能无限等。7. 我对这套架构的一点个人体会把交易当成 Git 来管理这个思路的价值不在于技术有多复杂而在于它强迫你把交易过程结构化、可追溯化。很多人做量化亏钱不是因为策略不够聪明而是因为过程太混乱——改了什么都不记得出了事也说不清。OpenAlice 这套 Trading-as-Git 加本地多 Agent 加风控闭环的组合本质上是在用工程纪律对抗人性弱点。信号 Agent 负责进攻风控 Agent 负责防守监控 Agent 负责兜底每个 Agent 只做一件事做扎实。这种架构不一定能让你赚更多钱但能让你亏得明白、亏得可控。如果你打算自己动手我的建议是先从风控 Agent 开始写而不是从信号 Agent 开始。因为大部分人做量化第一反应是我要找个赚钱的信号但真正决定你能不能活下来的是风控。先把风控闭环搭起来哪怕信号很粗糙你也不会暴仓。等风控稳了再慢慢优化信号这才是可持续的路径。另外Trading-as-Git 的提交记录建议你定期导出备份。这些记录是你最宝贵的资产比策略代码还重要。策略可以重写但历史决策的上下文丢了就再也找不回来了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑