☰
Trading-as-Git:本地量化Agent架构与风控闭环实战解析
2026/10/30 19:40:09 网站建设 项目流程

2023年年底,在我决定用本地量化 Agent 体系重做所有交易之前,我先经历了一轮特别痛的实盘暴仓。那晚我在手机上看行情,觉得某个品种突破了一个关键位置,头脑一热就下了双倍于常规仓位的单,价格反向扫掉止损后又快速反弹。复盘时我发现,问题根本不在行情判断,而在于整个流程缺少版本管理、缺少自动化校验、缺少止损后的强制冷却期。这直接促使我做了一件事:把所有交易决策变成可重复、可追溯、可回滚的工程流水线,也就是后来在 OpenAlice 项目里落地的 Trading-as-Git 本地量化 Agent 架构与风控闭环。

很多人以为量化交易就是写个策略挂在服务器上躺着收钱,真正做过几年的人会知道,难点从来不在“能想出一个策略”,而在策略会漂移、参数会失效、行情源会断连、心态会干预。这些乱七八糟的问题,几乎全部可以用工程手段约束住。OpenAlice 不是一个能预测未来的黑盒系统,它更像一个给交易上了保险丝的框架:策略像代码库一样被管理,Agent 负责决策,Harness 负责稳定运行,风控从开仓前到收盘后都有明确闸门。这篇文章我把这套东西的骨架、落地顺序和踩坑过程完整写下来,给同样被手动交易折磨过的朋友一个可直接参考的路线。

1. 一次真实的“放弃手动下单”时刻:复盘被迫重构的三个环节

1.1 手动交易最容易暴露的三个致命习惯

先说那次暴仓的具体过程。我的原始计划其实写得清清楚楚:当天只在某个价格区间内做一次试探性开仓,仓位不超过本金的某个比例,止损距离固定。等我真正打开行情软件,看到价格快速拉升,心跳一快,“感觉不进场就错过了”,先追加了一笔,又在回踩时补了一手。价格随后掉头向下,把止损打掉之后又拉了回来。那一单让我把之前三周的回测利润全部吐了回去。

这不是心态问题,至少不全是。真正的病根是三个习惯:

  • 第一,没有强制校验机制。我所谓的“计划”只在脑子里,没有一条代码、一个配置文件在开单前拦住我。系统不会因为“你今天已经连亏三单”而拒绝放行。
  • 第二,没有完整的操作历史。事发后我想复盘,发现自己根本不记得当时下单的精确时间、当时的账户权益、当时的滑点是多少。记忆里的复盘和真实的复盘完全是两回事。
  • 第三,止损之后没有冷却机制。被扫掉止损的瞬间人是想扳回来的,于是马上又开下一单,下一单又触发止损。连续止损会把小亏损滚成大窟窿。

我后来在 OpenAlice 里做的事,可以概括成一句话:把这三个习惯对应的三个环节全部自动化。决策入口只接受系统信号,执行出口只接受自动指令,中间的所有风险检查交给固定规则去判断。人只负责设计规则、观察结果、迭代规则,不负责在盘中“临场发挥”。

1.2 我需要一个能把策略“存档、回滚、审计”的系统

复盘完那次亏损之后,我做的第一件事不是去研究新指标,而是给自己提了一个问题:如果我用的是一套真正工程化的交易系统,暴仓这件事还发生得了吗?

答案是不会。因为在我加仓的那一刻,系统会发现:

  • 当前仓位已经超过该策略允许的最大仓位;
  • 当日已经触发过一次止损,冷却期还没过;
  • 我这次加仓的触发条件,和策略文件里定义的开仓条件完全不一致。

这些检查每一条都很简单,单拎出来对任何一个有经验的交易员来说都是常识。难的是把它们做成一套默认开启、不可绕过、有审计记录的体系。这就需要一个能存档所有策略版本的仓库,需要一条能回滚的风险预案,也需要一个能把每一次下单都记录成“提交记录”的账本。于是我在设计 OpenAlice 时直接借用了软件开发里 Git 的哲学,也就是后来这套架构最核心的理念:Trading-as-Git。

