3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
海龟交易策略(Turtle Trading System)是量化交易领域的经典之作,其核心思想基于**唐奇安通道(Donchian Channel)的突破系统,并结合真实波幅均值(ATR)**进行动态仓位管理和加仓减仓。其主要规则如下:
以下代码展示了如何在聚宽平台实现一个支持**多品种组合(如 300ETF、500ETF、创业板ETF)并支持动态复权(真实价格)**的海龟突破策略:
import numpy as np
import pandas as pd
from jqdata import *
def initialize(context):
# 1. 策略基本设置
set_benchmark('000300.XSHG')
set_option('use_real_price', True) # 开启真实价格模式,避免未来函数
# 2. 设定交易费率
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 3. 策略参数定义
g.donchian_high_window = 20 # 唐奇安通道上轨周期
g.donchian_low_window = 10 # 唐奇安通道下轨周期
g.atr_window = 20 # ATR周期
g.max_units = 4 # 最大加仓次数
# 4. 扩展为多品种组合(例如:沪深300ETF、中证500ETF、创业板ETF)
g.security_list = ['510300.XSHG', '510500.XSHG', '159915.XSHE']
# 5. 记录每个品种的交易状态
g.turtle_status = {}
for security in g.security_list:
g.turtle_status[security] = {
'units': 0, # 当前持仓Unit数
'last_buy_price': 0 # 上一次买入价格
}
# 每日开盘运行
run_daily(market_open, time='every_bar')
def get_atr_and_donchian(security, context):
# 获取历史数据(包含当前Bar的前N个Bar)
hist = attribute_history(security, g.donchian_high_window + 1, '1d', ['high', 'low', 'close'])
if len(hist) < g.donchian_high_window:
return None, None, None
# 计算唐奇安通道上下轨(不含当前Bar)
high_limit = hist['high'][:-1].max()
low_limit = hist['low'][:-1].max() # 止盈参考下轨
if g.donchian_low_window < g.donchian_high_window:
low_limit = hist['low'][-g.donchian_low_window-1:-1].min()
# 计算ATR (N值)
close_prev = hist['close'][:-1].values
high = hist['high'][-g.atr_window-1:-1].values
low = hist['low'][-g.atr_window-1:-1].values
tr_list = []
for i in range(len(high)):
if i == 0:
tr = high[i] - low[i]
else:
tr = max(high[i] - low[i], abs(high[i] - close_prev[i-1]), abs(low[i] - close_prev[i-1]))
tr_list.append(tr)
atr = np.mean(tr_list)
return atr, high_limit, low_limit
def market_open(context):
total_value = context.portfolio.total_value
for security in g.security_list:
status = g.turtle_status[security]
current_data = get_current_data()
if current_data[security].paused:
continue
current_price = current_data[security].last_price
atr, high_limit, low_limit = get_atr_and_donchian(security, context)
if atr is None or atr == 0:
continue
# 计算单个Unit的股数(假设资金分配到每个品种的权重相等)
target_value_per_unit = (total_value / len(g.security_list)) * 0.01
unit_size = int(target_value_per_unit / atr)
unit_size = (unit_size // 100) * 100 # A股100股整数倍限制
if unit_size == 0:
continue
# 1. 止损与止盈判断
if status['units'] > 0:
# 止损:价格低于上一次买入价 - 2 * ATR
# 止盈:价格跌破唐奇安通道下轨
if current_price < (status['last_buy_price'] - 2 * atr) or current_price < low_limit:
order_target(security, 0)
log.info(f"[止损/止盈] 卖出 {security},清空仓位")
status['units'] = 0
status['last_buy_price'] = 0
continue
# 2. 突破买入/加仓逻辑
if status['units'] == 0:
# 突破上轨首笔建仓
if current_price > high_limit:
order(security, unit_size)
log.info(f"[建仓] 突破上轨,买入 {security} {unit_size}股")
status['units'] = 1
status['last_buy_price'] = current_price
elif status['units'] < g.max_units:
# 价格每上涨 0.5 * ATR,加仓一个 Unit
if current_price >= (status['last_buy_price'] + 0.5 * atr):
order(security, unit_size)
log.info(f"[加仓] 价格上涨0.5N,买入 {security} {unit_size}股")
status['units'] += 1
status['last_buy_price'] = current_price
在聚宽平台进行回测时,通过调整品种配置和K线周期,可以观察到显著的业绩差异:
get_bars 或 run_daily(..., time='every_bar') 在分钟级别运行。分钟线能更灵敏地捕捉日内突破,止损更及时。然而,**交易摩擦成本(佣金+印花税+滑点)**会大幅上升。在实际回测中,若未设置合理的滑点(如未调用 set_slippage),分钟线可能表现虚高;一旦加入真实滑点,日内假突破的磨损可能导致净值跑输日线周期。initialize 中务必使用 set_option('use_real_price', True),确保回测与模拟盘价格一致,避免前复权带来的未来函数。set_slippage(PriceRelatedSlippage(0.00246)) 模拟真实交易摩擦,尤其在分钟级回测中,这能过滤掉无法实盘的虚假高收益。