海龟交易策略–量化交易经典之作(附Python完整代码)

一、引言

量化交易,作为金融市场的一种前沿交易方式,其核心在于利用数学模型和计算机技术对市场进行深入分析,进而执行精准的交易策略。在众多量化交易策略中,海龟交易策略以其独特的系统性和趋势跟踪能力,成为量化交易领域的经典之作。

二、海龟交易策略概述

1. 起源与发展

海龟交易策略起源于20世纪80年代的美国,由著名交易员理查德·丹尼斯(Richard Dennis)提出。丹尼斯坚信,优秀的交易技能可以通过系统化培训获得,而非仅仅依赖天赋。他通过培训一批“海龟”交易员,成功验证了这一理念,并将这套交易系统命名为“海龟交易系统”。

2. 核心原理

海龟交易策略以趋势跟踪为核心,致力于捕捉并利用市场中的中长期趋势。该策略通过明确的入场、加仓、止损和止盈规则,实现了交易过程的系统化和机械化,为投资者提供了一种有效的交易方法。

三、海龟交易策略详解

1. 建仓资金管理

海龟交易法将建仓资金按照一定比例划分为若干个小部分,以实现资金的有效利用。每次建仓头寸和加仓规模都与波动量N(平均真实波动振幅ATR)紧密相关,确保在控制风险的同时追求最大收益。

2. 入市信号

海龟交易法采用理查德·唐奇安的通道突破系统作为入市信号。该系统包括两个子系统:系统一基于20日最高价或最低价突破,系统二基于55日价格突破。当价格突破相应系统的价格通道时,即产生入市信号。

3. 加仓与止损

在捕捉到入市信号后,海龟交易法首先建立第一个交易单位的头寸。当市价继续向盈利方向突破1/2N时,策略将进行加仓操作。止损位设为2N,每加仓一次,止损位提高1/2N,以确保在趋势反转时及时止损。

4. 止盈

海龟交易法的止盈规则根据交易周期的不同而有所差异。短期策略中,多头头寸在突破过去10日最低价处止盈离市,空头头寸在突破过去10日最高价处止盈离市。中长期策略中,止盈标准放宽至20日最低价和最高价,以捕捉更大的市场趋势。

四、策略实现与回测

1. 策略实现

在量化交易平台上,海龟交易策略可以通过编写策略代码来实现。首先,需要获取历史数据并计算唐奇安通道和ATR。然后,根据价格突破通道的情况进行开仓操作,并计算加仓和止损信号。

2. 回测结果

以DCE.i2012合约为例,通过设定初始资金、手续费率和滑点比率等参数进行回测。结果显示,海龟交易策略在特定市场条件下表现出较好的盈利能力,但需注意市场环境、交易成本和参数选择对策略有效性的影响。

3. 策略代码(完整Python代码)