2. Trading-as-Git 治理模型:策略提交、分支回测与回滚发布

2.1 把每一次调参都变成一次 Git 提交

我在周围接触过不少做策略的人,他们最常见的工作方式是在某个策略文件里把参数改一改,跑一遍回测,发现结果行了就直接上实盘。两周后策略变差了,想改回去,却已经记不清之前那组参数到底是多少。这种“无版本策略开发”和“无版本软件开发”一样,注定是灾难。

Trading-as-Git 的第一条纪律:任何策略修改必须是一次 Git 提交,且提交信息必须写清楚三个问题——改了什么、为什么改、期望解决什么问题。

我给自己定的提交信息格式大概是这样的:

git commit -m "strategy=momentum_v3 feature=ema_slope_threshold target=reduce_drawdown reason=近两周回撤扩大,期望过滤假突破信号 result=详见backtests/2024-03-xx报告"

这看起来麻烦,但它带来的好处巨大。三个月后你回看历史,能精确知道自己的策略是怎么一步步演变成今天这个样子的:哪次调整是因为波动率变大,哪次是因为手续费结构变化,哪次是纯粹手痒瞎调。这些信息才是复利来源。

OpenAlice 的仓库结构也是围绕这个理念设计的。每个策略不是一个孤立脚本,而是一个包含入口信号、出口信号、风险参数、回测报告、运维脚本的完整目录:

OpenAlice/ ├── config/ │ ├── risk.yaml │ ├── data_sources.yaml │ └── secrets/ # API Key 等敏感信息,不入库 ├── agents/ │ └── momentum_v3/ │ ├── entry.py # 开仓信号 │ ├── exit.py # 平仓信号 │ ├── risk.py # 策略特有风控 │ ├── config.yaml │ ├── tests/ # 单元测试与断言 │ ├── backtests/ │ │ └── runs/ # 每次回测输出:报告、曲线、参数快照 │ └── ops/ │ ├── start.sh │ └── rollback.sh # 紧急降级脚本 ├── harness/ │ ├── scheduler.py │ ├── watchdog.py │ ├── executor.py │ └── audit_log.py └── audits/ └── daily_reconciliation.py

最开始有人觉得这套结构对个人交易者来说太“重”了,但我的体会正好相反。正是因为它重,你才不会在情绪上头的时候轻易改参数;因为改一次参数要走完整的测试和回测流程,你的“手痒动作”会被流程本身天然过滤掉。

2.2 回测就是 CI,模拟盘就是 staging,实盘才是 production

软件开发里有环境概念:本地环境、测试环境、预发布环境、生产环境。交易策略完全可以映射成同一套逻辑:

  • 历史回测 = CI 构建:每次策略提交都会自动跑一遍历史数据,生成收益曲线、最大回撤、夏普、胜率、盈亏比等指标,并把报告归档。如果回测结果突破了一些设定好的“红线”,比如最大回撤超过 20%,构建直接失败,不允许进入下一步。
  • 模拟盘 = staging 环境:用实时行情跑同样的策略逻辑,但是不真正下单。这一步验证的是“策略在当前行情下还灵不灵”,以及程序本身的稳定性。模拟盘没有真实资金约束,所以它不能验证执行层面的问题,但能暴露逻辑层面的问题。
  • 小资金实盘 = production 发布第一步:我只运行总仓位的很小一部分,相当于软件开发里的灰度发布。等运行一周到一个月,确认绩效和模拟盘没有大偏差,再逐步提高资金比例。

这套环境的价值在于,它把“能不能上实盘”从一种感觉变成了一个可验收的流程。任何一个策略都必须从下往上爬一遍,谁也不能从草稿直接跳到全仓生产环境。我见过太多人拿着一个过度拟合的回测曲线就全仓杀进去,这在 Trading-as-Git 体系里是被规则禁止的。

2.3 回滚不能只靠 git revert,还要有“停机释放”

Git 回滚代码很简单,但交易系统有个特殊问题:你可以回滚代码,却没法回滚已经持有的仓位。如果某次发布的策略有严重 bug,直接git revert把代码切回去只能解决“以后不再开新仓”,解决不了“当前持仓怎么处理”。

