海龟交易法则(策略源码)

什么是海龟交易法则?

1983年年中,著名的商品投机家理查德.丹尼斯与他的老友比尔.埃克哈特进行了一场辩论,这场辩论是关于伟大的交易员是天生造就还是后天培养的。理查德相信,他可以教会人们成为伟大的交易员。比尔则认为遗传和天性才是决定因素。

​ 为了解决这一问题,理查德建议招募并培训一些交易员,给他们提供真实的帐户进行交易,看看两个人中谁是正确的。

​ 他们在《巴伦氏》、《华尔街期刊》和《纽约时报》上刊登了大幅广告,招聘交易学员。广告中称,在一个短暂的培训会后,新手将被提供一个帐户进行交易。

​ 理查德从报名的人中精选出13个人,1983年12月底,学员被邀请到芝加哥进行两周的培训,到1984年1月初,开始用小帐户进行交易。到了2月初,在学员证明了自己的能力之后,丹尼斯给其中的大多数人提供了50万至200万美元的资金帐户。

​ “学员们被称为‘海龟’(丹尼斯先生说这项计划开始时他刚刚从亚洲回来,他解释了自己向别人说过的话,‘我们正在成长为交易员,就象在新加坡他们正在成长为海龟一样’)。”----斯坦利.W.安格瑞斯特,《华尔街期刊》,1989年9月5日

​ 海龟成为交易史上最著名的实验,因为在随后的四年中这些海龟交易员取得了年均复利80%的收益。

​ 是的,里克证明了交易可以被传授。他证明了用一套简单的法则,他可以使仅有很少或根本没有交易经验的人成为优秀的交易员。而这个交易法则被后世称为“海龟交易法则”。

海龟交易法则具体内容

海龟交易法则:海龟交易法则属于趋势交易,首先建立唐奇安通道(下文会具体解释),即确定上突破线和下突破线,如果价格突破上线,则做多,如果价格突破下线就平仓或做空。

唐奇安通道与开仓

唐奇安通道,作为一个通道必定有上线和下线,上线就是前N1日内的最高价,下线就是前N2日内的最低价,一般来说N1=20,N2=10;然后,价格上穿就买,下穿就卖,就是这么简单。

但是仅仅只用唐奇安通道进行买卖,其实效果跟MACD线等其他趋势策略的效果差不多,并没有更优

ATR与仓位管理

海龟交易法则最核心的部分,在于仓位的控制,这种止损会让你基准的亏损不超过总资金的n%,所以这部分的思想是需要我们学习的。

当日的真实波幅TR(true range)

计算当日真实波幅公式:

	TR_1=Max(H_1−L_1,H_1−C_0,C_0−L_1)

其中,下表1代表当日,下表0代表昨日,​是昨日开盘价close,H是最高价high,L是最低价low。

平均波幅ATR(Average true range)

一般取前20日的平均TR。

		ATR_{20}=mean(TR_1,TR_2…TR_{19},TR_{20})

其中,公式​代表求​和​的平均数。

这时候我们已经求出ATR,这个数字可以当做衡量今天的价格波幅的基准,为1单位,比如现在价格是100元,基准波幅ATR=4元,代表今天基准波幅在98-102元,如果是2倍ATR,波幅就在96-104元。

仓位管理

在仅讨论多头的情况下:

1、如果标的价格跌破"持仓均价-0.5(1、1.5、2)倍的ATR",则平仓至原始仓位的75%(50%,25%,0%)。

2、如果标的价格跌破唐奇安通道下轨,则全平仓。

海龟交易法则策略实现(基于掘金量化平台)

策略思想

  • 当价格上穿唐奇安通道且短MA在长MA上方时开多仓;当价格下穿唐奇安通道且短MA在长MA下方时开空仓(8手)

  • 若有多仓则在价格跌破唐奇安平仓通道下轨的时候全平仓位,否则根据跌破持仓均价 - x(x=0.5,1,1.5,2)倍ATR把仓位平至6/4/2/0手

  • 若有空仓则在价格涨破唐奇安平仓通道上轨的时候全平仓位,否则根据涨破持仓均价 + x(x=0.5,1,1.5,2)倍ATR把仓位平至6/4/2/0手

策略主要步骤实现

订阅数据

subscribe(symbols=symbols, frequency='1d', count=31, wait_group=True)

订阅数据需要在定义init函数里面设置,并调用subscribe函数,这里注意,我们需要通过计算前三十根bars来作为开平仓的标准,并在当前bar上做出开平仓操作,所以需要获取31根bar:

.symbols 需要设置订阅的标的代码。

.frequency需设置订阅数据的周期级别,这里设置1d 表示以一天为周期。

.count需要设置获取的bar的数量

数据获取

data = context.data(symbol=symbol, frequency='1d', count=31, fields='close')

订阅数据之后,需要获取已经订阅的数据来进行操作,这时需调用context.data函数:

.symbols 需要设置订阅的标的代码。

.frequency需设置订阅数据的周期级别,这里设置1d表示以一天为周期。