# coding=utf-8from __future__ import print_function, absolute_import, unicode_literalsimport numpy as npimport pandas as pdfrom gm.api import *'''以短期为例:20日线第一步:获取历史数据,计算唐奇安通道和ATR第二步:当突破唐奇安通道时,开仓。第三步:计算加仓和止损信号。'''def init(context):    # 设置计算唐奇安通道的参数    context.n = 20    # 设置合约标的    context.symbol = 'DCE.i2012'    # 设置交易最大资金比率    context.ratio = 0.8    # 订阅数据    subscribe(symbols=context.symbol, frequency='60s', count=2)    # 获取当前时间    time = context.now.strftime('%H:%M:%S')    # 如果策略执行时间点是交易时间段,则直接执行algo定义atr等参数,以防直接进入on_bar()导致atr等未定义    if '09:00:00' < time < '15:00:00' or '21:00:00' < time < '23:00:00':        algo(context)    # 如果是交易时间段,等到开盘时间确保进入algo()    schedule(schedule_func=algo, date_rule='1d', time_rule='09:00:00')    schedule(schedule_func=algo, date_rule='1d', time_rule='21:00:00')def algo(context):    # 计算通道的数据:当日最低、最高、上一交易日收盘    # 注:由于talib库计算ATR的结果与公式求得的结果不符,所以这里利用公式计算ATR    # 如果是回测模式,当天的数据直接用history取到    if context.mode == 2:        data = history_n(symbol=context.symbol, frequency='1d', count=context.n+1, end_time=context.now, fields='close,high,low,bob', df=True) # 计算ATR        tr_list = []        for i in range(0, len(data)-1):            tr = max((data['high'].iloc[i] - data['low'].iloc[i]), data['close'].shift(-1).iloc[i] - data['high'].iloc[i],                     data['close'].shift(-1).iloc[i] - data['low'].iloc[i])            tr_list.append(tr)        context.atr = int(np.floor(np.mean(tr_list)))        context.atr_half = int(np.floor(0.5 * context.atr))        # 计算唐奇安通道        context.don_open = np.max(data['high'].values[-context.n:])        context.don_close = np.min(data['low'].values[-context.n:])    # 如果是实时模式,当天的数据需要用current取到    if context.mode == 1:        data = history_n(symbol=context.symbol, frequency='1d', count=context.n, end_time=context.now, fields='close,high,low',                         df=True)  # 计算ATR        current_data = current(symbols=context.symbol)   # 最新一个交易日的最高、最低        tr_list = []        for i in range(1, len(data)):            tr = max((data['high'].iloc[i] - data['low'].iloc[i]),                     data['close'].shift(-1).iloc[i] - data['high'].iloc[i],                     data['close'].shift(-1).iloc[i] - data['low'].iloc[i])            tr_list.append(tr)        # 把最新一期tr加入列表中        tr_new = max((current_data[0]['high'] - current_data[0]['low']),                     data['close'].iloc[-1] - current_data[0]['high'],                     data['close'].iloc[-1] - current_data[0]['low'])        tr_list.append(tr_new)        context.atr = int(np.floor(np.mean(tr_list)))        context.atr_half = int(np.floor(0.5 * context.atr))        # 计算唐奇安通道        context.don_open = np.max(data['high'].values[-context.n:])        context.don_close = np.min(data['low'].values[-context.n:])    # 计算加仓点和止损点    context.long_add_point = context.don_open + context.atr_half    context.long_stop_loss = context.don_open - context.atr_half    context.short_add_point = context.don_close - context.atr_half    context.short_stop_loss = context.don_close + context.atr_halfdef on_bar(context, bars):    # 提取数据    symbol = bars[0]['symbol']    recent_data = context.data(symbol=context.symbol, frequency='60s', count=2, fields='close,high,low')    close = recent_data['close'].values[-1]    # 账户仓位情况    position_long = context.account().position(symbol=symbol, side=PositionSide_Long)    position_short = context.account().position(symbol=symbol, side=PositionSide_Short)    # 当无持仓时    if not position_long and not position_short:        # 如果向上突破唐奇安通道,则开多        if close > context.don_open:            order_volume(symbol=symbol, side=OrderSide_Buy, volume=context.atr, order_type=OrderType_Market, position_effect=PositionEffect_Open)            print('开多仓atr')        # 如果向下突破唐奇安通道,则开空        if close < context.don_close:            order_volume(symbol=symbol, side=OrderSide_Sell, volume=context.atr, order_type=OrderType_Market, position_effect=PositionEffect_Open)            print('开空仓atr')    # 有持仓时    # 持多仓,继续突破(加仓)    if position_long:        # 当突破1/2atr时加仓        if close > context.long_add_point:            order_volume(symbol=symbol, volume=context.atr_half, side=OrderSide_Buy, order_type=OrderType_Market,position_effect=PositionEffect_Open)            print('继续加仓0.5atr')            context.long_add_point += context.atr_half            context.long_stop_loss += context.atr_half        # 持多仓,止损位计算        if close < context.long_stop_loss:            volume_hold = position_long['volume']            if volume_hold >= context.atr_half:                order_volume(symbol=symbol, volume=context.atr_half, side=OrderSide_Sell, order_type=OrderType_Market, position_effect=PositionEffect_Close)            else:                order_volume(symbol=symbol, volume=volume_hold, side=OrderSide_Sell, order_type=OrderType_Market,position_effect=PositionEffect_Close)            print('平多仓0.5atr')            context.long_add_point -= context.atr_half            context.long_stop_loss -= context.atr_half    # 持空仓,继续突破(加仓)    if position_short:        # 当跌破加仓点时加仓        if close < context.short_add_point:            order_volume(symbol = symbol, volume=context.atr_half, side=OrderSide_Sell, order_type=OrderType_Market, position_effect=PositionEffect_Open)            print('继续加仓0.5atr')            context.short_add_point -= context.atr_half            context.short_stop_loss -= context.atr_half        # 持多仓,止损位计算        if close > context.short_stop_loss:            volume_hold = position_short['volume']            if volume_hold >= context.atr_half:                order_volume(symbol=symbol, volume=context.atr_half, side=OrderSide_Buy, order_type=OrderType_Market, position_effect=PositionEffect_Close)            else:                order_volume(symbol=symbol, volume=volume_hold, side=OrderSide_Buy, order_type=OrderType_Market,position_effect=PositionEffect_Close)            print('平空仓0.5atr')            context.short_add_point += context.atr_half            context.short_stop_loss += context.atr_halfif __name__ == '__main__':    '''    strategy_id策略ID,由系统生成    filename文件名,请与本文件名保持一致    mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST    token绑定计算机的ID,可在系统设置-密钥管理中生成    backtest_start_time回测开始时间    backtest_end_time回测结束时间    backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST    backtest_initial_cash回测初始资金    backtest_commission_ratio回测佣金比例    backtest_slippage_ratio回测滑点比例    '''    run(strategy_id='strategy_id',        filename='main.py',        mode=MODE_BACKTEST,        token='token',        backtest_start_time='2020-02-15 09:15:00',        backtest_end_time='2020-09-01 15:00:00',        backtest_adjust=ADJUST_PREV,        backtest_initial_cash=1000000,        backtest_commission_ratio=0.0001,        backtest_slippage_ratio=0.0001)

五、稳健性分析

为了检验海龟交易策略的稳健性,我们进行了多组回测并改变了策略标的和计算唐奇安通道的参数n。结果显示,不同标的的收益结果呈现差异,其中大商所的铁矿石表现较好。整体而言,海龟交易策略在使用上存在一定风险,需要投资者根据市场环境进行适当调整和优化。

设定初始资金100万,手续费率为0.01%,滑点比率为0.01%。回测结果如下图所示。

图片

六、结论

海龟交易策略作为量化交易领域的经典之作,以其系统化和趋势跟踪的特点为投资者提供了一种有效的交易方法。然而,该策略的有效性受市场环境、交易成本和参数选择的影响。因此,投资者在使用海龟交易策略时应充分了解其优势和局限,并结合自身情况和市场状况进行适当的调整和优化。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/106053
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 5天前
下一篇 5天前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注