海龟交易法则 — 完整实施方案规范

基于 Curtis Faith,Way of the Turtle: The Secret Methods that Turned Ordinary People into Legendary Traders (2007)


目录

  1. 概述
  2. 海龟心态
  3. 完整海龟交易系统
  4. 仓位确定 — N系统(基于ATR)
  5. 入场规则(详细)
  6. 止损规则
  7. 出场规则
  8. 交易的市场
  9. 风险管理 & 回撤
  10. 优势、期望 & 统计
  11. 系统设计原则
  12. 行为 / 纪律规则
  13. 常见错误
  14. 完整交易生命周期示例
  15. 实施伪代码
  16. 比较:系统1 vs 系统2
  17. 关键语录

1. 概述

1.1 海龟实验

1983年,传奇商品交易员 Richard Dennis 与他的搭档 William Eckhardt 就一个看似简单的问题打赌:交易可以教会吗,还是这是一种天赋?

Dennis 认为他可以召集一群普通人——没有交易经验的人——教他们他的规则,给他们资金交易,他们会变得盈利。Eckhardt 不同意,他认为 Dennis 的能力中有某种内在的东西无法通过指令传递。

为了解决这个赌注,Dennis 通过《华尔街日报》广告招募了第一批"海龟"(名字来源于他在新加坡参观的海龟养殖场,他说"我们要像他们养海龟一样培养交易员")。第二期班于1984年跟进。

1.2 招募

超过1000人申请。Dennis 和 Eckhardt 在两期班中总共选择了大约 23名海龟。背景刻意多样化:一位扑克牌玩家、一位游戏设计师、一位会计师、一位保安、一位龙与地下城玩家等。选拔标准聚焦于:

1.3 结果

Dennis 是对的。在项目进行的大约四年半时间里,海龟们总共获利 超过1.75亿美元。Curtis Faith 是最成功的海龟,当时年仅19岁,为Dennis 个人赚了超过3100万美元。

海龟实验证明了:

1.4 为什么这本书重要

数十年来,海龟规则一直是保密的。当它们最终在网上发布时(先是前海龟 Russell Sands 部分发布,然后更完整),Faith 觉得背景缺失了。这本书不仅提供了规则,还提供了背后的理由、心理学和系统设计哲学。没有理解为什么它们有效和什么使它们难以遵守,规则本身毫无价值。


2. 海龟心态

2.1 概率思维

海龟被教导将交易不是作为一系列单独的交易,而是作为一个统计过程来思考。任何单笔交易本质上是随机的——你无法提前知道它会赢还是输。你可以知道的是大量交易的期望值

这需要思维的根本性转变:

新手思维 海龟思维
"这笔交易会成功吗?" "像这样的100笔交易的期望值是多少?"
"我已经连续输了5笔——系统坏了" "5连败在正常统计方差范围内"
"我应该跳过这个信号;它看起来很弱" "我必须接受每个信号来捕获统计优势"
"我要拿部分利润锁定收益" "我将让系统的出场规则决定何时平仓"
"这个市场感觉不对" "我的感受与系统的优势无关"

2.2 优势与期望

优势是一种统计优势,在大量发生中将产生净盈利。它不意味着每笔交易都赢——远非如此。赌场在轮盘赌上的优势只有约5.26%,却能产生数十亿。海龟的优势在概念上类似:每笔交易小,但通过数百笔交易 relentless 正向。

期望是优势的数字表达:

期望 = (获胜概率 × 平均盈利) - (失败概率 × 平均亏损)

对于海龟,典型特征是:

这意味着:E = (0.38 × 4.5R) - (0.62 × 0.8R) = 1.71R - 0.50R = +1.21R 每笔交易

+1.21R的 正期望意味着每冒险1美元,系统平均返回1.21美元——一个巨大的优势。

2.3 大数定律

优势只在大量交易样本中显现。在任何短序列——10、20、甚至50笔交易——中,随机性占主导。海龟被教导:

这就是为什么一致性和纪律比系统的具体参数更重要。

2.4 破坏交易员的认知偏差

Faith 花费大量篇幅讨论为什么大多数人即使获得盈利系统也会失败。关键偏差:

偏差 描述 它如何破坏交易
损失厌恶 损失比同等收益感觉糟糕约2.5倍 交易员提前兑现赢家并让亏损运行——恰恰与有效方法相反
近因偏差 过度加权近期事件 3笔亏损后,交易员跳过下一个信号——而这通常是大赢家
结果偏差 通过结果而非过程判断决策 来自糟糕过程的盈利交易强化了坏习惯
锚定 执着于参考价格 因为购买价格而拒绝止损
沉没成本谬误 持有亏损因为已经投入 加仓亏损仓位以"摊薄成本"
后见之明偏差 相信过去事件可预测 导致过度自信和低估风险
赌徒谬误 相信过去损失使未来胜利更可能 在亏损后增加仓位,在盈利后减少

2.5 趋势跟踪的情感挑战

趋势跟踪在心理上是残酷的,因为:

  1. 大多数交易亏损。 35-40%的胜率意味着输的次数比赢的多。这会磨损心理。
  2. 你让开放利润回吐。 跟踪出场意味着你在平仓前看着大利润缩水。这感觉像赔钱即使你是盈利的。
  3. 长期的平稳期。 在震荡、区间市场中,系统在没有任何大盈利来补偿的情况下消耗许多小亏损。这些时期可能持续数月。
  4. 入场信号感觉错误。 在20日高点或55日高点买入通常感觉像在最糟糕的时机买入——"太高了。"这与大多数人的直觉相反。
  5. 你必须机械地行动。 系统要求你压制判断并遵守规则,即使每个本能都说不要。

Dennis 自己说规则可以登在报纸上,没有人会遵守。这后来被证明在很大程度上是真的——即使在海龟中,由于不同程度的纪律而非不同规则,表现差异也是巨大的。


3. 完整海龟交易系统