所以我给每个生产版本都配套了一份回滚预案。这里面最核心的工具不是我一开始设想的“立即清仓脚本”,而是一个更稳妥的三步停机释放流程:

  1. 停止所有新开仓信号:最优先的动作不是平仓,而是把入场逻辑挂起,避免系统在故障状态下继续裸露风险。
  2. 对现有持仓做风险评估:逐个订单检查止损是否有效、止损位是否需要按当前波动率做调整。该止损的让止损去执行,不该动的不要一刀切乱平。
  3. 确认旧版本稳定后,再切换代码并恢复开仓信号。

刚开始我觉得这个流程太温和,后来真遇到一次行情源数据异常导致策略频繁开平仓,我才意识到“立刻全部平仓”这种事情只有在极端情况下才需要做。90% 的故障场景里,最重要的其实是“先止血、再观察、后修复”,而不是恐慌式清仓。

3. OpenAlice 的本地 Agent 架构:数据、决策、执行与编排四层拆解

3.1 为什么坚持本地部署而不是云端托管

做量化交易,很多人第一反应是把系统放在云服务器上,因为方便、稳定、不占用本地资源。OpenAlice 的核心设计却是另一条路线:本地优先,Agent 跑在自己机器上。这不是标新立立,而是有实际理由的。

第一是账户信息的隐私性。实盘环境里,你的持仓、余额、策略信号都属于高敏感数据,放在本地意味着只有你自己能接触这些信息,不需要信任任何第三方平台的数据保管能力。第二是延迟。从策略发出信号到订单到达交易所,每一毫秒都可能影响成交质量。本地与行情源之间的链路更短,且网络路径完全由自己控制。第三是避免单点依赖。云端托管意味着你还要多维护一台服务器,多处理一种故障模式;本机只要一台稳定运行的主机,配合 UPS 和备用网络就能达到不差的可靠性指标。

当然,本地部署不等于没有安全工作要做。API Key 必须以加密形式保存在独立配置目录里,禁止写入 Git 仓库;系统要定期轮换密钥;对外访问权限要收敛到交易所需的进程。这些内容我会在后面的踩坑部分具体展开。

3.2 四层结构:数据层、决策层、执行层、编排层

OpenAlice 的 Agent 架构我分成四层,每一层都有明确的边界和职责。这样拆的好处是,出问题时能快速定位是数据问题、策略问题、执行问题还是运行环境问题。

先看数据层。它负责聚合行情数据、账户数据和历史基准数据,同时做完整性和时间戳校验。这一层产出的数据必须干净、连续、时间对齐。标的断线后补回来的数据如果缺了中间几根 K 线,这一层应该直接标记为不可用,而不是让决策层去“猜”。

决策层是 Agent 本身的业务逻辑:状态机、开仓信号、平仓信号、仓位目标、以及策略特有的风险参数。决策层的输入是数据层的“干净数据”,输出是一个结构化的“交易意图”,比如“以限价 100.5 买入 200 股,止损 99,止盈 103”。它不直接操作账户,也不知道怎么下单,这样策略逻辑就非常容易测试——输入一组历史数据,对比输出的交易意图是否符合预期。

执行层负责把交易意图转化为真实订单。它检查账户当前持仓、可用余额、市场深度,然后把意图翻译成具体委托并发送到交易所。执行层要处理限价单与市价单的转换、部分成交、撤单、重试、交易所拒绝等账务细节。

编排层是我后来慢慢补强的一层,也是让系统真正“稳”的关键。它不关心你用什么策略,只关心进程是不是活着、调度是否发生了重叠、磁盘日志够不够写、断线之后 Watchdog 是否把故障进程重启起来。

3.3 Agent 和 Harness 到底什么关系

在开发过程中,我经常被问到“你这个 Agent 和 Harness 到底怎么分工”。我的理解是:Agent 是大脑,负责思考;Harness 是躯干和神经系统,负责让大脑在一个稳定可靠的躯干里正常运转。

