手动回测10个策略要多久?资深交易员算过账:一个策略跑完历史数据平均40分钟,10个就是6.7小时。这还没算参数调优的反复折腾。更糟的是,人的注意力会漂移,凌晨2点的回测结果和上午10点的可能完全是两套标准。
一位独立开发者受够了这种"假装在分析"的状态,干脆写了个 overnight tournament system(隔夜策略锦标赛系统)。核心逻辑粗暴直接:让策略在真实市场数据上互相厮杀,按夏普比率和胜率排名,第二天早上给你一张 leaderboard(排行榜)。进化论的压力测试,但对象是交易算法。
4个文件撑起整套系统
TradeSight 的代码结构干净得像产品经理画的架构图:
app/ 目录管执行:dashboard.py 跑 Flask 路由,runner.py 是策略引擎,alpaca_client.py 封装了 Alpaca 的 API 接口。strategies/ 目录放策略:base.py 定义基类,MACD、RSI 等具体策略继承实现。cron/ 目录就一个 overnight_run.sh,负责定时触发。
没有微服务,没有消息队列,没有 Kubernetes。开发者解释:「这套系统的目标是验证想法,不是支撑百亿资管。」
策略接入的门槛被压到极低。继承 Strategy 基类,实现两个方法:compute_signals 返回买卖信号数组(1 买、-1 卖、0 持有),submit_orders 把信号转成模拟订单。一个 MACD 金叉策略的完整代码不到 50 行。
锦标赛怎么跑:6个策略的平行宇宙
系统内置了 6 个开箱即用的策略。每晚的 tournament 流程如下:
对每个策略,遍历全部交易标的。从 Alpaca 拉取 200 分钟 K 线,转成 OHLCV 格式喂给策略。策略吐出信号,系统提交纸面订单。第二天早晨按夏普比率 + 胜率加权排序。
关键设计:所有策略跑的是同一时段的同一批数据,排除了「A 策略测的是牛市、B 策略测的是熊市」这种不公平比较。就像把六匹马放在同一条跑道、同一个发令枪下。
开发者特别强调了 paper trading(模拟交易)的价值:「回测是开卷考试,纸面交易是闭卷小测。价格滑点、订单延迟、部分成交这些摩擦成本,只有真金白银的模拟才能暴露。」
为什么不用现成的回测框架?
Backtrader、Zipline、QuantConnect 这些工具已经存在多年。TradeSight 的区别在于「 overnight 」这个场景定义。
传统回测框架假设你坐在屏幕前,点一下跑一批结果。TradeSight 假设你在睡觉。cron 任务凌晨自动触发,runner.py 并行执行多个策略进程,dashboard 早晨展示排名。整个流程不需要人参与。
这种设计牺牲了一部分灵活性——你不能中途改参数、不能可视化逐笔成交。但换来了可扩展性:加第 7 个策略,只需要新建一个 .py 文件;加新的交易标的,改一下配置列表。
「大多数交易员的策略死在『想测但没空测』,而不是『测了但不好』。」开发者说。
一个被刻意保留的粗糙
代码里有个细节:策略的 submit_orders 方法直接调 Alpaca API,没有中间缓存,没有失败重试。这在生产系统里属于事故隐患,但开发者故意没修。
「纸面交易的 API 限额很宽松,失败率极低。加重试逻辑会增加代码复杂度,而复杂度是策略迭代的最大敌人。」他算过账:过去 3 个月跑了 400+ 次 tournament,API 失败次数是 0。
这种「够用就好」的取舍,贯穿整个项目。Flask 没上蓝图,数据库用 SQLite,前端是原生 HTML 没套框架。全部代码加起来不到 800 行。
「我试过用更重的技术栈重写,结果花在调依赖上的时间超过了写策略。」
TradeSight 目前托管在 GitHub,文档只有 README 里的快速开始。开发者没打算商业化,「这工具解决的是我自己的痒点,顺便看看有没有同类。」
如果你也有 10 个策略在脑子里打架、却没时间一一验证——你会选择手动回测到深夜,还是写个脚本让机器替你跑完这场淘汰赛?
热门跟贴