海龟同时交易两个互补的突破系统。两者都是基于 Donchian Channel 突破的趋势跟踪系统(以通道突破交易先驱 Richard Donchian 命名)。

3.1 系统1 — 短期突破

概念: 使用20日突破捕获较短趋势,并带有过滤器避免在前一个盈利突破后立即交易。

参数 多头入场 空头入场
入场触发 价格超过过去20天的最高价 价格跌破过去20天的最低价
过滤器 如果前一个20日突破在这个市场中是赢家则跳过 如果前一个20日突破在这个市场中是赢家则跳过
出场 价格跌破过去10天的最低价 价格超过过去10天的最高价
突破周期 20天 20天
出场周期 10天 10天

过滤器规则(关键细节):

过滤器存在是因为突破系统在震荡市场中遭受假突破。在盈利突破后,下一个突破成为假信号(鞭打)的概率更高。所以系统1 跳过当前突破信号如果前一个突破本应是盈利的。

然而,有一个关键安全机制:如果被过滤的(跳过的)突破结果是一个真正的大行情,海龟将在55日突破上作为后备入场。这防止过滤器导致完全错过大趋势。

"前一个突破是赢家"的定义: 该市场中前一个20日突破如果被交易本应是盈利的——意味着价格在触发10日出场前按有利于交易的方向移动了至少2N。这个评估是理论性的(突破可能实际上没有被交易)。

3.2 系统2 — 长期突破

概念: 使用55日突破捕获较长趋势,无过滤器。

参数 多头入场 空头入场
入场触发 价格超过过去55天的最高价 价格跌破过去55天的最低价
过滤器 无——接受每个信号 无——接受每个信号
出场 价格跌破过去20天的最低价 价格超过过去20天的最高价
突破周期 55天 55天
出场周期 20天 20天

系统2更简单更稳健。因为55日突破更罕见,它们倾向于代表更强的趋势。没有过滤器意味着海龟在这个时间框架上永远不会错过大行情。

3.3 为什么两个系统?

两个系统是互补的:

3.4 突破定义(精确)

当当前价格超过(对于多头)或跌破(对于空头)通道边界时,发生突破。边界是从回看期间的收盘价计算的。信号在日内生成——你不等待在水平上方收盘。当价格触及或超过20日高点(系统1)或55日高点(系统2)的瞬间,订单被触发。

实际上,海龟在每个交易日开始时在突破水平放置止损订单,所以执行是自动的。


4. 仓位确定 — N系统(基于ATR)

仓位确定是海龟系统中最重要的组成部分。Curtis Faith 对此非常强调:入场和出场规则与交易多少相比几乎是次要的。海龟使用围绕一个称为 N 的概念的波动率基础仓位确定方法。

4.1 什么是N?

N 是市场日常波动的度量,等同于计算为20天指数移动平均线的平均真实范围(ATR)

单日的真实范围定义为:

真实范围 = 最大值 of:
  (a) 今天高点 - 今天低点
  (b) |今天高点 - 昨天收盘|
  (c) |今天低点 - 昨天收盘|

(b)和(c)中的绝对值捕获跳空。如果市场跳空高开然后在窄幅交易,真实范围反映跳空。

N 是真实范围的20天指数移动平均线:

N_today = (19 × N_yesterday + TR_today) / 20

这是平滑期为20的EMA。它适应变化的波动——当市场波动更大时N增加;当它安静下来时N减少。

4.2 美元波动

为了比较不同合约大小的市场间波动,海龟将N转换为美元条款

美元波动 = N × 每点美元

"每点美元"是期货合约移动一点的美元价值。例如:

市场 合约 每点美元 如果 N = 美元波动
原油 1,000桶 每$1移动$1,000 1.20 $1,200
黄金 100盎司 每$1移动$100 8.50 $850
标普500 每点$250 每1点移动$250 12.00 $3,000
大豆 5,000蒲式耳 每1美分移动$50 14.00 $700
长期国债 $100,000面值 每1点移动$1,000 0.70 $700
日元 12,500,000日元 每0.01移动$12.50 0.0032 $400

4.3 单位大小计算

海龟仓位确定的基本构建块是单位。一个单位代表仓位大小,其中价格移动1N等于账户的1%

单位大小 = 账户权益的1% / 美元波动

或等价地:

单位大小 = (账户权益 × 0.01) / (N × 每点美元)

工作示例:

账户权益:       $1,000,000
市场:           取暖油
每点美元:       每$1移动$42,000(每合约42,000加仑)
N:              0.0141($1 = 1美分移动)
美元波动:       0.0141 × $42,000 = $592.20

单位大小 = ($1,000,000 × 0.01) / $592.20
         = $10,000 / $592.20
         = 16.88

向下取整至每单位16份合约。

为什么这很重要: 通过以波动率定义仓位大小,海龟确保每个市场贡献大致相同的每单位美元风险。 取暖油移动1N的成本与黄金或大豆移动1N的成本相同——约账户权益的1%。这是使多元化工作的机制:没有单一市场可以主导投资组合。

4.4 为什么是每N 1%?

选择1%这个数字是为了:

4.5 仓位限制 — 相关性框架

为防止过度集中,海龟在严格的仓位限制下运作:

限制类型 最大单位 理由
单个市场 4个单位 防止任何单个市场的过度集中
密切相关的市场 总共6个单位 例如黄金+白银合计不能超过6个单位
松散相关的市场 总共10个单位 例如所有金属(黄金、白银、铜)不能超过10个单位
单一方向(所有多头或所有空头) 12个单位 防止过度方向偏差
总投资组合 24个单位 所有市场和方向的绝对最大值

海龟使用的相关性分组:

密切相关:

松散相关:

4.6 跨账户变动的单位大小

单位计算使用当前账户权益,这意味着:

4.7 工作示例 — 完整单位计算

场景: 账户权益为$2,000,000。我们同一天评估三个市场。

