@Channelchan
2018-11-28T10:00:31.000000Z
字数 10881
阅读 64776
60分钟看长短期MA趋势, 15分钟做均线择时。
from __future__ import divisionfrom vnpy.trader.vtConstant import *from vnpy.trader.app.ctaStrategy import CtaTemplateimport talib as ta######################################################################### 策略继承CtaTemplateclass MultiFrameMaStrategy(CtaTemplate):className = 'MultiFrameMaStrategy'author = 'ChannelCMT'# 策略参数fastPeriod = 20; slowPeriod = 55signalMaPeriod = 20lot = 1# 策略变量maTrend = {} # 记录趋势状态,多头1,空头-1transactionPrice = {} # 记录成交价格# 参数列表,保存了参数的名称paramList = ['fastPeriod', 'slowPeriod','signalMaPeriod']# 变量列表,保存了变量的名称varList = ['maTrend','transactionPrice']# 同步列表,保存了需要保存到数据库的变量名称syncList = ['posDict', 'eveningDict']#----------------------------------------------------------------------def __init__(self, ctaEngine, setting):super().__init__(ctaEngine, setting)#----------------------------------------------------------------------def onInit(self):"""初始化策略"""self.writeCtaLog(u'策略初始化')self.transactionPrice = {s:0 for s in self.symbolList} # 生成成交价格的字典self.maTrend = {s:0 for s in self.symbolList}self.putEvent()#----------------------------------------------------------------------def onStart(self):"""启动策略"""self.writeCtaLog(u'策略启动')self.putEvent()#----------------------------------------------------------------------def onStop(self):"""停止策略"""self.writeCtaLog(u'策略停止')self.putEvent()#----------------------------------------------------------------------def onTick(self, tick):"""收到行情TICK推送"""pass#----------------------------------------------------------------------def onBar(self, bar):"""收到Bar推送"""pass#----------------------------------------------------------------------def on60MinBar(self, bar):"""收到60MinBar推送"""symbol = bar.vtSymbolam60 = self.getArrayManager(symbol, "60m")if not am60.inited:return# 计算均线并判断趋势fastMa = ta.MA(am60.close, self.fastPeriod)slowMa = ta.MA(am60.close, self.slowPeriod)if fastMa[-1] > slowMa[-1]:self.maTrend[symbol] = 1else:self.maTrend[symbol] = -1#----------------------------------------------------------------------def on15MinBar(self, bar):"""收到15MinBar推送"""symbol = bar.vtSymbolam15 = self.getArrayManager(symbol, "15m")if not am15.inited:returnsignalMa = ta.EMA(am15.close, self.signalMaPeriod)maUp = signalMa[-1]>signalMa[-3] # 均线上涨maDn = signalMa[-1]<signalMa[-3] # 均线下跌# 均线上涨, 趋势为多头, 多头没有持仓if maUp and (self.maTrend[symbol]==1) and (self.posDict[symbol+'_LONG']==0):if (self.posDict[symbol+'_SHORT']==0):self.buy(symbol, bar.close*1.01, self.lot) # 成交价*1.01发送高价位的限价单,以最优市价买入进场elif (self.posDict[symbol+'_SHORT'] > 0):self.cancelAll() # 撤销挂单self.cover(symbol, bar.close*1.01, self.posDict[symbol+'_SHORT'])self.buy(symbol, bar.close*1.01, self.lot)# 均线下跌, 趋势为空头, 空头没有持仓if maDn and (self.maTrend[symbol]==-1) and (self.posDict[symbol+'_SHORT']==0):if (self.posDict[symbol+'_LONG']==0):# self.cancelAll() # 撤销挂单self.short(symbol, bar.close*0.99, self.lot) # 成交价*0.99发送低价位的限价单,以最优市价卖出进场elif (self.posDict[symbol+'_LONG'] > 0):self.cancelAll() # 撤销挂单self.sell(symbol, bar.close*0.99, self.posDict[symbol+'_LONG'])self.short(symbol, bar.close*0.99, self.lot)self.putEvent()#----------------------------------------------------------------------def onOrder(self, order):"""收到委托变化推送(必须由用户继承实现)"""# 对于无需做细粒度委托控制的策略,可以忽略onOrderpass#----------------------------------------------------------------------def onTrade(self, trade):"""收到成交推送(必须由用户继承实现)"""# 对于无需做交易信息记录的策略,可以忽略onTradepass#----------------------------------------------------------------------def onStopOrder(self, so):"""停止单推送"""pass
if __name__=="__main__":from vnpy.trader.app.ctaStrategy import BacktestingEngine# 创建回测引擎对象engine = BacktestingEngine()# 设置回测使用的数据engine.setBacktestingMode(engine.BAR_MODE) # 设置引擎的回测模式为K线engine.setDatabase('VnTrader_1Min_Db') # 设置使用的历史数据库engine.setStartDate('20180901 12:00',initHours=200) # 设置回测用的数据起始日期engine.setEndDate('20181123 12:00') # 设置回测用的数据终止日期# 配置回测引擎参数engine.setSlippage(0.002) # 设置滑点engine.setRate(5/10000) # 设置手续费千1engine.setCapital(1000000) # 设置回测本金# # 在引擎中创建策略对象parameterDict = {'symbolList':['BTCUSDT:binance']} # 策略参数配置engine.initStrategy(MultiFrameMaStrategy, parameterDict) # 创建策略对象engine.runBacktesting()
import pandas as pdtradeReport = pd.DataFrame([obj.__dict__ for obj in engine.tradeDict.values()])tradeDf = tradeReport.set_index('dt')tradeDf.tail()
# 显示逐日回测结果engine.showDailyResult()
2018-11-27 16:39:28.106324 计算按日统计结果
2018-11-27 16:39:28.125304 ------------------------------
2018-11-27 16:39:28.125304 首个交易日: 2018-09-01 00:00:00
2018-11-27 16:39:28.125304 最后交易日: 2018-11-23 00:00:00
2018-11-27 16:39:28.125304 总交易日: 84
2018-11-27 16:39:28.125304 盈利交易日 54
2018-11-27 16:39:28.125304 亏损交易日: 29
2018-11-27 16:39:28.125304 起始资金: 1000000
2018-11-27 16:39:28.125304 结束资金: 1,003,343.23
2018-11-27 16:39:28.125304 总收益率: 0.33%
2018-11-27 16:39:28.125304 年化收益: 0.96%
2018-11-27 16:39:28.125304 总盈亏: 3,343.23
2018-11-27 16:39:28.125304 最大回撤: -308.75
2018-11-27 16:39:28.125304 百分比最大回撤: -0.03%
2018-11-27 16:39:28.125304 总手续费: 230.16
2018-11-27 16:39:28.125304 总滑点: 0.14
2018-11-27 16:39:28.125304 总成交金额: 460,323.2
2018-11-27 16:39:28.125304 总成交笔数: 71
2018-11-27 16:39:28.125304 日均盈亏: 39.8
2018-11-27 16:39:28.125304 日均手续费: 2.74
2018-11-27 16:39:28.125304 日均滑点: 0.0
2018-11-27 16:39:28.125304 日均成交金额: 5,480.04
2018-11-27 16:39:28.125304 日均成交笔数: 0.85
2018-11-27 16:39:28.125304 日均收益率: 0.0%
2018-11-27 16:39:28.125304 收益标准差: 0.01%
2018-11-27 16:39:28.125304 Sharpe Ratio: 4.24

