量化策略——海龟混合双通道策略

本文主要是利用海龟交易策略进行量化交易策略的构建,同时用均线策略,布林带策略等经典策略构建第二条通道进行策略改善。

数据来源:
https://tushare.pro/register?reg=403436
不知道如何编写代码的也可以直接进入数据工具接口生成即可Tushare数据工具,非常方便。

首先先利用API接口获得沪深300近10年数据,然后进行数据清理,构造布林带策略和均线均线策略的组件。

import math
import tushare as ts
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import talib


matplotlib.rcParams['axes.unicode_minus']=False
plt.rcParams['font.sans-serif']=['SimHei']
ts.set_token('af3...')#这里是token码 获取地址  https://tushare.pro/register?reg=403436(需注册)
pro = ts.pro_api()

df=pro.index_daily(ts_code='399300.SZ', start_date='20100101', end_date='20211010')
df=df.sort_index()
df.index=pd.to_datetime(df.trade_date,format='%Y-%m-%d')#设置日期索引
df = df[::-1]
close = df.close
ret = df['close'].pct_change()

close20 = talib.MA(np.array(close),timeperiod=20)
atr1 = talib.ATR(df['high'].values,df['low'].values,df['close'].values,timeperiod=20)
atr = pd.DataFrame(atr1)
atr.index=pd.to_datetime(df.trade_date,format='%Y-%m-%d')
atr = atr.fillna(0)
mv = talib.MA(np.array(df.close),timeperiod=20)
close_bup = mv+2*atr1
close_bdw = mv-2*atr1

#实现最大回撤

def MaxDrawdown(return_list):
    
    # 1. find all of the peak of cumlative return 
    maxcum = np.zeros(len(return_list))
    b = return_list[0]
    for i in range(0,len((return_list))):
        if (return_list[i]>b):
            b = return_list[i]
        maxcum[i] = b
    
    # 2. then find the max drawndown point
    i = np.argmax((maxcum-return_list)/maxcum) 
    if i == 0:
        return 0
    j = np.argmax(return_list[:i])   
    
    # 3. return the maxdrawndown
    return (return_list[j]-return_list[i])/return_list[j]

先构造经典20日,55日海龟长期交易策略

'''
普通短期海龟交易策略图示及框架
'''
def haigui(short,long):
    SmaSignal = pd.Series(0,index=close.index)
    for i in range(long,len(close)):
        if close[i]>max(close[i-long:i]):
            SmaSignal[i]=1
        elif close[i]<min(close[i-short:i]):
            SmaSignal[i]=0
        else:
            SmaSignal[i]=SmaSignal[i-1]
    SmaTrade = SmaSignal.shift(1).dropna()
    SmaRet = ret*SmaTrade
    SmaRet=SmaRet.dropna()
    
    #策略累积收益率
    cumStock = (1+ret[SmaRet.index[0:]]).cumprod()
    cumTrade = np.cumprod(1+SmaRet)

    plt.plot(cumTrade,label='海龟交易策略净值线',color='r')
    plt.plot(cumStock,label='直接持有净值线',color='k')
    plt.title('海龟交易策略')
    plt.legend()
    #总收益率
    year_n = len(df)/242
    cagr=(1+cumTrade[-1])**(1/year_n)-1
    SR=(SmaRet.mean()-0.00135/365)/SmaRet.std()*np.sqrt(242)
    benchmark =ret.mean()
    IR=(SmaRet.mean()-benchmark)/SmaRet.std()*np.sqrt(242)
    MH=MaxDrawdown(cumTrade)
    print('策略累计收益率:'+ str(cumTrade[-1]))
    print('策略年化收益率:'+ str(cagr))
    print('夏普比率:'+ str(SR))
    print('信息比率:'+ str(IR))
    print('最大回撤:'+ str(MH))

'''
长期:20,55
'''

haigui(20,55)

策略累计收益率:1.7992776730184188
策略年化收益率:0.09110535656105423
夏普比率:0.45756551980402194
信息比率:0.031684543775977014
最大回撤:0.32839036842157054

海龟交易策略整体情况是不错的,但是还不够好,年化9%不够高。

优化系统 均线策略X海龟双通道策略
构造20日均线 上穿20日均线或海龟线任意一个就买入 下穿20日均线且碰到海龟线才卖出
 