.count需要设置获取的bar的数量

.fields需要设置返回值的种类

获取持仓信息

position_long = context.account().position(symbol=symbol, side=PositionSide_Long)

position_short = context.account().position(symbol=symbol, side=PositionSide_Short)

在判断平仓条件时,需要获取持仓信息(包含持仓均价),这就需要调用context.account().position函数:

.symbols 需要设置订阅的标的代码。

.side需要设置持仓方向,有PositionSide_LongPositionSide_Short两个选择。

在判断平仓条件时,需要获取持仓信息(包含持仓均价),这就需要调用context.account().position函数:

.symbols 需要设置订阅的标的代码。

.side需要设置持仓方向,有PositionSide_LongPositionSide_Short两个选择。

策略回测分析

回测报告

分析

​ 我们选取了2017年6月至2017年12月作为回测周期,“RB1801”与“FG801”作为标的合约,均线长短周期分别为5d,20d,唐奇安通道上下轨计算周期分别为20d,10d,ATR计算周期为20d,可以看出:

胜率(具有盈利的平仓次数与总平仓次数之比)达到了34.48%,因为海龟交易法则为趋势跟踪策略,所以胜率不会太高。

卡玛比率(年化收益率与历史最大回撤之比)是使用最大回撤率来衡量风险。采用最大回撤率来衡量风险,关注的是最极端的情况。卡玛比率越高表示策略承受每单位最大损失获得的报酬越高。在这里卡玛比率超过了9。

夏普比率(年化收益率减无风险收益率的差收益波动率之比)超过2.5,也即承受1单位的风险,会有超过2.5个单位的收益回报

策略收益曲线整体相对稳定,适合稳定型投资者,最大回撤极小,另外,策略在趋势行情行情中表现更加。

海龟交易法则策略源码

# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals

import sys

import numpy as np
import pandas as pd

try:
    import talib
except:
    print('请安装TA-Lib库')
    sys.exit(-1)
from gm.api import *

'''
本策略基于掘金量化交易平台 网址:www.myquant.cn

本策略通过计算CZCE.FG801和SHFE.rb1801的ATR.唐奇安通道和MA线,
当价格上穿唐奇安通道且短MA在长MA上方时开多仓;当价格下穿唐奇安通道且短MA在长MA下方时开空仓(8手)
若有多仓则在价格跌破唐奇安平仓通道下轨的时候全平仓位,否则根据跌破
持仓均价 - x(x=0.5,1,1.5,2)倍ATR把仓位平至6/4/2/0手
若有空仓则在价格涨破唐奇安平仓通道上轨的时候全平仓位,否则根据涨破
持仓均价 + x(x=0.5,1,1.5,2)倍ATR把仓位平至6/4/2/0手
回测数据为:CZCE.FG801和SHFE.rb1801的1min数据
回测时间为:2017-09-15 09:15:00到2017-10-01 15:00:00
'''


def init(context):
    # context.parameter分别为唐奇安开仓通道.唐奇安平仓通道.短ma.长ma.ATR的参数
    context.parameter = [20, 10, 5, 20, 20]
    context.tar = context.parameter[4]
    # context.goods交易的品种
    context.goods = ['CZCE.FG801', 'SHFE.rb1801']
    # 订阅context.goods里面的品种, bar频率为1min
    subscribe(symbols=context.goods, frequency='1d', count=51)
    # 止损的比例区间


