用Python构建交易策略:回测的误导与风险管理

Bifu Editorial · 2026-05-25 · 阅读 8 分钟


目录

Python让测试交易想法变得快速,但也同样容易让你自欺欺人。本文实用地讲解了环境搭建、数据处理、回测陷阱,以及决定系统能否生存的仓位规模和止损设置。

Python不会给你优势,它只提供一个测试平台。

2024年一项针对量化金融开发者的调查显示,Python的使用率为81.3%。大银行在用,金融科技公司在用,大多数接触代码的个人交易者最终也会用到它。原因很平常也很正确:库很完善,语法不碍事,你可以在一个下午内从原始价格序列到经过测试的规则。

但有一点容易被忽略。Python是一个测量工具,而不是一个策略。它会愉快地回测一个糟糕的想法,并打印出一条漂亮的权益曲线。真正重要的技能不是编写循环——而是知道哪些结果在欺骗你。把工具当作一种方法来检验某个想法是否能在真实数据和真实成本中存活,它才有价值。把它当作印钞机,它只会悄悄给你上一堂昂贵的课。

建立环境,别在未来自欺欺人

三个库完成了大部分工作。NumPy处理数组运算。pandas提供DataFrame,一旦你开始操作价格和成交量数据,它们就存在于其中。matplotlib绘制图表,当某些数据看起来不对劲时,你会盯着这些图表看。

pip install numpy pandas matplotlib

至于编辑器,选一个能让你保持诚实的。PyCharm拥有真正的调试器和集成测试,这比人们承认的更重要——很多“策略有效”的情况其实是一个bug,如果你逐步跟踪一笔交易就能发现。VS Code更轻量,也很好用。Jupyter notebooks非常适合探索,但对于你计划交易的东西来说确实很危险,因为单元格可能乱序执行,而且很容易让未来的数据残留在变量中,泄露到“过去”的计算里。如果你用notebooks做研究,在信任最终逻辑之前,将其重建为一个干净的脚本。

从第一次提交开始就把整个项目放在Git下。不是为了协作——是为了你自己。当一个回测在周二看起来很棒,周四却崩溃时,版本历史记录是你找到那一行改变了代码的方式。一个无法精确重构的策略,是一个你无法信任的策略。

两类策略,两种不同的错误方式

大多数系统化想法属于两类中的一类,每类都有其特有的失败模式,值得提前指出。

趋势跟踪 利用动量。规则大致是:某物正在移动,就加入,直到它停止。它有效是因为趋势的持续性比随机概率所暗示的更常见——但它也带来痛苦,因为大多数时候没有趋势,所以你会在震荡中不断小额亏损,等待那笔能补偿一切的行情。趋势系统以低胜率和少数大赢家取胜。如果你无法忍受在大部分交易中亏损,你可能会在关键交易来临前放弃。

均值回归 下相反的赌注:价格被过度拉伸,会回弹到均值。它有很高的胜率,感觉很好,直到某次价格没有回归并继续远离。那单笔交易可以抹去一连串的小额盈利。没有硬止损的均值回归不是策略,而是倒计时。

注意对称性。趋势跟踪要求你容忍频繁的小额亏损;均值回归则要求你经受住罕见的大亏损。两者都没有更安全,只是以不同的方式分配痛苦,而 你实际能承受的回撤曲线 应该决定你构建哪一种。

技术分析——解读价格和成交量历史以寻找可重复的模式——是大多数Python策略所编码的内容。基本面分析——对基础业务或资产进行估值——更难自动化,通常作为过滤器而不是信号出现。没有规则说只能选一个,但要清楚你的代码实际在测试什么。

“交易成功的关键是情绪纪律。如果智力是关键,那就会有更多的人在交易中赚钱了。”——维克多·斯佩兰迪奥

这句引文不是装饰。编码策略的全部意义在于将决策从你的直觉转移到你在冷静时制定的规则上。 纪律问题并不会因为计算机下单而消失 ——它转移到你是否会在系统处于水下那天真正遵循它。

数据是大多数回测出错的地方

你的策略的诚实程度取决于其底层数据。获取数据是容易的一半。

你可以从API获取价格——Alpha Vantage和Yahoo Finance提供免费层级,IEX Cloud提供更干净的数据流——或者从付费提供商如Bloomberg、Refinitiv或Quandl获取,如果你需要深度和可靠性。免费数据适合学习,但要知道免费数据流有缺口、偶尔的坏数据点,有时还会静默调整历史数据。

然后是数据清洗,而这里就是结果被悄悄制造出来的地方:

问题 常见修复方法 陷阱
缺失值 用均值/中位数填充、插值或删除行 用周围点插值可能引入未来数据,而策略本不该拥有这些数据
不同资产间的量纲差异 Min-Max缩放到[0,1]或z-score标准化 在整个数据集上拟合缩放器会让测试期间的统计量泄露到训练中
错误数据和异常值 过滤或截断极端值 截断过于激进,会恰好抹去那些在实盘中会击垮策略的波动尖峰

必须牢记在心的两个词是 前视偏差生存偏差。前视偏差是指在策略无法在决策时获得的信息——使用今日收盘价来做今日入场,使用尚未发生的数据计算出的归一化值。生存偏差是指仅对今天仍然存在的资产进行测试,这悄悄删除了每一家归零的公司,让任何“逢低买入”规则看起来都很出色。两者都会夸大回测结果,而且除非你主动查找,否则它们是无形的。

诚实回测,以及无人建模的成本

数据清理干净后,回测在机械上很简单:在历史上运行规则,记录它会做什么,查看结果。机械部分并不是难点,难的是相信输出结果。

忽略成本的回测是虚构的。每笔交易都要支付点差,可能还有佣金,以及滑点——你看到的价格与你实际成交价格之间的差距。在一个交易频繁的策略上,仅成本一项就可以将打印出来的利润变成实际亏损。悲观地建模成本。如果边缘仅在零成本下存在,那就没有边缘。

然后是过拟合,这是所有失败中最诱人的一种。添加足够多的参数,你可以完美拟合任何过去。一条为精准匹配2021-2023年而调整的曲线,对2025年没有任何意义。防御措施古老且不引人注目:保留策略在开发过程中从未见过的数据,在不同的市场体制下测试,并对任何“必须是14”否则整个系统就崩溃的参数保持怀疑。一个稳健的边缘有点模糊。一个脆弱的边缘则锋利如刀且毫无价值。

教程跳过的那一半系统

入场信号吸引了所有注意力,但它们是工作系统中最重要的部分中最不重要的。

入场规则告诉你何时进场,但没说多少、何时出场,或如何知道你错了。这三个因素——仓位规模、离场和失效确认——才是区分策略与直觉的东西,它们应该像信号一样明确地写在代码中。

  • 仓位规模 决定单笔交易可能让你损失多少。固定分数模型——每笔交易承担账户恒定的小比例风险——能防止一次糟糕的判断变成灾难性的损失。 你如何确定仓位大小比交易什么对生存更重要,而且编码起来很简单。
  • 止损与失效确认 在入场前就定义好证明想法错误的价格。不是感觉——而是水平。 止损的位置应该来自策略结构本身,而不是来自你当天愿意损失多少。如果没有一个价格会让你退出,那就没有交易。
  • 离场逻辑 也处理盈利交易。止盈或移动止损的规则,能将好的入场转化为已实现的收益,而不是一次过山车。

将这些作为策略的一流部分来编码,让回测来衡量它们。一个有平庸信号但严格风险控制的系统,通常能跑赢一个虽有出色信号但无风险控制的系统。这不是口号,而是当你实际测试两者时权益曲线所显示的结果。一旦涉及杠杆,这一点更为重要,因为一个对你不利的仓位可能在 触发追加保证金或被强制平仓 之前,你的观点还来不及实现。

从何入手

从小处着手。一个资产,一个清晰的规则,明确的止损和仓位规模,诚实地模拟成本,以及一块策略在开发期间从未触及的数据。运行它。阅读回撤,而不仅仅是回报——最糟糕的一段将是你实盘时必须经历的部分,也是告诉你能否承受的数字。然后写下你看到的,这样下一个版本就能用证据而非记忆来争论。

Python让这一切变得快速,但不会让任何东西变得真实。这个工具的唯一诚实取决于你是否诚实——而编码进策略的纪律,正是你 在市场让你感到不适时仍需保持的纪律 。这并不能保证盈利结果;一个经过测试的规则是一种故意管理风险的方法,而不是对结果的承诺。

Ready to put this into practice?

Python让测试交易想法变得快速,但也同样容易让你自欺欺人。本文实用地讲解了环境搭建、数据处理、回测陷阱,以及决定系统能否生存的仓位规模和止损设置。

Start trading

免责声明

This content is for educational purposes only and does not constitute financial, investment, legal, tax or trading advice. Digital assets, RWA products, gold-related products and forex products involve risk, including possible loss of principal. Always review product rules and risk disclosures before trading.