具体到 OpenAlice 里,Agent 一般对应一个策略。它的代码里只写市场逻辑:如果当前价格高于某个均线,产生一个开仓意图;如果持仓浮动亏损超过阈值,产生一个平仓意图。别的什么都不管。

Harness 则是围绕 Agent 的一层运行时框架,负责这些事:

  • 调度:保证一个 Agent 不会被重复启动,信号计算和订单执行不能在同一个 tick 里并发跑两遍。
  • 看门狗:监控 Agent 心跳。比如一个策略主循环超过 30 秒没有输出,就认为它卡死了,自动杀掉重启。
  • 资源限制:对日志大小、内存占用、网络重试次数做上限约束。
  • 审计:把所有关键事件都写入结构化日志,包括信号生成、风控拒绝、订单回报,保证事后任何一笔操作都能对账。

Agent 可以被替换,Harness 却要保持稳定。这就好比你可以换一个更聪明的交易员坐在驾驶座上,但方向盘、刹车、仪表盘这些基础设施不能随便换。这套分层让我后来迭代策略时非常舒服:换策略不用碰基础设施,修 Harness 也不用碰具体信号逻辑。

4. 风控闭环的四道闸门:入参白名单、实时熔断、仓位公式与日终对账

4.1 事前检查:把“临时起意”挡在参数之外

很多人理解的风控是止损,但真正的风控闭环从开仓之前就已经开始。OpenAlice 的事前检查围绕参数白名单和预算边界来做,核心目标是拦截系统之外的“人肉操作”和配置错误。

我的risk.yaml长这样:

risk: max_position_pct: 0.20 # 单策略最大市值占总权益比例 single_trade_risk_pct: 0.01 # 单笔交易最多承担账户权益的 1% 损失 daily_loss_limit_pct: 0.03 # 当日净值回撤超过 3% 停止开新仓 max_open_trades: 3 # 最多同时持有 3 个仓位 cooldown_seconds_after_stop: 300 # 止损后冷却 5 分钟才允许再次入场

启动 Agent 之前,系统会做一次静态校验:解析这份配置,检查数值是否在合法范围内。比如max_position_pct大于 1 就直接报错,因为仓位比例不可能超过 100%;single_trade_risk_pct为负也报错。这些看似废话的检查,在配置被复制粘贴出错时会救你一命。

更重要的是“零手工干预”原则:实盘运行时,Agent 只接受配置文件里定义的参数和策略逻辑产生的信号。任何不经过系统的外部指令都不该进入账户。要实现这个目标,OpenAlice 的做法是把交易所 API 的密钥权限缩小到只能由执行进程访问,人在盘中也只通过只读界面查看状态。这就是我说的“把临时起意挡在参数之外”。

4.2 事中检查:熔断器与下单前的三重校验

行情是实时变化的,单靠开仓前的检查不够。OpenAlice 在下单前会走三重校验,任意一重不过就拒绝挂单:

第一重是仓位预算校验。系统把已有持仓换算成市场价值,加上即将新增的仓位,如果超过了max_position_pct就拒绝。第二重是当日亏损熔断。每次收到账户权益更新后,系统计算当日回撤比例,一旦触及daily_loss_limit_pct,会把所有开仓信号挂起,直到下一个交易日。第三重是订单语义校验,执行层会核对订单方向、数量是否为正、价格是否远离涨跌停等基础语义。

熔断器是这层里最值得说的部分。它的状态有三个:正常、预警、熔断。进入预警状态时,系统允许平仓但禁止开新仓;进入熔断状态时,所有新订单都被拒绝,只保留已有的止损单继续工作。熔断条件可以是当日亏损比例、单笔亏损比例、连续止损次数、API 连续报错次数等。条件越多,覆盖的异常场景越多,但也不要盲目堆量,否则一次正常的行情波动就会触发无谓的停机。我实际用的核心条件只有四个:当日净值回撤、连续止损次数、行情源断连时长、订单回报超时率。

4.3 仓位公式:为什么单笔风险永远比仓位大小重要

新手容易纠结“这一单到底下多少手”,老手更关心“这一单如果错了会亏掉账户的多少百分比”。这两个口径完全不同。