市场:黄金(COMEX)
  价格:               $450.00/盎司
  20日ATR(N):       $6.50
  合约大小:           100盎司
  每点美元:            每点$100(1点 = $1)
  美元波动:           $6.50 × $100 = $650
  账户的1%:          $20,000
  单位:               $20,000 / $650 = 30.77 → 30份合约

市场:原油(NYMEX)
  价格:               $58.00/桶
  20日ATR(N):       $1.30
  合约大小:           1,000桶
  每点美元:           每点$1,000(1点 = $1)
  美元波动:           $1.30 × $1,000 = $1,300
  账户的1%:          $20,000
  单位:               $20,000 / $1,300 = 15.38 → 15份合约

市场:日元(CME)
  价格:               0.8900($/100日元)
  20日ATR(N):       0.0074
  合约大小:           12,500,000日元
  每点美元:           每0.0001移动$12.50
  美元波动:           74跳动 × $12.50 = $925
  账户的1%:          $20,000
  单位:               $20,000 / $925 = 21.62 → 21份合约

注意单位大小差异很大(30黄金 vs 15原油 vs 21日元),但每N移动的美元风险被均等化为约$20,000(每个市场账户的1%)。


5. 入场规则(详细)

5.1 突破机制

当当前价格超过前N天(系统1为20,系统2为55)的最高价时触发多头入场。当当前价格跌破前N天的最低价时触发空头入场

实际上:

  1. 在市场开盘前,计算每个市场组合的20日高低。
  2. 在20日高点上方1个跳动放置买入止损(对于系统1多头)。
  3. 在20日低点下方1个跳动放置卖出止损(对于系统1空头)。
  4. 对于系统2同样在55日水平。
  5. 如果市场日内穿过该水平,订单自动成交。

5.2 系统1过滤器 — 完整细节

系统1的过滤器规则:如果该市场中前一个20日突破本应是盈利的,不要接受当前20日突破。

盈利定义为:突破将在10日出场触发前按有利方向移动至少2N。

实施逻辑:

对于每个市场,跟踪上一次20日突破信号(无论是否被交易):
  1. 记录突破价格。
  2. 突破后,跟踪最大有利偏移(MFE)。
  3. 跟踪10日出场何时触发。
  4. 如果MFE ≥ 2N在10日出场前 → 分类为赢家。
  5. 否则 → 分类为输家。

当前信号决策:
  如果 previous_breakout == 赢家 → 跳过当前系统1信号。
  如果 previous_breakout == 输家 → 接受当前系统1信号。

后备: 如果由于过滤器跳过了系统1信号,但价格继续趋势并最终触发55日突破(系统2入场),海龟将在该信号上入场。这防止过滤器导致完全错过大趋势。

5.3 金字塔 — 增加单位

一旦建立1个单位的初始仓位,海龟在价格朝有利方向移动时增加额外单位。加仓规则:

每按上次入场价格移动0.5N,增加1个单位。
每个市场最多:4个单位。

示例 — 多头黄金,N = $6.50:

单位 入场触发 价格 合约数 累计合约数
第一个单位 20日突破 $450.00 30 30
第二个单位 入场 + 0.5N $453.25 30 60
第三个单位 入场 + 1.0N $456.50 30 90
第四个单位 入场 + 1.5N $459.75 30 120

加仓水平基于前一单位的实际成交价格,而非理论价格。如果第二个单位以$453.50成交(滑点$0.25),第三个单位触发为$453.50 + $3.25 = $456.75。

5.4 为什么是0.5N增量?

选择0.5N间距是为了平衡两个目标:

  1. 足够激进以在强劲趋势中建立有意义仓位——在初始入场的1.5N内增加3个额外单位意味着快速建立满仓。
  2. 不会太激进以至于所有单位聚集——0.5N间距意味着加仓分散在约1.5天的正常价格变动中(因为1N ≈ 1天变动)。

5.5 入场时机

海龟在市场开盘前放置订单。所有入场订单都是止损单(多头买入止损,空头卖出止损)放置在突破水平。这确保了:


6. 止损规则

6.1 2N止损

每个海龟仓位都有从入场价格的2N处的硬止损。这是每个单位的最大损失。

多头止损  = 入场价格 - 2N
空头止损  = 入场价格 + 2N

由于1个单位调整为1N移动 = 账户的1%,2N止损意味着:

6.2 增加单位的止损放置

当添加额外单位时,所有现有单位的止损被抬高(对于多头)或降低(对于空头)以保持与最近入场的2N距离。

示例 — 多头黄金,N = $6.50:

事件 止损计算 止损价格
第一个单位在$450.00入场 $450.00 - $13.00 $437.00
第二个单位在$453.25入场 $453.25 - $13.00 $440.25(所有单位)
第三个单位在$456.50入场 $456.50 - $13.00 $443.50(所有单位)
第四个单位在$459.75入场 $459.75 - $13.00 $446.75(所有单位)

最大仓位风险(4个单位):

单位 入场 止损 每合约风险($) 每单位风险($)
1 $450.00 $446.75 $3.25 $9,750
2 $453.25 $446.75 $6.50 $19,500
3 $456.50 $446.75 $9.75 $29,250
4 $459.75 $446.75 $13.00 $39,000
合计 $97,500

在$2,000,000账户上,这是权益的4.875%——远低于理论最大值8%,因为早期单位已经朝有利方向移动。

6.3 鞭打问题

2N止损足够宽以在正常日波动中存活,但又足够紧以在真正逆转时被止损。然而,在震荡市场中,系统将产生鞭打——在突破上入场,被止损,然后看着市场恢复趋势。

海龟对鞭打的方法:

  1. 接受它们作为业务成本。 鞭打是捕获大趋势所支付的代价。
  2. 永远不要加宽止损以避免鞭打。2N止损是神圣不可侵犯的。
  3. 如果出现新突破信号则重新入场。 被止损不排除在下一个有效信号上重新入场。
  4. 系统1上的过滤器规则部分减轻了鞭打——通过在赢家后跳过信号(更可能跟随假突破)。

6.4 止损纪律

