Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • shell

  • tool

  • 网络

  • compute_base

  • blog

  • growth

  • java

  • C&C++

  • ai

  • secure

  • cms

  • english

  • 生活

  • 金融学

    • 交易概念基础
    • 打造投资系统
    • 给企业估值
    • 读《走向幻觉, 走向成熟》
    • 创新药产业知识指南
    • 海龟交易法
      • 1. 海龟交易法则简介
        • 1.1 历史背景
        • 1.2 核心理念
        • 1.3 CTA策略分类
      • 2. 核心概念
        • 2.1 真实波动幅度(TR)与 ATR
        • 2.2 头寸单位(Unit)
        • 2.3 上轨与下轨
      • 3. 交易规则详解
        • 3.1 入市规则
        • 系统1(短期系统)
        • 系统2(长期系统)
        • 3.2 加仓规则
        • 3.3 止损规则
        • 3.4 止盈/退出规则
      • 4. 完整交易流程图
      • 5. Python代码实现
        • 5.1 核心指标计算
        • 5.2 回测框架
      • 6. 注意事项与私货
        • 6.1 适用场景
        • 6.2 A股应用调整
        • 6.3 作者评价(来自知乎文章)
      • 7. 参考资料
    • 产业链整理
  • more

  • other
  • 金融学
Jacky
2026-01-05
目录

海龟交易法

# 1. 海龟交易法则简介

# 1.1 历史背景

海龟交易法则起源于1983年,由著名商品投机家理查德·丹尼斯(Richard Dennis) 和 威廉·艾克哈特(William Eckhardt) 共同创立。

两人曾就"交易能力是天生的还是可以培养的"展开辩论,最终决定通过实验来验证。他们招募了一批没有交易经验的普通人,称之为"海龟",并传授给他们一套完整的交易系统。

实验结果证明,这套系统在短短几年内创造了惊人的收益,许多"海龟"成为了成功的交易员。

# 1.2 核心理念

  • 趋势跟踪:顺势而为,不预测市场方向
  • 严格纪律:机械化执行交易规则
  • 风险控制:通过头寸管理控制每笔交易的风险
  • 一致性:所有交易决策基于相同的规则

# 1.3 CTA策略分类

海龟交易法是典型的 CTA(Commodity Trading Advisor,商品交易顾问)策略,属于趋势跟踪类型。

CTA策略类型 特点 代表策略
趋势跟踪 顺势而为,捕捉中长期趋势 海龟交易法、双均线策略
均值回归 逆势操作,价格偏离后回归 布林带策略、配对交易
套利策略 利用价差获利,风险较低 跨期套利、跨品种套利
高频策略 短线交易,依赖速度优势 做市策略、统计套利

💡 CTA的核心优势:与股票市场的低相关性,在股市下跌时往往能提供正收益,是资产配置中重要的对冲工具。

# 2. 核心概念

# 2.1 真实波动幅度(TR)与 ATR

真实波动幅度(True Range, TR) 是衡量市场波动性的关键指标,取以下三个值的最大值:

计算方式 公式
当日振幅 最高价 - 最低价
跳空高开 最高价 - 前收盘价
跳空低开 最低价 - 前收盘价

真实波动幅度均值(Average True Range, ATR) 是过去N日TR的移动平均值:

其中:

  • = 周期天数(通常为20天)
  • = 前一日的ATR值
  • = 当日的真实波动幅度

💡 ATR的意义:ATR反映了市场的波动性,波动越大ATR越高。海龟用它来标准化不同品种的风险。

# 2.2 头寸单位(Unit)

海龟将资金分成若干"头寸单位",核心原则是:价格波动1个ATR,总仓位资金变化1%。

头寸计算公式(股票):

头寸单位总资金

其中: 为当前价格, 为真实波动幅度均值。

头寸计算公式(期货):

头寸单位总资金保证金比例

计算示例(股票):

假设:总资金10万元,平安银行价格16.20元,ATR=0.464元

头寸单位元

即每次交易约34914元。

# 2.3 上轨与下轨

在海龟交易系统中,上轨和下轨是价格通道的边界:

术语 含义 系统1 系统2
入场上轨 突破买入信号线 20日最高价 55日最高价
入场下轨 跌破做空信号线 20日最低价 55日最低价
出场上轨 空头平仓信号线 10日最高价 20日最高价
出场下轨 多头平仓信号线 10日最低价 20日最低价

示意图:

价格 ↑
      ──────── 55日最高价(系统2入场上轨)
      ──────── 20日最高价(系统1入场上轨 / 系统2出场上轨)
      ──────── 10日最高价(系统1出场上轨)
      
      ~~~~ 价格波动区间
      
      ──────── 10日最低价(系统1出场下轨)
      ──────── 20日最低价(系统1入场下轨 / 系统2出场下轨)
      ──────── 55日最低价(系统2入场下轨)
价格 ↓
1
2
3
4
5
6
7
8
9
10
11

# 3. 交易规则详解

# 3.1 入市规则

海龟使用两套入市系统:

# 系统1(短期系统)

  • 入市信号:价格突破过去20日的最高价(做多)或最低价(做空)
  • 过滤规则:若上次突破为盈利性突破,则忽略本次信号
    • 盈利性突破:上次入场后,价格未触及止损就再次突破
    • 亏损性突破:上次入场后,触发了止损
  • 执行:信号出现立即行动,不等收盘

# 系统2(长期系统)

  • 入市信号:价格突破过去55日的最高价(做多)或最低价(做空)
  • 无过滤:所有突破信号都执行
  • 执行:信号出现立即行动

# 3.2 加仓规则

入市后可逐步建仓:

  1. 初始建仓:入市时买入 1个头寸单位
  2. 加仓条件:价格每向盈利方向移动 0.5个ATR,加仓1个头寸单位
  3. 上限:单一品种最多持有 4个头寸单位

加仓示例(做多):

加仓次数 触发条件 累计头寸
第1次(入场) 突破20日高点 1单位
第2次 入场价 + 0.5ATR 2单位
第3次 入场价 + 1.0ATR 3单位
第4次 入场价 + 1.5ATR 4单位(满仓)

# 3.3 止损规则

严格的止损是海龟系统的核心:

  • 止损原则:单笔交易导致总资金亏损不超过 2%
  • 止损距离:入场价格 ± 2个ATR(做多减,做空加)
  • 动态调整:每次加仓后,止损位调整为最新加仓价 ± 2ATR

止损示例:

  • 入场价格:100元
  • ATR:2元
  • 止损价格:100 - 2×2 = 96元

⚠️ 重要:一旦触发止损,所有头寸全部退出!

# 3.4 止盈/退出规则

系统 多头退出 空头退出
系统1 价格跌破10日最低价 价格突破10日最高价
系统2 价格跌破20日最低价 价格突破20日最高价

# 4. 完整交易流程图

开始
  │
  ▼
计算ATR和头寸单位
  │
  ▼
监控价格 ─────────────────┐
  │                      │
  ▼                      │
是否突破入场上/下轨?      │
  │                      │
  ├─ 否 ─────────────────┘
  │
  ▼ 是
检查过滤条件(系统1)
  │
  ▼
买入1个头寸单位
  │
  ▼
设置止损(入场价±2ATR)
  │
  ▼
持仓监控 ◄────────────────┐
  │                      │
  ├─ 触发止损?           │
  │   └─ 是 → 全部平仓 → 结束
  │                      │
  ├─ 触发止盈?           │
  │   └─ 是 → 全部平仓 → 结束
  │                      │
  ├─ 价格上涨0.5ATR且未满仓?
  │   └─ 是 → 加仓1单位 → 更新止损 ─┘
  │
  └─ 否 ─────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 5. Python代码实现

# 5.1 核心指标计算

import pandas as pd
import numpy as np

class TurtleTrader:
    """海龟交易系统"""
    
    def __init__(self, capital=100000, risk_percent=0.01, atr_period=20):
        self.capital = capital          # 总资金
        self.risk_percent = risk_percent  # 单次风险比例(1%)
        self.atr_period = atr_period    # ATR周期
        
        # 系统参数
        self.entry_period_s1 = 20       # 系统1入场周期
        self.exit_period_s1 = 10        # 系统1出场周期
        self.entry_period_s2 = 55       # 系统2入场周期
        self.exit_period_s2 = 20        # 系统2出场周期
        
        # 交易状态
        self.position = 0               # 当前持仓单位数
        self.entry_price = 0            # 入场价格
        self.stop_loss = 0              # 止损价格
        self.max_units = 4              # 最大头寸单位
    
    def calculate_tr(self, high, low, prev_close):
        """计算真实波动幅度 TR"""
        tr1 = high - low
        tr2 = abs(high - prev_close)
        tr3 = abs(low - prev_close)
        return max(tr1, tr2, tr3)
    
    def calculate_atr(self, df):
        """计算ATR指标"""
        df = df.copy()
        df['prev_close'] = df['close'].shift(1)
        df['tr'] = df.apply(
            lambda x: self.calculate_tr(x['high'], x['low'], x['prev_close']), 
            axis=1
        )
        df['atr'] = df['tr'].rolling(window=self.atr_period).mean()
        return df
    
    def calculate_channels(self, df):
        """计算唐奇安通道(上下轨)"""
        df = df.copy()
        
        # 系统1通道
        df['entry_up_s1'] = df['high'].rolling(self.entry_period_s1).max()
        df['entry_down_s1'] = df['low'].rolling(self.entry_period_s1).min()
        df['exit_up_s1'] = df['high'].rolling(self.exit_period_s1).max()
        df['exit_down_s1'] = df['low'].rolling(self.exit_period_s1).min()
        
        # 系统2通道
        df['entry_up_s2'] = df['high'].rolling(self.entry_period_s2).max()
        df['entry_down_s2'] = df['low'].rolling(self.entry_period_s2).min()
        df['exit_up_s2'] = df['high'].rolling(self.exit_period_s2).max()
        df['exit_down_s2'] = df['low'].rolling(self.exit_period_s2).min()
        
        return df
    
    def calculate_unit_size(self, price, atr):
        """计算头寸单位(金额)"""
        if atr == 0:
            return 0
        unit = (self.capital * self.risk_percent * price) / atr
        return unit
    
    def generate_signals(self, df, system=1):
        """生成交易信号"""
        df = self.calculate_atr(df)
        df = self.calculate_channels(df)
        
        if system == 1:
            entry_up = 'entry_up_s1'
            entry_down = 'entry_down_s1'
            exit_up = 'exit_up_s1'
            exit_down = 'exit_down_s1'
        else:
            entry_up = 'entry_up_s2'
            entry_down = 'entry_down_s2'
            exit_up = 'exit_up_s2'
            exit_down = 'exit_down_s2'
        
        df['signal'] = 0
        
        # 做多信号:突破入场上轨
        df.loc[df['close'] > df[entry_up].shift(1), 'signal'] = 1
        
        # 做空信号:跌破入场下轨
        df.loc[df['close'] < df[entry_down].shift(1), 'signal'] = -1
        
        # 多头出场:跌破出场下轨
        df.loc[df['close'] < df[exit_down].shift(1), 'exit_long'] = True
        
        # 空头出场:突破出场上轨
        df.loc[df['close'] > df[exit_up].shift(1), 'exit_short'] = True
        
        return df
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