def on_bar(context, bars):
    bar = bars[0]
    symbol = bar['symbol']
    recent_data = context.data(symbol=symbol, frequency='1d', count=51, fields='close,high,low')
    close = recent_data['close'].values[-1]
    # 计算ATR
    atr = talib.ATR(recent_data['high'].values, recent_data['low'].values, recent_data['close'].values,
                    timeperiod=context.tar)[-1]
    # 计算唐奇安开仓和平仓通道
    context.don_open = context.parameter[0] + 1
    upper_band = talib.MAX(recent_data['close'].values[:-1], timeperiod=context.don_open)[-1]
    context.don_close = context.parameter[1] + 1
    lower_band = talib.MIN(recent_data['close'].values[:-1], timeperiod=context.don_close)[-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:
        # 计算长短ma线.DIF
        ma_short = talib.MA(recent_data['close'].values, timeperiod=(context.parameter[2] + 1))[-1]
        ma_long = talib.MA(recent_data['close'].values, timeperiod=(context.parameter[3] + 1))[-1]
        dif = ma_short - ma_long
        # 获取当前价格
        # 上穿唐奇安通道且短ma在长ma上方则开多仓
        if close > upper_band and (dif > 0):
            order_target_volume(symbol=symbol, volume=80, position_side=PositionSide_Long, order_type=OrderType_Market)
            print(symbol, '市价单开多仓8手')
        # 下穿唐奇安通道且短ma在长ma下方则开空仓
        if close < lower_band and (dif < 0):
            order_target_volume(symbol=symbol, volume=80, position_side=PositionSide_Short, order_type=OrderType_Market)
            print(symbol, '市价单开空仓8手')
    elif position_long:
        # 价格跌破唐奇安平仓通道全平仓位止损
        if close < lower_band:
            order_close_all()
            print(symbol, '市价单全平仓位')
        else:
            # 获取持仓均价
            vwap = position_long['vwap']
            # 获取持仓的资金
            band = vwap - np.array([200, 2, 1.5, 1, 0.5, -100]) * atr
            # 计算最新应持仓位
            grid_volume = int(pd.cut([close], band, labels=[0, 10, 20, 30, 40])[0]) * 2
            order_target_volume(symbol=symbol, volume=grid_volume, position_side=PositionSide_Long,
                                order_type=OrderType_Market)
            print(symbol, '市价单平多仓到', grid_volume, '手')
    elif position_short:
        # 价格涨破唐奇安平仓通道或价格涨破持仓均价加两倍ATR平空仓
        if close > upper_band:
            order_close_all()
            print(symbol, '市价单全平仓位')
        else:
            # 获取持仓均价
            vwap = position_short['vwap']
            # 获取平仓的区间
            band = vwap + np.array([-100, 0.5, 1, 1.5, 2, 200]) * atr
            # 计算最新应持仓位
            grid_volume = int(pd.cut([close], band, labels=[0, 10, 20, 30, 40])[0]) * 2
            order_target_volume(symbol=symbol, volume=grid_volume, position_side=PositionSide_Short,
                                order_type=OrderType_Market)
            print(symbol, '市价单平空仓到', grid_volume, '手')


def on_backtest_finished(context, indicator):

    print ("Eeee")
    print (indicator)


if __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='bdd1f831-0c90-11e8-923b-00ffe31f5606',
        filename='turtal.py',
        mode=MODE_BACKTEST,
        token='732412ea44cd9db2dc2d93ac78dcd99a1ce54142',
        backtest_start_time='2017-06-01 09:15:00',
        backtest_end_time='2017-12-11 15:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

来源:掘金量化     作者:宋瑞笛

推荐阅读:

市面上经典的量化交易策略都在这里了!(源码)

期货/股票数据大全查询(历史/实时/Tick/财务等)

学习Python量化有哪些书籍?这里有一份书单送给你

量化交易领域最重要的10本参考书推荐!

配对交易—这个股票策略曾年赚5000万美元

一个量化策略师的自白(好文强烈推荐)

网格交易法,一个不容易亏钱的投资策略(附源码)

 

  • 8
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
海龟交易策略是一种经典的市场交易策略,其基本原理是根据价格的波动情况进行交易。 在Python中,可以使用Turtle库来实现海龟交易策略源码。以下是一个简单的示例: ```python import turtle def turtle_trading_strategy(price_data): # 初始化海龟交易指标参数 entry_price = price_data[0] # 入场价格 exit_price = price_data[0] # 出场价格 stop_loss = price_data[0] * 0.98 # 止损价格 position = 0 # 持仓数量,0表示没有持仓,正数表示多头持仓,负数表示空头持仓 # 初始化海龟图形 turtle.setup(800, 600) # 设置画布大小 turtle.title("Turtle Trading Strategy") # 设置标题 # 循环遍历价格数据 for price in price_data: if price > entry_price and position <= 0: # 如果价格高于入场价格且当前没有持仓,则进行多头开仓操作 turtle.pendown() turtle.goto(0, price) turtle.penup() entry_price = price stop_loss = entry_price * 0.98 # 更新止损价格 position = 1 # 更新持仓数量 elif price < exit_price and position >= 0: # 如果价格低于出场价格且当前持有多头仓位,则进行多头平仓操作 turtle.pendown() turtle.goto(0, price) turtle.penup() exit_price = price position = 0 # 更新持仓数量 elif price < stop_loss and position >= 0: # 如果价格低于止损价格且当前持有多头仓位,则进行多头止损操作 turtle.pendown() turtle.goto(0, price) turtle.penup() exit_price = price position = 0 # 更新持仓数量 elif price > stop_loss and position < 0: # 如果价格高于止损价格且当前持有空头仓位,则进行空头止损操作 turtle.pendown() turtle.goto(0, price) turtle.penup() exit_price = price position = 0 # 更新持仓数量 turtle.done() # 绘制完毕后显示海龟图形 # 示例数据 price_data = [100, 110, 105, 120, 130, 125, 115, 135, 140, 130] # 调用海龟交易策略函数 turtle_trading_strategy(price_data) ``` 上述代码实现了一个简单的海龟交易策略,给定一个价格数据列表,程序根据海龟交易策略的规则进行买入和卖出操作,并使用Turtle库在画布上进行可视化展示。具体规则包括根据价格的波动情况进行入场、出场和止损操作。 该示例中的价格数据为示意数据,实际应用时需要根据市场的实时价格进行交易决策。同时,为了简化代码,示例中省略了其他相关操作,如手续费、资金管理等,实际应用中需要综合考虑更多因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值