一、目标与范围:用同一套流程跑通“回测 → 模拟 → 实盘”
双均线是最典型的“能快速跑通全流程”的策略:规则足够简单,能把精力留给工程问题。本文不追求把双均线写成万能策略,而是把关键目标写清楚:你要得到一条可复盘的数据链路、一份可复现的回测结果、以及一套在实盘环境里不崩溃的运行系统。
为避免“回测看起来很美、实盘完全两套世界”,全流程会围绕三个问题展开:同一份数据口径能否贯穿历史与实时;同一套信号定义能否贯穿回测与实盘;同一套风控与监控能否在断线、滑点与波动放大时兜底。
二、策略规则要写成“可执行规格”:信号、确认与退出
双均线的核心只有一句话:短均线上穿长均线做多,下穿平仓或反向。但要让策略可复盘,你必须补齐规格:用什么周期的 K 线,均线窗口是多少,信号是否需要收盘确认,下一根开盘成交还是当根成交,是否允许反手,是否设置冷却期,是否限制日内最大交易次数。
很多回测差异不是来自指标,而是来自“信号时刻”的定义。最稳妥的做法是以收盘确认信号,用下一根 bar 的开盘价模拟成交,并在实盘里对齐为“信号生成后下一个可成交时刻下单”。只要你把信号时刻统一,回测和实盘的差距就会明显缩小。
三、数据口径:时间戳、交易日历与复权必须一开始就统一
双均线对数据质量非常敏感:缺口会改变均线窗口的有效样本数,重复会引入虚假信号,时区错位会让日线与分钟线产生系统性漂移。建议从第一天就把内部数据模型定下来:统一 UTC 毫秒时间戳、统一字段命名(open/high/low/close/volume)、统一交易日历处理方式、统一复权或不复权口径。
更重要的是“对账思维”:你需要能回答这两个问题——某一根 bar 的来源是什么、是否可能被更新;实时流落盘回放后与历史接口是否一致。如果做不到对账,后面所有策略讨论都只能停留在解释层。
四、用 iTick 获取历史 K 线:把“拉数据”当成可验收模块
历史拉取不是一次性脚本,而是数据产品的一部分。你要明确三件事:拉取范围(开始/结束)、缺口处理(是否允许空洞)、以及幂等性(重复拉取是否覆盖一致)。建议把拉取做成固定函数,并把请求参数、返回条数、缺失比例写进日志。
import requests
BASE = "https://api.itick.org"
TOKEN = "your_api_token"
headers = {"accept": "application/json", "token": TOKEN}
params = {
"region": "US",
"code": "AAPL",
"start": "2025-01-01",
"end": "2026-04-20",
"interval": "1d",
}
r = requests.get(f"{BASE}/stock/kline", params=params, headers=headers, timeout=15)
r.raise_for_status()
rows = (r.json() or {}).get("data", [])
print("rows", len(rows))
拉取完成后不要急着回测,先做两步验收:检查时间戳是否严格递增、检查是否存在缺口或重复。只要这两步不过关,均线策略的回测结果通常没有参考意义。
五、backtrader 回测实现:让策略只做“产出信号”
从工程可维护性出发,建议把系统拆成三层:数据层负责统一口径与补洞,策略层只负责产生“允许开仓/允许平仓”的信号,执行层负责下单细节与成交假设。回测阶段你可以把执行层简化为 backtrader 的 broker,但接口仍然要保持一致:策略不应该直接写成交价与下单方式。
策略实现时要明确两个关键点:一是均线的计算基于 close 还是某种加权价格;二是信号是否使用上一根 bar 的已知数据,避免使用未来信息。只要策略层保持纯粹,你在后续从回测迁移到实盘时就不会被迫重写核心逻辑。
六、交易成本与滑点:不写清楚就等于没回测
双均线在趋势期表现好,但在震荡期会频繁换手,交易成本对结果的影响往往比均线窗口更大。成本建模至少要包含三项:手续费、点差/滑点、以及成交失败或部分成交的概率假设(在回测里可以先用保守滑点替代)。
更实用的做法是把成本写成“区间”:给一个乐观成本与一个保守成本,分别跑一遍回测。若两者结论完全相反,说明策略优势并不稳健,后续应该把精力放在减少交易次数(过滤、冷却期、波动阈值)而不是继续调窗口参数。
七、稳健性检查:不要只做一次回测,要做“滚动 + 敏感性”
把双均线做成可上线策略,核心不是找到一组最优参数,而是证明它在参数附近不会崩塌。建议至少做两类检查:滚动回测(把样本切成多个窗口重复跑),以及参数敏感性(短均线、长均线在合理范围内变化时收益/回撤是否平滑)。
如果你发现策略对某个参数极度敏感,通常意味着它在拟合某段行情结构。此时最有价值的动作不是继续调参,而是回到数据与执行假设:是否存在缺口导致均线样本数变化,是否存在成本低估导致换手被奖励,是否存在信号时刻定义不一致导致虚假优势。
八、从回测到实盘:数据缺口、执行缺口、风控缺口
实盘与回测差异最大的地方,通常不是均线公式,而是三类缺口。数据缺口来自断线、乱序、重复与补洞:你必须把“最后确认处理到的时间戳/序号”写入状态,并在重连后用 REST 补齐缺口,再把补洞数据与实时数据对账,否则同一段行情在不同运行周期里会产生不同信号。
执行缺口来自点差、滑点、撮合深度与限流。更稳的设计是策略输出“允许交易”的意图,执行模块根据当前流动性决定市价/限价/放弃,并把成交耗时、滑点与失败原因记录下来供复盘。只要执行层有足够可观测性,你才能定位问题到底出在策略还是出在市场与系统。
风控缺口来自策略的“天然弱点”:双均线会在震荡期反复止损。建议把冷却时间、最大日内交易次数、波动过滤与最大回撤阈值写成硬规则,并允许在行情异常或数据异常时降级到“只观察不交易”。
九、监控与告警:把交易系统当成长期运行的软件
实盘系统的目标不是“跑起来”,而是“长期不崩”。建议至少监控六类指标:行情延迟、断线次数、缺口长度、重连耗时、下单成功率、以及成交滑点分布。对双均线这种频繁换手策略,滑点分布的尾部尤其关键,它会决定你是否在关键时刻被“最差几笔成交”拖垮。
告警也应分级:数据链路异常(断线、缺口扩大)优先触发降级;交易链路异常(下单失败、拒单增加)优先触发暂停开仓;风险告警(回撤或波动阈值触发)优先触发减仓或清仓。把告警与动作绑定,系统才具备自我保护能力。
十、结语:让策略变成资产的关键是“可复盘与可对账”
双均线策略本身并不稀奇,真正稀缺的是一套能复盘、能对账、能持续运行的链路。只要你把口径统一、把策略写成规格、把成本写成区间、把实盘缺口写成工程约束,你就能把任何一个简单策略变成可迭代的研究资产。
当你能在每次回撤后明确回答三件事:信号是否一致、执行是否偏离、风控是否按规则触发,你的系统就开始进入正循环。最终你得到的不只是一个双均线示例,而是一条从想法到实盘的可复制流程。



