@Channelchan
2018-09-19T12:16:16.000000Z
字数 8339
阅读 1298
策略逻辑:设定唐安奇通道上线,为50分钟收盘最大值,当分钟的最大值突破上一分钟通道的上线1.01倍时认为有上涨趋势并做多,分钟最小值突破上线0.99倍且上一分钟是在上线之上时判断有下跌趋势并做空(若有仓位,突破时平仓,并且反向开仓)。
在一号的海龟策略基础上,增加了仓位管理操作,利用ATR判断波动率,波动率小的时候重仓,波动率大的时候弱仓。
# coding: utf-8from vnpy.trader.vtConstant import *from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,BarGenerator,ArrayManager)from collections import defaultdictimport numpy as npimport talib as taimport pandas as pdfrom datetime import datetimeclass wangge_Strategy(CtaTemplate):#单边海龟策略+波动率仓位管理className = 'wangge_Strategy'author = 'sky'symbol = EMPTY_STRING# 策略变量posSize = 1 # 每笔下单的数量fastWindow = 20 # 快速均线参数slowWindow = 80 # 慢速均线参数stopRatio = 0.06 # 止损比例fixsize = 1transactionPrice = EMPTY_FLOAT # 记录成交价格wave = EMPTY_FLOAT########### 参数列表,保存了参数的名称paramList = ['name','className','author','symbol','fastWindow','slowWindow','stopRatio','profitMultiplier']# 变量列表,保存了变量的名称varList = ['inited','trading','posDict','transactionPrice','maTrend']# 同步列表,保存了需要保存到数据库的变量名称syncList = ['posDict','eveningDict','bondDict']#----------------------------------------------------------------------def __init__(self, ctaEngine, setting):# 首先找到策略的父类(就是类CtaTemplate),然后把DoubleMaStrategy的对象转换为类CtaTemplate的对象super(wangge_Strategy, self).__init__(ctaEngine, setting)#----------------------------------------------------------------------def onInit(self):"""初始化策略(必须由用户继承实现)"""self.writeCtaLog(u'海龟策略初始化')# 初始化仓位字典self.symbol = self.symbolList[0]self.generateBarDict(self.onBar)self.generateBarDict(self.onBar,5,self.on5MinBar,size =100)if self.ctaEngine.engineType == 'trading':# 实盘载入1分钟历史数据,并采用回放计算的方式初始化策略参数# 通用可选参数:["1min","5min","15min","30min","60min","4hour","1day","1week","1month"]pastbar1 = self.loadHistoryBar(self.Symbol,type_ = "1min", size = 1000)# 更新数据矩阵(optional)for bar1 in zip (pastbar1):self.amDict[self.symbol].updateBar(bar1)elif self.ctaEngine.engineType == 'backtesting':# 获取回测设置中的initHours长度的历史数据self.initBacktesingData()self.putEvent()#----------------------------------------------------------------------def onStart(self):"""启动策略(必须由用户继承实现)"""self.writeCtaLog(u'网格策略初始化')#print('start',file=test)self.putEvent()#----------------------------------------------------------------------def onStop(self):"""停止策略(必须由用户继承实现)"""self.putEvent()#----------------------------------------------------------------------def onTick(self, tick):"""收到行情TICK推送(必须由用户继承实现)"""passdef onBar(self, bar):"""收到Bar推送(必须由用户继承实现)"""self.writeCtaLog('stg_onbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,bar.close))self.bg5Dict[bar.vtSymbol].updateBar(bar)am = self.am5Dict[self.symbol]# fastMa = ta.MA(am.close, self.fastWindow)# slowMa = ta.MA(am.close, self.slowWindow)# if fastMa[-2] < slowMa[-2] and fastMa[-1] > slowMa[-1]:# self.Trend = 1# else:# self.Trend = 0# if slowMa[-1]>slowMa[-2]:# self.wave = 1# else:# self.wave = 0# if (self.posDict[self.symbol+"_LONG"] >0 and self.posDict[self.symbol+"_LONG"] <10):# if self.wave == 0:# self.sell(self.symbol, bar.close*0.98, self.posDict[self.symbol+"_LONG"], priceType = PRICETYPE_LIMITPRICE,levelRate = 10)# n = int((bar.close-self.transactionPrice)/0.001)# print('n:%s,bar.close:%s,self.transactionPrice:%s'%(n,bar.close,self.transactionPrice))# if n>0:# self.sell(self.symbol, bar.close, n,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)# if self.posDict[self.symbol+"_LONG"] == 0:# if self.wave == 1:# self.buy(self.symbol, bar.close*0.98, 5, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)# elif n<0:# self.buy(self.symbol, bar.close*0.98, -n, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)if self.posDict[self.symbol+"_LONG"] ==5:self.sell(self.symbol, bar.close, 5,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)def on5MinBar(self, bar):"""15分钟K线推送"""self.writeCtaLog('stg_on5Minbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,self.am5Dict[bar.vtSymbol].close))self.am5Dict[bar.vtSymbol].updateBar(bar)am5 = self.am5Dict[self.symbol]fastMa = ta.MA(am5.close, self.fastWindow)slowMa = ta.MA(am5.close, self.slowWindow)if fastMa[-2] < fastMa[-1] and slowMa[-2] > slowMa[-1]:self.Trend = 1else:self.Trend = 0if (self.posDict[self.symbol+"_LONG"] == 0) and (self.posDict[self.symbol+"_SHORT"] == 0):if self.Trend == 1:self.buy(self.symbol, bar.close*1.02 , 5 ,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)######### 计算策略需要的信号-------------------------------------------------####################################self.putEvent()def onOrder(self, order):"""收到委托变化推送(必须由用户继承实现)"""# 对于无需做细粒度委托控制的策略,可以忽略onOrderpass#----------------------------------------------------------------------def onTrade(self, trade):"""收到成交推送(必须由用户继承实现)"""self.transactionPrice = trade.price#print('price:%s, direction:%s,offset:%s,self.Cross:%s,tradeVolume: %s'#%(trade.price, trade.direction, trade.offset,self.Cross,trade.volume),file=test0)pass#----------------------------------------------------------------------def onStopOrder(self, so):"""停止单推送"""pass
from __future__ import divisionfrom vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEnginefrom vnpy.trader.app.ctaStrategy.ctaBase import *if __name__ == '__main__':# 创建回测引擎engine = BacktestingEngine()# 设置引擎的回测模式为K线engine.setBacktestingMode(engine.BAR_MODE)# 设置回测用的数据起始日期engine.setStartDate('20180820 01:01',initHours=1) # 设置回测用的数据起始日期engine.setEndDate('20180823 16:01')# 设置产品相关参数engine.setSlippage(0.2) # 股指1跳engine.setRate(0.3/10000) # 万0.3engine.setSize(300) # 股指合约大小engine.setPriceTick(0.2) # 股指最小价格变动# 设置使用的历史数据库engine.setDatabase('OANDA_M1')# 在引擎中创建策略对象d = {'symbolList':['AUD_USD:oanda']}engine.initStrategy(wangge_Strategy, d)# 开始跑回测engine.runBacktesting()# 输出策略的回测日志import pandas as pdfrom datetime import datetimeimport oslog = engine.logListdataframe = pd.DataFrame(log)filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'filename = os.path.abspath(filename)dataframe.to_csv(filename,index=False,sep=',')# 显示回测结果engine.showBacktestingResult()engine.showDailyResult()
仓位字典构造完成
初始仓位: {'AUD_USD:oanda_LONG': 0, 'AUD_USD:oanda_SHORT': 0}
可平仓量: {'AUD_USD:oanda_LONG': 0, 'AUD_USD:oanda_SHORT': 0}
2018-09-18 23:42:54.797719 开始回测
2018-09-18 23:42:54.797719 策略初始化
2018-09-18 23:42:54.798719 载入历史数据。数据范围:[20180820 00:01,20180820 01:01)
2018-09-18 23:42:54.820751 We don't have AUD_USD:oanda in database
2018-09-18 23:42:54.821751 Our database have these symbols: []
2018-09-18 23:42:54.821751 !!没有数据 没有数据 没有数据!!
2018-09-18 23:42:54.821751 策略初始化完成
2018-09-18 23:42:54.821751 策略启动完成
2018-09-18 23:42:54.821751 开始回放回测数据,回测范围:[20180820 01:01,20180823 16:01)
2018-09-18 23:42:54.822750 载入历史数据。数据范围:[20180820 01:01,20180823 16:01)
2018-09-18 23:42:54.829745 We don't have AUD_USD:oanda in database
2018-09-18 23:42:54.829745 Our database have these symbols: []
2018-09-18 23:42:54.829745 !!没有数据 没有数据 没有数据!!
2018-09-18 23:42:54.829745 数据回放结束
2018-09-18 23:42:54.839739 计算回测结果
2018-09-18 23:42:54.840746 成交记录为空,无法计算回测结果
2018-09-18 23:42:54.840746 ------------------------------
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-2-ba112c76f517> in <module>()
37 dataframe.to_csv(filename,index=False,sep=',')
38 # 显示回测结果
---> 39 engine.showBacktestingResult()
40 engine.showDailyResult()
C:\ProgramData\Anaconda3\lib\site-packages\vnpy_fxdayu-1.1.0-py3.6.egg\vnpy\trader\app\ctaStrategy\ctaBacktesting.py in showBacktestingResult(self)
990 # 输出
991 self.output('-' * 30)
--> 992 self.output(u'第一笔交易:\t%s' % d['timeList'][0])
993 self.output(u'最后一笔交易:\t%s' % d['timeList'][-1])
994
KeyError: 'timeList'
def test(symboll):from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine, OptimizationSetting, MINUTE_DB_NAME# 创建回测引擎对象engine = BacktestingEngine()# 设置回测使用的数据engine.setBacktestingMode(engine.BAR_MODE) # 设置引擎的回测模式为K线engine.setDatabase(MINUTE_DB_NAME) # 设置使用的历史数据库engine.setStartDate('2018001 01:01',initHours=1) # 设置回测用的数据起始日期engine.setEndDate('20180905 16:01')# 配置回测引擎参数engine.setSlippage(0.2) # 设置滑点为股指1跳engine.setRate(0.3/10000) # 设置手续费万0.3engine.setSize(300) # 设置股指合约大小engine.setPriceTick(0.2) # 设置股指最小价格变动engine.setCapital(1000000) # 设置回测本金# # 在引擎中创建策略对象d = {'symbolList':[symboll]} # 策略参数配置engine.initStrategy(DeStrategy, d) # 创建策略对象engine.runBacktesting()import pandas as pdfrom datetime import datetimeimport oslog = engine.logListdataframe = pd.DataFrame(log)filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'filename = os.path.abspath(filename)dataframe.to_csv(filename,index=False,sep=',')# 显示回测结果# 显示逐日回测结果engine.showDailyResult()# 显示逐笔回测结果engine.showBacktestingResult()
test('EOSUSDT:binance')
symbol = ['EOSUSDT:binance','BTCUSDT:binance','ETCUSDT:binance','ETHUSDT:binance','LTCUSDT:binance']
for i in symbol:test(i)
# # 显示前10条成交记录# for i in range(1000):# d = engine.tradeDict[str(i+1)].__dict__# print('TradeID: %s, Time: %s, Direction: %s, Price: %s, Volume: %s' %(d['tradeID'], d['dt'], d['direction'], d['price'], d['volume']))