海龟有一个绝对规则:止损永远不要远离价格。它们只能收紧(向价格移动)当仓位添加单位时。这是不可协商的。将止损移宽是交易员能养成的最具破坏性的习惯,因为它将小、定义的损失转化为不可控制的、潜在灾难性的损失。


7. 出场规则

7.1 系统1出场 — 10日规则

多头: 当价格触及或跌破过去10天的最低价时退出。
空头: 当价格触及或超过过去10天的最高价时退出。

这是一个跟踪出场——10日低/高随价格移动。在强劲上升趋势中,10日低点稳步上升,保护利润。在停滞的趋势中,10日低点赶上当前价格,触发出场。

7.2 系统2出场 — 20日规则

多头: 当价格触及或跌破过去20天的最低价时退出。
空头: 当价格触及或超过过去20天的最高价时退出。

更长的出场周期允许系统2持有趋势更长时间,但也意味着它在出场前放弃更多开放利润。

7.3 出场机制

7.4 出场的心理困难

Faith 认为出场在心理上比入场难得多,因为:

  1. 回吐利润。 10日跟踪出场意味着到你出场时,价格已经从前高大幅回落。看着开放利润从$100,000缩水到$60,000然后出场触发是情感上毁灭性的,即使$60,000是一个出色的结果。

  2. 提前出场诱惑。 通过收紧出场来"锁定"利润的冲动是压倒性的。但收紧出场破坏系统优势——补偿许多小额亏损的大赢家之所以出现,是因为出场足够宽以持有通过正常回撤。

  3. 晚出场遗憾。 在大趋势结束且跟踪出场平仓后,市场经常略微反弹,使交易员感觉出场太晚。这是幻觉——出场价格是无法提前知道的。

Faith 注意到出场是海龟中最大的偏离来源。那些手动覆盖出场——过早拿利润或晚出场——的人始终不如那些机械遵守规则的人。


8. 交易的市场

8.1 原始海龟组合

海龟交易了五个板块的多元化流动性期货组合:

板块 市场
利率 美国长期国债(30年)、美国中期国债(10年)、欧洲美元(90天)
货币 英镑、德国马克、瑞士法郎、日元、加元、法郎
商品 — 谷物 玉米、大豆、豆粕、豆油、小麦
商品 — 金属 黄金、白银、铜、铂
商品 — 能源 原油、取暖油、无铅汽油
商品 — 软商品/肉类 咖啡、可可、糖、棉花、活牛、瘦猪

这给了他们约 20-25个市场的敞口。

8.2 为什么多元化必不可少

趋势跟踪依赖于捕获大趋势,这在任何单个市场中是罕见且不可预测的。多元化确保:

Faith 认为多元化是交易中唯一的免费午餐。你可以增加回报而不同比例增加风险,只需添加更多不相关的市场。

8.3 最低流动性要求

海龟只交易具有足够流动性的市场,定义为:

作为一个粗略指导,一个市场需要的成交量使得海龟的最大仓位代表少于1-2%的日成交量以避免滑点问题。


9. 风险管理 & 回撤

9.1 账户权益定义

海龟使用三种权益度量:

类型 定义 用于
核心权益 起始权益 +/- 所有已平仓交易损益 基本参考
总权益 核心权益 + 开放交易损益(逐市定价) 报告
降低权益 核心权益减去回撤-reduction因子 回撤期间的仓位确定

对于仓位确定,海龟在正常条件下使用核心权益。这防止开放利润过早膨胀仓位规模(波动的开放赢家可能暂时膨胀权益,导致仓位规模过大然后痛苦反转)。

9.2 回撤减少规则

当账户从权益峰值遭受回撤时,仓位规模减少:

每从权益峰值回撤10%,单位规模减少20%。
回撤 单位规模减少 有效单位大小
0% to -10% 无减少 正常的100%
-10% to -20% 20%减少 正常的80%
-20% to -30% 40%减少 正常的60%
-30% to -40% 60%减少 正常的40%
-40%+ 80%减少 正常的20%

实施:

回撤 = (峰值权益 - 当前权益) / 峰值权益
减少因子 = FLOOR(回撤 / 0.10) × 0.20
调整后单位 = 正常单位 × (1 - 减少因子)

示例: 账户峰值$2,000,000,现在$1,650,000。

9.3 为什么这个规则存在

回撤减少规则有两个关键功能:

  1. 生存。 50%回撤需要100%收益才能恢复。通过在回撤期间减少规模,系统确保账户能够生存即使是不利的时期。没有这个规则,趋势跟踪中的正常回撤(20-40%)可能成为终止性的。

  2. 反马丁格尔逻辑。 系统在赢时自然交易更大,输时交易更小。回撤规则在严重回撤期间放大了这种效果,作为额外安全网。

9.4 预期回撤统计

Faith 提供了关于适当实施的海龟风格系统预期:

统计 典型范围
最大历史回撤 30-50%
平均年度回撤 15-25%
最长回撤持续时间 6-18个月
从最大回撤恢复时间 12-36个月
10%+回撤频率 每年1-3次
20%+回撤频率 每2-3年一次

这些数字令人清醒。持续12个月的40%回撤是心理上痛苦的,即使它在统计上对系统来说是正常的。这就是为什么心态和纪律被如此强调——系统有效,但只有你能生存回撤而不偏离规则。

9.5 生存回撤的重要性

Faith 讲述说一些海龟失败不是因为系统停止工作,而是因为他们无法容忍回撤

教训是严峻的:回撤就是系统。 你不能要100%+的盈利年份而没有30-40%的回撤年份。它们是不可分割的。


10. 优势、期望 & 统计

10.1 数学定义优势

海龟优势表达为:

E = (PW × AW) - (PL × AL)

其中:

对于海龟系统:

组成部分 典型值
PW(胜率) 35-40%
PL(亏率) 60-65%
AW(平均盈利) 4-5R
AL(平均亏损) 0.5-1.0R
E = (0.38 × 4.5) - (0.62 × 0.8)
  = 1.71 - 0.50
  = +1.21R 每笔交易