OpenAlice 计算仓位用的是一个经典的风险倒推公式:

开仓数量 = (账户权益 × 单笔风险比例) ÷ (入场价 - 止损价)

举个例子:账户权益 100 万,单笔风险设成 1%,也就是单次止损最多亏 1 万;入场价是 100,止损价设在 98,每股风险是 2 元。那么开仓数量 = 1 万 ÷ 2 = 5000 股,投入市值是 50 万,占总权益 50%。如果止损距离变窄,比如只有 0.5 元,同样的风险预算下可以买 2 万股,投入市值会变成 200 万,这时候就需要配合总仓位上限来收敛。

这个公式的价值在于,它让“仓位大小”不再依赖人的心理预期,而完全由“你愿意承担多少风险”决定。止损距离近,仓位自然大;止损距离远,仓位自然小。这样每笔交易的风险贡献是接近恒定的,账户的波动也就不会因为某一次判断失误而失控。

4.4 事后对账与复盘:闭环的最后一块拼图

风控如果只做到事中和事前,还没有真正闭环。真正让风险体系不断进化的环节,是日终对账和周期性复盘。

每天收盘后,OpenAlice 会拉取交易所账户的真实持仓和成交记录,与本地策略日志里的“预期成交”做比对。对账要回答三件事:策略信号生成后是否真的下单了?订单是否以预期价格范围成交?当前持仓是否与本地记录一致?任何一项对不上都会产生一条审计告警。账对不上,其他一切分析都是白搭。

周度复盘时,我会把每个策略的回测绩效和实盘绩效放在一起比较。重点看几个偏差指标:实际滑点是否比回测假设高、成交率是否下降、信号触发频率是否与回测一致。如果实盘绩效持续系统地差于回测,我会沿着数据层到执行层逐步排查。这里非常容易出错的一点是手续费和滑点模型过于乐观,常见做法是在回测里至少按真实费率再上浮一定比例来模拟冲击成本,宁可保守,不要虚假繁荣。

把这些对账和复盘结果再带回参数配置阶段,就形成了一个真正的闭环:实盘数据反馈到下一次参数调整与风控阈值修订,而每一次修订又通过 Trading-as-Git 留下记录,可追溯、可回放、可审计。

5. 从空仓库到实盘运行:我实测跑通的七步落地流程

5.1 第一步到第三步:搭建骨架、固定数据源、建立基线

光理解理念不够,落地步骤才决定你能不能真的跑起来。我完整跑过一遍,最顺的路线是下面七步。

第一步,搭建仓库骨架。先创建一个裸 Git 仓库,把前面展示的目录结构填进去。这一步不用急着写策略代码,先保证config、harness、audits都有明确位置,敏感信息如 API Key 用环境变量或加密文件方式处理,不入库。

第二步,固定数据源与校验逻辑。连接行情源和账户 API,写一个数据完整性检查脚本:K 线是否连续、时间戳是否对齐、是否有异常跳空。这一步做不好,后续所有回测和实盘信号都可能建立在不干净的数据上。

第三步,选择第一个策略并建立回测基线。我不建议上来就写一个新策略,最好先把自己过去最熟悉、逻辑最简单的一套规则搬进来,比如双均线交叉加固定止损止盈。为它生成第一份回测报告,存在backtests/runs/下。这份报告就是后期所有比较的基准线,策略好不好,要和它自身的历史版本比,而不是和别人的收益数字比。

5.2 第四步到第六步:接上风控、走模拟盘、小资金发布

第四步,把风控配置完整接进来。把第二小节里的risk.yaml从模板改成实际可执行的参数,并启动静态检查脚本验证配置合法。这一步的逻辑是:风控不是事后补救,是在第一次真正下单前就必须存在的系统能力。

第五步,进入模拟盘环境(staging)。模拟盘会消费实时行情、产生信号、在日志里模拟下单,但不连接交易所接口。我个人会在模拟盘阶段至少运行一周,观察 Agent 是否稳定、信号频率是否合理、Harness 有没有触发重启。模拟盘的验证重点是“程序运行问题”,不是“策略收益问题”,收益好不好是回测阶段该回答的事情。