# 5.2 回测框架

def backtest_turtle(df, trader, system=1):
    """海龟策略回测"""
    df = trader.generate_signals(df, system)
    
    position = 0
    entry_price = 0
    stop_loss = 0
    units = 0
    trades = []
    equity = [trader.capital]
    
    for i in range(1, len(df)):
        row = df.iloc[i]
        prev_row = df.iloc[i-1]
        current_equity = equity[-1]
        
        # 计算当前头寸单位大小
        unit_size = trader.calculate_unit_size(row['close'], row['atr'])
        
        if position == 0:  # 无持仓
            if row['signal'] == 1:  # 做多信号
                position = 1
                entry_price = row['close']
                stop_loss = entry_price - 2 * row['atr']
                units = 1
                trades.append({
                    'date': row.name,
                    'action': 'BUY',
                    'price': entry_price,
                    'units': units
                })
        
        elif position == 1:  # 持有多头
            # 检查止损
            if row['low'] <= stop_loss:
                pnl = (stop_loss - entry_price) * unit_size / row['close'] * units
                current_equity += pnl
                trades.append({
                    'date': row.name,
                    'action': 'STOP_LOSS',
                    'price': stop_loss,
                    'pnl': pnl
                })
                position = 0
                units = 0
            
            # 检查止盈出场
            elif row.get('exit_long', False):
                pnl = (row['close'] - entry_price) * unit_size / row['close'] * units
                current_equity += pnl
                trades.append({
                    'date': row.name,
                    'action': 'EXIT',
                    'price': row['close'],
                    'pnl': pnl
                })
                position = 0
                units = 0
            
            # 检查加仓条件
            elif units < trader.max_units:
                add_price = entry_price + units * 0.5 * row['atr']
                if row['high'] >= add_price:
                    units += 1
                    stop_loss = add_price - 2 * row['atr']
                    trades.append({
                        'date': row.name,
                        'action': 'ADD',
                        'price': add_price,
                        'units': units
                    })
        
        equity.append(current_equity)
    
    return pd.DataFrame(trades), equity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

# 6. 注意事项与私货

# 6.1 适用场景

适用 不适用
期货市场(原设计场景) 波动极小的品种
趋势明显的市场 震荡盘整行情
流动性好的品种 流动性差的小盘股

# 6.2 A股应用调整

  1. 头寸计算调整:A股无杠杆,头寸单位可能超过总仓位,需设置上限
  2. 最小交易单位:A股需100股整手交易,计算后需取整
  3. T+1限制:当日买入次日才能卖出,无法及时止损
  4. 涨跌停限制:可能导致无法按预期价格成交

# 6.3 作者评价(来自知乎文章)

  • 当标的波动较小时,单位头寸会超过总仓位
  • 头寸计算公式有点复杂,很多人简化为将资金等分为5-6份
  • 稳定盈利的交易系统需要和交易者自身的财务状况、性格等匹配
  • 与总结系统相比,可能更重要的是系统的执行,有术无道,无根之木,活不了

# 7. 参考资料

  1. 《海龟交易法则》- 柯蒂斯·费思 (opens new window)
  2. 知乎 - 一文看懂海龟交易法则 (opens new window)
  3. 海龟策略要素代码解析 (opens new window)
#finance#investment#trading#quantitative#cta
上次更新: 2026/01/05, 21:58:44
创新药产业知识指南
产业链整理

← 创新药产业知识指南 产业链整理→

最近更新
01
产业链整理
01-27
02
mermaid 入门指南
01-22
03
whimsical 入门指南
01-21
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式