10.2 为什么35%胜率高度盈利

关键洞察是赢家和输家之间的不对称

平均盈利 / 平均亏损 = 4.5R / 0.8R = 5.6:1 风险回报比

这意味着每个赢家大约值5.6个输家。即使输62%的时间,赢家也超过补偿。数学:

对于每100笔交易:
  38个赢家 × 4.5R  = 171.0R  gained
  62个输家  × 0.8R  =  49.6R  lost
  净:                = 121.4R  profit
  每笔交易:          =   1.21R

10.3 R倍数

R倍数将交易结果表达为初始风险的倍数。如果交易的初始风险是$2,000(2N止损距离):

交易结果 美元损益 R倍数
在2N止损 -$2,000 -1.0R
在1N止损(收紧止损) -$1,000 -0.5R
盈亏平衡出场 $0 0R
以2:1盈利出场 +$4,000 +2.0R
持有大趋势 +$20,000 +10.0R
超级交易 +$50,000 +25.0R

海龟系统的优势来自右尾——偶尔的+10R到+25R赢家,补偿了许多-0.5R到-1.0R输家。

10.4 蒙特卡罗分析

Faith 倡导使用蒙特卡罗模拟来理解可能结果的范围。通过从实际交易结果中随机重采样,你可以生成数千个假设权益曲线并评估:

对于海龟系统,蒙特卡罗分析通常显示:

10.5 大数定律在实践中的应用

Faith 强调统计优势只在大样本中显现。实际含义:


11. 系统设计原则

11.1 稳健性优于优化

Faith 深度批评曲线拟合——优化系统参数以拟合历史数据。海龟规则使用整数(20日、55日、2N)恰恰是因为它们不是优化的。系统有效不是因为20天是完美的回看期,而是因为趋势跟踪在广泛参数范围内有效。

稳健性测试: 如果系统在一系列广泛参数值中保持盈利,它是稳健的。如果将突破从20天改为18或22天导致结果显著变化,系统可能是曲线拟合。海龟系统在突破期约15到30天(系统1)和40到70天(系统2)范围内保持盈利。

11.2 为什么曲线拟合破坏系统

曲线拟合在回测中有效但在live交易中失败,因为:

  1. 未来与过去不同。 市场动态、波动率制度和相关性发生变化。
  2. 优化参数捕获噪音而非信号。 19天突破可能比20天回测更好,但差异是随机噪音,而非可利用的优势。
  3. 过度优化的系统脆弱。 它们只在回测时期的特定条件下有效。海龟系统刻意的简单性使其在变化的条件中具有弹性。

11.3 样本外测试

Faith 建议永远不要仅在用于开发的同一数据上评估系统。适当测试需要:

  1. 样本内期间 — 使用此数据开发规则。
  2. 样本外期间 — 在从未用于开发的 数据上测试最终规则。
  3. Walk-forward分析 — 在滚动的样本内窗口上重复优化并在后续样本外期间测试。

在样本内有效但在样本外失败的系统是曲线拟合。海龟系统开发于1980年代初期并持续数十年工作——终极样本外测试。

11.4 简单性的重要性

完整的海龟系统可以用几页描述。没有奇异指标,没有形态识别,没有基本面分析。这种简单性是刻意的且必不可少的:

11.5 多元化作为唯一的免费午餐

Faith 回声现代投资组合理论的原则:多元化是改善风险调整回报而不需要额外优势的唯一方式。海龟多元化于:


12. 行为 / 纪律规则

12.1 核心规则

  1. 交易每个信号。 不挑拣、不二思、不"感觉不对"。系统的优势依赖于捕获完整结果分布,包括无法提前预测的大赢家。
  2. 永远不覆盖系统。 如果系统说买,你就买。如果系统说持有,你就持有。如果系统说出场,你就出场。你的感受是噪音;系统是信号。
  3. 跨时间保持一致。 系统会有糟糕的月份甚至糟糕的季度。一致性意味着在建仓第18个月的回撤中与在盈利序列第1个月中以相同方式交易。
  4. 接受亏损作为业务成本。 每笔亏损是为捕获大趋势的期权支付的小额保费。没有这些保费,你就无法获得大趋势。
  5. 永远不要冒超过系统规定的风险。 仓位确定规则在那里确保生存。出于任何原因——即使"高信念"交易——超出它们违反了系统的统计基础。

12.2 为什么纪律是瓶颈

Dennis 著名的观察——"我可以在报纸上公布规则,没有人会遵守"——被证明是显著有先见之明的。规则最终被发布了。它们很简单。然而很少有人成功交易它们,因为:

12.3 最难的部分:连败

38%胜率的系统将以合理概率产生:

在这些序列期间,每个认知偏差都在向交易员尖叫停止、改变某些东西、放弃系统。表现最差的海龟是那些倾听这些冲动的人。


13. 常见错误

13.1 过度优化参数

将突破从20改为19天因为回测显示3%改善几乎肯定是在捕获噪音。参数敏感性分析的正确回应:如果系统在一系列广泛范围内有效,选择一个整数并放手。

13.2 在亏损后跳过信号

这是最具破坏性的错误。连续4-5笔亏损后,交易员决定"这个市场不起作用"或"我将等待条件改善"。接下来的信号通常是变成10R赢家的那个。通过跳过它,交易员摧毁了数学优势。

13.3 在错误时间减少规模

在亏损后减少仓位规模(超出回撤规则要求)意味着当盈利交易最终到来时,它们太小而无法恢复累积亏损。海龟回撤规则系统地处理规模减少——临时调整 делает больше вреда, чем пользы。

13.4 添加复杂性

在亏损期后,添加过滤器、指标或条件来"改进"系统的冲动是压倒性的。损害表现常见添加:

每个添加都减少样本量,增加复杂性,并为曲线拟合提供更多机会。

13.5 将亏损期与系统崩溃混淆