第六步,小资金实盘发布。先给生产环境打一个 Git tag,比如prod-2024-01-15-v1,然后只配置最小资金量运行。我建议这个阶段的金额要小到即使全部亏损也不心疼,但又要大到超过最低下单门槛。小资金实盘运行一周以上,确认系统在真实行情和真实执行链路中表现正常,再进入下一步。

5.3 第七步:灰度加仓与定期迭代

第七步不是一次性的动作,而是持续过程。当小资金实盘与模拟盘的表现偏差在可接受范围内,我会按比例逐步提高资金。加仓的标准不是“最近赚钱了所以加”,而是“执行层的滑点、成交率、系统稳定性都验证过了”。每加一次仓位,相当于一次生产变更,同样要留提交记录。

之后进入日常运营节奏:每天看审计日志和对账报告,每周看绩效偏差,每月做一次策略回测再验证。这套节奏让我从原来“天天盯盘、天天焦虑”的状态里解脱出来。价值不在于省了多少事,而在于每一次系统报警和每一次绩效变化都有据可查,不再是摸黑做交易。

6. 本地部署时我踩过的五个真实坑:时间同步、断网重连、日志爆炸与数据漂移

6.1 时间偏差导致信号错位,行情时间戳必须统一

第一次实盘运行后,我发现一个诡异现象:策略在本地逻辑里判断某根 K 线已经收盘,但行情源时间戳还没到收盘点,导致信号被计算在一个未完成的 K 线上。查到最后是本地机器时钟和交易所服务器时钟差了十几秒。这个问题在手动交易时完全无感,但对自动化系统来说足以造成信号错位。

解法分两层。第一层是时间同步,定时用网络时间协议同步本机时间;第二层是代码层面强制所有行情判断使用行情源提供的交易所时间戳,而不是本地机器时间。K 线完成的标准必须是行情源里那根 K 线的收盘时间小于等于当前交易所时间,和本地时钟无关。

6.2 网络断连后的回补数据会制造“假突破”

有一次策略在一个突破信号附近反复开仓又平仓,我一度以为是策略逻辑坏了。检查日志后发现,是行情源在凌晨断线了一段时间,重连后一次性把缺失的数据回补过来。决策层看到几百根 K 线“凭空出现”,以为行情发生了剧烈变化,于是一口气触发了多个信号。

这就是数据漂移之外最隐蔽的一类问题:回补数据会让系统以为“瞬间发生了大波动”。我的解法是在数据层增加一个“新鲜度”标志。每一根 K 线必须同时满足连续性校验和时间戳新鲜度校验才会被送入决策层;如果断线期间的数据是一次性补回来的,系统会标记该时段数据为“离线重建”,并自动跳过所有基于这些数据产生的信号。宁可错过一段行情,也不能吃下一段假行情。

6.3 日志没有轮转,磁盘写满后进程悄悄挂掉

运营第三周时,Agent 突然变得极其卡顿,重启也没用。排查发现是日志文件已经占满了整个磁盘。因为每次下单我都把完整订单、回报、内部状态都打进了日志,单日就能写出几 GB,一个月下来直接把机器拖垮。

现在的做法是日志按天轮转,保留最近 30 天,超出部分自动清理。关键审计信息单独抽出来写进 SQLite 或 CSV 表,保证日志可以被清理而审计记录不丢失。另外给 Harness 加了一个磁盘水位监控,低于 10% 时报警并进入只读模式,停止写新日志但保留交易执行能力。对本地部署来说,“机器自己把自己写死”是最不值得的故障。

6.4 参数漂移与市场结构变化,让回测失效

运行到第二个月,某个策略的实盘表现开始稳定地弱于回测。我反复检查了代码、数据、执行链路,都没有发现错误。后来把两个月的时间窗口切成小段逐段分析,才发现问题的根源是市场波动率结构发生了变化:货币政策和市场情绪导致日内波动形态改变,策略依赖的突破特征在实盘中出现频率明显下降。