# 显示逐笔回测结果engine.showBacktestingResult()
2018-11-27 16:39:29.634764 计算回测结果
2018-11-27 16:39:29.637760 ------------------------------
2018-11-27 16:39:29.638759 第一笔交易: 2018-09-05 22:00:00
2018-11-27 16:39:29.638759 最后一笔交易: 2018-11-23 11:58:00
2018-11-27 16:39:29.638759 总交易次数: 36
2018-11-27 16:39:29.638759 总盈亏: 3,341.06
2018-11-27 16:39:29.638759 最大回撤: -254.65
2018-11-27 16:39:29.638759 平均每笔盈利: 92.81
2018-11-27 16:39:29.638759 平均每笔滑点: 0.0
2018-11-27 16:39:29.638759 平均每笔佣金: 6.45
2018-11-27 16:39:29.638759 胜率 36.11%
2018-11-27 16:39:29.638759 盈利交易平均值 339.84
2018-11-27 16:39:29.638759 亏损交易平均值 -46.82
2018-11-27 16:39:29.638759 盈亏比: 7.26

df = engine.calculateDailyResult()df1, result = engine.calculateDailyStatistics(df)print(pd.Series(result))
2018-11-27 16:39:30.319064 计算按日统计结果
annualizedReturn 0.955208
dailyCommission 2.74002
dailyNetPnl 39.8003
dailyReturn 0.00384366
dailySlippage 0.00169048
dailyTradeCount 0.845238
dailyTurnover 5480.04
endBalance 1.00334e+06
endDate 2018-11-23 00:00:00
lossDays 29
maxDdPercent -0.0308648
maxDrawdown -308.747
profitDays 54
returnStd 0.0140566
sharpeRatio 4.23614
startDate 2018-09-01 00:00:00
totalCommission 230.162
totalDays 84
totalNetPnl 3343.23
totalReturn 0.334323
totalSlippage 0.142
totalTradeCount 71
totalTurnover 460323
dtype: object
from vnpy.trader.app.ctaStrategy.ctaBacktesting import OptimizationSetting# 优化配置setting = OptimizationSetting() # 新建一个优化任务设置对象setting.setOptimizeTarget('sharpeRatio') # 设置优化排序的目标是夏普setting.addParameter('fastPeriod', 20, 40, 10) # 增加第一个优化参数,起始30,结束50,步进10setting.addParameter('slowPeriod', 40, 80, 20) # 增加第二个优化参数,起始60,结束30,步进10# setting.addParameter('signalMaPeriod', 10, 20, 5) # 增加第二个优化参数,起始10,结束30,步进5setting.addParameter('symbolList', ['BTCUSDT:binance'])import timestart = time.time()# 执行单线程优化resultList = engine.runOptimization(MultiFrameMaStrategy, setting)# 执行多进程优化一般会改写成py文件然后用多线程运行,提高优化速度。# resultList = engine.runParallelOptimization(MultiFrameMaStrategy, setting)print('耗时:%s' %(time.time()-start))
2018-11-27 16:42:45.230052 计算按日统计结果
2018-11-27 16:42:45.247034 ------------------------------
2018-11-27 16:42:45.247034 优化结果:
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 20, 'slowPeriod': 40, 'symbolList': ['BTCUSDT:binance']}"],目标:3.8373178980181555
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 20, 'slowPeriod': 60, 'symbolList': ['BTCUSDT:binance']}"],目标:3.7506375116750355
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 30, 'slowPeriod': 40, 'symbolList': ['BTCUSDT:binance']}"],目标:3.6425674453940045
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 20, 'slowPeriod': 80, 'symbolList': ['BTCUSDT:binance']}"],目标:3.5332416281547103
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 40, 'slowPeriod': 40, 'symbolList': ['BTCUSDT:binance']}"],目标:3.117938276707989
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 30, 'slowPeriod': 80, 'symbolList': ['BTCUSDT:binance']}"],目标:2.9456588639684242
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 30, 'slowPeriod': 60, 'symbolList': ['BTCUSDT:binance']}"],目标:2.919579847922548
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 40, 'slowPeriod': 60, 'symbolList': ['BTCUSDT:binance']}"],目标:2.6339188082989096
2018-11-27 16:42:45.247034 参数:["{'fastPeriod': 40, 'slowPeriod': 80, 'symbolList': ['BTCUSDT:binance']}"],目标:2.458459639228935
耗时:160.99369764328003
import pandas as pdprint(pd.DataFrame(resultList).sort_values(1, ascending=False))
0 1 \
0 [{'fastPeriod': 20, 'slowPeriod': 40, 'symbolL... 3.837318
1 [{'fastPeriod': 20, 'slowPeriod': 60, 'symbolL... 3.750638
2 [{'fastPeriod': 30, 'slowPeriod': 40, 'symbolL... 3.642567
3 [{'fastPeriod': 20, 'slowPeriod': 80, 'symbolL... 3.533242
4 [{'fastPeriod': 40, 'slowPeriod': 40, 'symbolL... 3.117938
5 [{'fastPeriod': 30, 'slowPeriod': 80, 'symbolL... 2.945659
6 [{'fastPeriod': 30, 'slowPeriod': 60, 'symbolL... 2.919580
7 [{'fastPeriod': 40, 'slowPeriod': 60, 'symbolL... 2.633919
8 [{'fastPeriod': 40, 'slowPeriod': 80, 'symbolL... 2.458460
2
0 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
1 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
2 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
3 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
4 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
5 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
6 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
7 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
8 {'startDate': 2018-09-01 00:00:00, 'endDate': ...
# 显示优化的所有统计数据for result in resultList:print('-' * 30)print('参数:%s,目标:%s' %(result[0], result[1]))print('统计数据:')for k, v in result[2].items():print('%s:%s' %(k, v))
------------------------------
参数:["{'fastPeriod': 20, 'slowPeriod': 40, 'symbolList': ['BTCUSDT:binance']}"],目标:3.8373178980181555
统计数据:
startDate:2018-09-01 00:00:00
endDate:2018-11-23 00:00:00
totalDays:84
profitDays:43
lossDays:40
endBalance:1002162.8486499999
maxDrawdown:-800.1604799999623
maxDdPercent:-0.0802844900912358
totalNetPnl:2162.8486499999967
dailyNetPnl:25.748198214285676
totalCommission:366.11134999999996
dailyCommission:4.358468452380952
totalSlippage:0.23000000000000015
dailySlippage:0.00273809523809524
totalTurnover:732222.7000000001
dailyTurnover:8716.936904761906
totalTradeCount:115
dailyTradeCount:1.369047619047619
totalReturn:0.21628486500000488
annualizedReturn:0.617956757142871
dailyReturn:0.009231223526044257
returnStd:0.037268087692137686
sharpeRatio:3.8373178980181555
------------------------------
参数:["{'fastPeriod': 20, 'slowPeriod': 60, 'symbolList': ['BTCUSDT:binance']}"],目标:3.7506375116750355
统计数据:
startDate:2018-09-01 00:00:00
endDate:2018-11-23 00:00:00
totalDays:84
profitDays:50
lossDays:32
endBalance:1002955.52815
maxDrawdown:-312.15648999996483
maxDdPercent:-0.031176176911619793
totalNetPnl:2955.528149999998
dailyNetPnl:35.1848589285714
totalCommission:216.72784999999996
dailyCommission:2.580093452380952
totalSlippage:0.13400000000000006
dailySlippage:0.001595238095238096
totalTurnover:433455.70000000007
dailyTurnover:5160.186904761906
totalTradeCount:67
dailyTradeCount:0.7976190476190477
totalReturn:0.29555281499999975
annualizedReturn:0.8444366142857136
dailyReturn:0.0033835644182150003
returnStd:0.013975745298525763
sharpeRatio:3.7506375116750355