趋势跟踪系统在低波动、区间市场中有表现不佳的延长时期。这些时期不是系统崩溃的证据。它们在统计上是预期的。只有当市场基本性质发生变化(即市场停止趋势)时,系统才"崩溃"——在有记录的历史中从未发生过。

13.6 过早获利了结

在出场信号触发前拿利润是最常见的偏离之一。它感觉良好"锁定"赢家,但它系统地移除推动系统盈利的大额异常赢家的价值。一个交易员在+2R而不是让出场运行至+8R时拿利润,破坏了该交易75%的价值。


14. 完整交易生命周期示例

14.1 设置

系统:            系统2(55日突破)
市场:            原油(NYMEX)
账户权益:    $1,000,000
日期:              3月15日
N(20日ATR):    $1.50
合约大小:         1,000桶
每点美元:        每$1移动$1,000
55日高点:       $62.00
55日低点:        $53.00
当前价格:        $61.80

14.2 仓位确定

美元波动 = $1.50 × $1,000 = $1,500
账户的1%     = $1,000,000 × 0.01 = $10,000
单位大小      = $10,000 / $1,500 = 6.67 → 每单位6份合约

14.3 入场 — 单位1

3月17日: 原油突破$62.00,触发55日突破。

入场:  $62.10(轻微滑点成交)
大小:   6份合约(1个单位)
止损:   $62.10 - (2 × $1.50) = $59.10
风险:   ($62.10 - $59.10) × 6 × $1,000 = $18,000(账户的1.8%)

14.4 增加单位2

加仓触发是第一个入场上方$0.75:$62.10 + $0.75 = $62.85。

3月20日: 价格达到$62.85。

入场:  $62.90(成交)
大小:   6份额外合约(单位2)
止损:   $62.90 - $3.00 = $59.90(所有12份合约现在共用此止损)

更新风险概况:

单位 入场 止损 每合约风险 每单位风险
1 $62.10 $59.90 $2.20 $13,200
2 $62.90 $59.90 $3.00 $18,000
合计 $31,200(3.12%)

14.5 增加单位3

触发:$62.90 + $0.75 = $63.65。

3月24日: 价格达到$63.65。

入场:  $63.70(成交)
大小:   6份额外合约(单位3)
止损:   $63.70 - $3.00 = $60.70(所有18份合约)

更新风险:

单位 入场 止损 每合约风险 每单位风险
1 $62.10 $60.70 $1.40 $8,400
2 $62.90 $60.70 $2.20 $13,200
3 $63.70 $60.70 $3.00 $18,000
合计 $39,600(3.96%)

注意:单位1现在只从其入场风险$1.40——少于1N。跟踪止损正在保护早期利润。

14.6 增加单位4(最大)

触发:$63.70 + $0.75 = $64.45。

3月28日: 价格达到$64.45。

入场:  $64.50(成交)
大小:   6份额外合约(单位4 — 最大)
止损:   $64.50 - $3.00 = $61.50(所有24份合约)

更新风险:

单位 入场 止损 每合约风险 每单位风险
1 $62.10 $61.50 $0.60 $3,600
2 $62.90 $61.50 $1.40 $8,400
3 $63.70 $61.50 $2.20 $13,200
4 $64.50 $61.50 $3.00 $18,000
合计 $43,200(4.32%)

仓位现在达到最大规模:24份合约跨4个单位。

14.7 持有趋势

接下来几周,原油继续走高:

4月10日: 价格 $68.00  |  20日低点 = $63.50  |  止损:$61.50
4月20日: 价格 $71.00  |  20日低点 = $65.00  |  止损:$61.50
5月1日:  价格 $74.50  |  20日低点 = $68.50  |  止损:$61.50
5月10日: 价格 $73.00  |  20日低点 = $69.00  |  止损:$61.50

注意:2N止损($61.50)没有进一步收紧,因为对于系统2,出场由20日低点规则管辖。止损此时仅作为紧急后备——20日出场会先触发。

14.8 出场

5月15日: 原油回撤。20日低点为$69.00。价格触及$69.00。

出场价格:$69.00
所有24份合约同时退出。

14.9 交易损益摘要

单位 入场 出场 每合约利润 合约数 利润
1 $62.10 $69.00 $6.90 6 $41,400
2 $62.90 $69.00 $6.10 6 $36,600
3 $63.70 $69.00 $5.30 6 $31,800
4 $64.50 $69.00 $4.50 6 $27,000
合计 24 $136,800
盈利占账户百分比:  13.68%
R倍数(单位1):     $41,400 / $18,000 初始风险 = 2.30R
R倍数(总计):      $136,800 / $43,200 最大风险 = 3.17R

这是一个中等赢家——不是那种让海龟赚大钱的大赢家类型,但是一个展示系统正常工作的稳健盈利交易。真正的大额海龟利润来自原油(或其他市场)趋势数月,产生+10R到+25R结果。


15. 实施伪代码

15.1 每日系统循环

FUNCTION RunDailyTurtleSystem():
    today = GetCurrentDate()
    equity = GetCoreEquity()
    peak_equity = GetPeakEquity()
    drawdown = CalculateDrawdown(equity, peak_equity)
    drawdown_factor = 1.0 - (FLOOR(drawdown / 0.10) * 0.20)
    drawdown_factor = MAX(drawdown_factor, 0.20)  // minimum 20% of normal

    FOR each market IN portfolio:
        UpdatePriceData(market, today)
        N = CalculateN(market)           // 20-day EMA of True Range
        UpdateChannels(market)            // 20-day and 55-day high/low

        // Check exits first (before entries)
        IF HasOpenPosition(market):
            CheckExitSignals(market, N)
            CheckStopLoss(market)
        ELSE:
            CheckEntrySignals(market, N, equity, drawdown_factor)
        ENDIF

        // Check for pyramiding (adding Units to existing positions)
        IF HasOpenPosition(market) AND Units(market) < 4:
            CheckPyramidSignals(market, N, equity, drawdown_factor)
        ENDIF
    ENDFOR

    EnforcePorfolioLimits()   // Check all position limits
    LogDailyPortfolioState()