市场结构漂移没法靠一次代码修复解决,只能靠持续的监控和再验证。我用了一套简单的办法:每个策略维护一个“绩效健康度”指标,把最近 20 个交易日的滚动收益和回测期望收益做比较,连续跌破某个阈值就自动把该策略的资金权重下调一半,并生成提醒。等它重新稳定再考虑恢复。这个机制比我每天盯盘判断“策略还灵不灵”可靠得多。

6.5 账户权益口径不一致,导致仓位计算失真

最后一个坑出在仓位公式上。账户 API 通常会返回总权益、可用余额、持仓保证金等多个口径。最开始我用可用余额来计算仓位,遇到已有持仓占用保证金时,计算出来的可加仓数量会比预期小很多;后来改成总权益,又在极端行情下因为保证金不足导致订单被交易所拒绝。

最终的统一口径是:用总权益来计算风险预算和单笔风险额度,用可用余额来作为下单前的最终否决条件。任何一笔新单不仅要满足风险公式给出的数量上限,还必须保证下单后账户剩余可用余额仍为正值,且高于某个安全垫。两道口径各管各的事,不再混用,仓位计算才真正稳定下来。

7. 从单策略到多 Agent 策略组:下一步我会怎么扩展这套体系

7.1 多 Agent 隔离与全局熔断,让策略之间不互相拖累

单策略跑顺之后,很自然的想法是增加更多策略来平滑收益曲线。但多策略不是把几个脚本塞进同一台机器同时跑这么简单。我目前正在实践的方向有两个:策略隔离和全局风险集中控制。

策略隔离指的是每个 Agent 拥有独立的状态目录、独立日志、独立配置。即使一个 Agent 因为数据异常或代码 bug 崩溃,也不应该影响其他 Agent 运行。实现上,Harness 用独立进程来跑每个 Agent,进程之间只通过消息总线通信。一个 Agent 的重启、回滚都在它自己的生命周期里完成,其他 Agent 完全无感。

全局风险集中控制则是反过来,所有 Agent 的仓位和风险需要汇总到同一个全局熔断器里。每个 Agent 有自己单策略的风控参数,但汇总后的总仓位、总当日亏损、总单笔风险额度,还要经过全局阀值校验。任何一笔订单要么同时通过单策略和全局两层检查,要么被直接拒绝。套一个人人听过的说法:策略之间可以各跑各的,但“这辆车总不能每只脚都踩自己的油门”。

7.2 Agent 的关停比启动更难:给每个 Agent 写一份 shutdown 协议

扩展多 Agent 的过程中,我踩到的最深的一个设计失误是从来没认真考虑过“怎么把一个 Agent 安全停下来”。停一个正在运行的策略,比停一个普通服务麻烦得多:它手里可能有持仓,它可能在等待某个止损触发,它可能处于一个不完整的状态机分支里。

我现在给每个 Agent 都写了一份 shutdown 协议,按顺序执行:先把 Agent 状态置为“不再接收新信号”,然后等待当前持仓的自我保护逻辑接管,也就是让已有的止损止盈继续挂在交易所;接下来执行一次状态快照,把内存中的持仓、参数、pending 订单全部落盘;最后才终止进程。这个顺序保证了“停机”和“清仓”是两件事,停机不一定需要马上清仓,但停完机之后系统必须处于一个可解释、可审计的安全状态。

7.3 这套体系对我最大的改变:亏损时知道为什么亏

写到最后,说一点个人体会。OpenAlice 这套 Trading-as-Git 本地量化 Agent 架构,并不会提高任何策略的“胜率”,更不会保证赚钱。它真正解决的问题是把交易从玄学变成工程:每一次决策有据可查,每一次参数调整有提交历史,每一次亏损可以被分解到数据、策略、执行、风控的具体环节。

对我这样的人来说,最值钱的东西反而不是某一次漂亮的交易,而是每晚能看着审计日志说一句“今天这笔亏损是因为策略在某个时刻触发了一笔计划内的止损,执行路径没有问题,这是策略本身需要改进的地方”。从“我怎么又亏了”变成“我清楚地知道我为数不多的几条亏损原因分别是什么”,这中间的差距,就是我从盲目实盘走到本地量化 Agent 体系后的最大收获。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询