def haiguiXjunxian(short,long):
    SmaSignal = pd.Series(0,index=close.index)
    s=0
    k=0
    for i in range(long,len(close)):
        if close[i]>max(close[i-long:i]) or all([close[i]>close20[i],close[i-1]<close20[i-1]]):
            SmaSignal[i]=1
            k+=1
        elif  close[i]<min(close[i-short:i]) and all([close[i]<close20[i],close[i-1]>close20[i-1]]):
            SmaSignal[i]=0
            k+=1
        else:
            SmaSignal[i]=SmaSignal[i-1]
        s=s+SmaSignal[i]
        ds = len(close)-s
        
    SmaTrade = SmaSignal.shift(1).dropna()
    SmaRet = ret*SmaTrade
    SmaRet=SmaRet.dropna()
    
    #策略累积收益率
    cumStock = (1+ret[SmaRet.index[0:]]).cumprod()
    
    cumTrade = np.cumprod(1+SmaRet)
    plt.plot(cumTrade,label='海龟交易策略净值线',color='r')
    plt.plot(cumStock,label='直接持有净值线',color='k')
    plt.title('海龟交易策略')
    plt.legend()
    #总收益率
    year_n = len(df)/242
    cagr=(1+cumTrade[-1])**(1/year_n)-1
    SR=(SmaRet.mean()-0.00135/365)/SmaRet.std()*np.sqrt(242)
    benchmark =ret.mean()
    IR=(SmaRet.mean()-benchmark)/SmaRet.std()*np.sqrt(242)
    MH=MaxDrawdown(cumTrade)
    print('策略累计收益率:'+ str(cumTrade[-1]))
    print('策略年化收益率:'+ str(cagr))
    print('夏普比率:'+ str(SR))
    print('信息比率:'+ str(IR))
    print('最大回撤:'+ str(MH))
  
haiguiXjunxian(20,55)

策略累计收益率:1.8879248200168226
策略年化收益率:0.09399056122632032
夏普比率:0.35310434487607206
信息比率:0.11052841469154707
最大回撤:0.46696138837984724

成功跑赢原始海龟策略,但是最大回撤过大,而且没计算交易成本,所以继续改进。

构造布林带上下轨,限制交易频率,在满足海龟交易策略且位于布林带上轨才买入,而在满足海龟交易策略且刺穿布林带下轨才卖出。

def haiguiXbulin(short,long):
    SmaSignal = pd.Series(0,index=close.index)
    s=0
    k=0
    for i in range(long,len(close)):
        if close[i]>max(close[i-long:i]) and close[i]>close_bup[i]:
            SmaSignal[i]=1
            k+=1
        elif  close[i]<min(close[i-short:i]) and all([close[i]<close_bdw[i],close[i-1]>close_bdw[i-1]]):
            SmaSignal[i]=0
            k+=1
        else:
            SmaSignal[i]=SmaSignal[i-1]
        s=s+SmaSignal[i]
        ds = len(close)-s
        
    SmaTrade = SmaSignal.shift(1).dropna()
    SmaRet = ret*SmaTrade
    SmaRet=SmaRet.dropna()
    
    #策略累积收益率
    cumStock = (1+ret[SmaRet.index[0:]]).cumprod()
    
    cumTrade = np.cumprod(1+SmaRet)
    plt.plot(cumTrade,label='海龟交易策略净值线',color='r')
    plt.plot(cumStock,label='直接持有净值线',color='k')
    plt.title('海龟交易策略')
    plt.legend()
    #总收益率
    year_n = len(df)/242
    cagr=(1+cumTrade[-1])**(1/year_n)-1
    SR=(SmaRet.mean()-0.00135/365)/SmaRet.std()*np.sqrt(242)
    benchmark =ret.mean()
    IR=(SmaRet.mean()-benchmark)/SmaRet.std()*np.sqrt(242)
    MH=MaxDrawdown(cumTrade)
    print('策略累计收益率:'+ str(cumTrade[-1]))
    print('策略年化收益率:'+ str(cagr))
    print('夏普比率:'+ str(SR))
    print('信息比率:'+ str(IR))
    print('最大回撤:'+ str(MH))

haiguiXbulin(20,55)

策略累计收益率:2.2329523717630524
策略年化收益率:0.10449872667110616
夏普比率:0.5754578953903876
信息比率:0.17648503084869085
最大回撤:0.27539806074090606

 跑赢上一个均线+海龟的组合模型,且最大回测大幅度降低,夏普比率上到0.7。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值