END FUNCTION

15.2 N计算

FUNCTION CalculateN(market):
    // True Range for today
    high  = market.today.high
    low   = market.today.low
    close_prev = market.yesterday.close

    TR = MAX(
        high - low,
        ABS(high - close_prev),
        ABS(low - close_prev)
    )

    // 20-day EMA
    IF market.N_previous IS NULL:
        // Initialize with simple average of first 20 TRs
        market.N = SimpleAverage(market.TR_history, 20)
    ELSE:
        market.N = (19 * market.N_previous + TR) / 20
    ENDIF

    RETURN market.N
END FUNCTION

15.3 单位大小计算

FUNCTION CalculateUnitSize(market, equity, drawdown_factor):
    dollar_vol = market.N * market.dollars_per_point
    risk_amount = equity * 0.01 * drawdown_factor
    unit_contracts = FLOOR(risk_amount / dollar_vol)

    // Enforce minimum of 1 contract
    unit_contracts = MAX(unit_contracts, 1)

    RETURN unit_contracts
END FUNCTION

15.4 入场信号检测

FUNCTION CheckEntrySignals(market, N, equity, drawdown_factor):
    price = market.current_price

    // --- System 2 (55-day breakout, no filter) ---
    IF price > market.high_55day:
        IF CanAddPosition(market, "long"):
            unit = CalculateUnitSize(market, equity, drawdown_factor)
            EnterLong(market, unit, N, system=2)
        ENDIF
    ELSIF price < market.low_55day:
        IF CanAddPosition(market, "short"):
            unit = CalculateUnitSize(market, equity, drawdown_factor)
            EnterShort(market, unit, N, system=2)
        ENDIF
    ENDIF

    // --- System 1 (20-day breakout, with filter) ---
    IF price > market.high_20day:
        IF NOT FilterBlocksEntry(market, "long"):
            IF CanAddPosition(market, "long"):
                unit = CalculateUnitSize(market, equity, drawdown_factor)
                EnterLong(market, unit, N, system=1)
            ENDIF
        ELSE:
            // Signal filtered — log for failsafe monitoring
            market.filtered_long = TRUE
        ENDIF
    ELSIF price < market.low_20day:
        IF NOT FilterBlocksEntry(market, "short"):
            IF CanAddPosition(market, "short"):
                unit = CalculateUnitSize(market, equity, drawdown_factor)
                EnterShort(market, unit, N, system=1)
            ENDIF
        ELSE:
            market.filtered_short = TRUE
        ENDIF
    ENDIF
END FUNCTION

15.5 系统1过滤器逻辑

FUNCTION FilterBlocksEntry(market, direction):
    // Look up the last 20-day breakout in this market for this direction
    last_breakout = GetLastBreakout(market, direction, period=20)

    IF last_breakout IS NULL:
        RETURN FALSE    // No previous breakout — take the signal
    ENDIF

    // Was the previous breakout a theoretical winner?
    // A winner is defined as price moving 2N in favor before the 10-day exit
    IF last_breakout.max_favorable_excursion >= 2 * last_breakout.N:
        RETURN TRUE     // Previous was a winner — SKIP this signal
    ELSE:
        RETURN FALSE    // Previous was a loser — TAKE this signal
    ENDIF
END FUNCTION

15.6 金字塔逻辑

FUNCTION CheckPyramidSignals(market, N, equity, drawdown_factor):
    position = GetPosition(market)
    last_entry = position.last_entry_price
    units = position.unit_count
    add_threshold = 0.5 * N

    IF position.direction == "long":
        trigger = last_entry + add_threshold
        IF market.current_price >= trigger AND units < 4:
            IF CanAddPosition(market, "long"):
                new_unit = CalculateUnitSize(market, equity, drawdown_factor)
                AddUnit(market, new_unit, market.current_price)
                UpdateStops(market, N)  // Tighten stops for all units
            ENDIF
        ENDIF

    ELSIF position.direction == "short":
        trigger = last_entry - add_threshold
        IF market.current_price <= trigger AND units < 4:
            IF CanAddPosition(market, "short"):
                new_unit = CalculateUnitSize(market, equity, drawdown_factor)
                AddUnit(market, new_unit, market.current_price)
                UpdateStops(market, N)
            ENDIF
        ENDIF
    ENDIF
END FUNCTION

15.7 止损和出场管理

FUNCTION CheckExitSignals(market, N):
    position = GetPosition(market)
    price = market.current_price

    IF position.system == 1:
        exit_period = 10
    ELSIF position.system == 2:
        exit_period = 20
    ENDIF

    IF position.direction == "long":
        exit_level = market.GetLowestLow(exit_period)
        IF price <= exit_level:
            ClosePosition(market, reason="channel_exit")
        ENDIF

    ELSIF position.direction == "short":
        exit_level = market.GetHighestHigh(exit_period)
        IF price >= exit_level:
            ClosePosition(market, reason="channel_exit")
        ENDIF
    ENDIF
END FUNCTION

FUNCTION CheckStopLoss(market):
    position = GetPosition(market)
    price = market.current_price

    IF position.direction == "long" AND price <= position.stop_price:
        ClosePosition(market, reason="stop_loss")
    ELSIF position.direction == "short" AND price >= position.stop_price:
        ClosePosition(market, reason="stop_loss")
    ENDIF
END FUNCTION

FUNCTION UpdateStops(market, N):
    position = GetPosition(market)
    new_stop = NULL

    IF position.direction == "long":
        new_stop = position.last_entry_price - (2 * N)
        // Only tighten — never widen
        IF new_stop > position.stop_price:
            position.stop_price = new_stop
        ENDIF

    ELSIF position.direction == "short":
        new_stop = position.last_entry_price + (2 * N)
        IF new_stop < position.stop_price:
            position.stop_price = new_stop
        ENDIF
    ENDIF
END FUNCTION

15.8 投资组合风险管理覆盖

FUNCTION CanAddPosition(market, direction):
    current_units = GetTotalUnits(market)
    IF current_units >= 4:
        RETURN FALSE  // Max 4 units per market
    ENDIF

    // Check closely correlated group
    group = GetCloselyCorrelatedGroup(market)
    group_units = SumUnits(group)
    IF group_units >= 6:
        RETURN FALSE  // Max 6 units in closely correlated markets
    ENDIF

    // Check loosely correlated group
    sector = GetLooselyCorrelatedGroup(market)
    sector_units = SumUnits(sector)
    IF sector_units >= 10:
        RETURN FALSE  // Max 10 units in loosely correlated markets
    ENDIF

    // Check single direction limit
    direction_units = GetDirectionUnits(direction)
    IF direction_units >= 12:
        RETURN FALSE  // Max 12 units in one direction
    ENDIF

    // Check total portfolio
    total_units = GetTotalPortfolioUnits()
    IF total_units >= 24:
        RETURN FALSE  // Max 24 units total
    ENDIF

    RETURN TRUE
END FUNCTION

FUNCTION EnforcePorfolioLimits():
    // After all entry/exit processing, verify limits are not exceeded
    // This is a safety check — the CanAddPosition function should
    // prevent violations, but limits should be verified daily

    ASSERT GetTotalPortfolioUnits() <= 24
    ASSERT GetDirectionUnits("long") <= 12
    ASSERT GetDirectionUnits("short") <= 12

    FOR each market IN portfolio:
        ASSERT GetTotalUnits(market) <= 4
    ENDFOR

    FOR each group IN closely_correlated_groups:
        ASSERT SumUnits(group) <= 6
    ENDFOR

    FOR each sector IN loosely_correlated_groups:
        ASSERT SumUnits(sector) <= 10
    ENDFOR
END FUNCTION

15.9 回撤计算

FUNCTION CalculateDrawdown(current_equity, peak_equity):
    IF current_equity >= peak_equity:
        UpdatePeakEquity(current_equity)
        RETURN 0.0
    ENDIF

    drawdown = (peak_equity - current_equity) / peak_equity
    RETURN drawdown
END FUNCTION

FUNCTION GetEffectiveEquityMultiplier(drawdown):
    // For every 10% drawdown, reduce by 20%
    reduction_steps = FLOOR(drawdown / 0.10)
    multiplier = 1.0 - (reduction_steps * 0.20)
    multiplier = MAX(multiplier, 0.20)  // Floor at 20%
    RETURN multiplier
END FUNCTION

16. 比较:系统1 vs 系统2

特征 系统1 系统2
突破周期 20天 55天
出场周期 10天 20天
过滤器 是 — 盈利后跳过 否 — 接受每个信号
55日后备 是 — 如果系统1被过滤则55日入场 不适用
信号频率 较高(每年更多交易) 较低(每年更少交易)
胜率 较低(约32-38%) 较高(约38-42%)
平均盈利大小 较小(持仓期较短) 较大(持仓期较长)
平均亏损大小 较小(出场更紧) 较大(出场更宽)
持仓期 数天到数周 数周到数月
鞭打频率 较高(突破期短,更多假信号) 较低(突破期长,更多显著变动)
震荡市场表现 差——许多假突破 较好——产生更少信号
趋势市场表现 好——早期捕获趋势 好——捕获大趋势的更大一部分
心理难度 较高(亏损更频繁) 较低(交易更少,噪音更少)
最适合 频繁短期趋势的市场 产生持续数周/月趋势的市场
资本要求 较低每市场(止损更紧) 较高每市场(止损更宽)
减少更少开放利润 是——出场更快(10日) 否——出场更慢(20日)
放弃更多开放利润 是——更宽的跟踪出场
每笔交易期望 略低 略高
年度回报贡献 更多交易 × 更小平均盈利 更少交易 × 更大平均盈利

组合优势: 同时运行两个系统提供跨时间框架的多元化。当系统1在震荡市场中鞭打时,它产生小亏损但系统2可能根本不触发(避免相同亏损)。当大趋势发展时,系统2捕获大变动,而系统1可能已被过滤或提前出场。


17. 关键语录

"交易成功的秘诀从来不是找到一个'秘密'系统。而是学会好好交易一个好的系统。"

"我可以在报纸上公布我的交易规则,没有人会遵守。关键是的一致性和纪律。" — Richard Dennis

"好的交易不是关于正确,而是关于交易正确。如果你想成功,你需要把交易当作一个统计游戏。"

"与优势交易,管理风险,保持一致,保持简单。这就是海龟方式的全部秘诀。"

"表现最好的海龟是最一致遵守规则的人。表现最差的海龟是最试图聪明的人。"

"亏损期不意味着系统坏了;意味着市场条件暂时不利。当条件变化时系统会恢复——但只有你仍在交易它。"

"大多数交易员宁愿感觉良好而不是赚钱。他们想在每笔交易中都正确。海龟学会接受在单笔交易中错误以换取长期正确。"

"我在1984年交易的市场与今天可用的市场并无太大不同。趋势跟踪原则是永恒的,因为它们基于人性,而人性不变。"

"出场比入场重要得多。你可以随机入场并用好的出场策略赚钱。你不能用好的入场和坏的出场赚钱。"

"仓位确定是任何交易系统中最重要的部分。它决定投资组合的风险和长期回报复利。然而大多数交易员在入场上花90%时间,在仓位确定上花0%时间。"

"遵守系统的情感困难是其有效的主要原因。如果它很容易,每个人都会做,优势就会消失。"

"不要担心单笔交易。担心你是否遵守规则。结果会随时间照顾自己。"

"我所知最好的交易员是最简单的。他们有几个简单的规则,他们遵守它们,然后赚大钱。我所知最差的交易员是最复杂的——总是寻找完美的指标、完美的时机、完美的入场。"


实施规范结束。