[关闭]
@Channelchan 2018-11-28T17:57:06.000000Z 字数 7088 阅读 61285

5_MultiSignal


多信号策略逻辑:

  1. CCI指标(30分钟信号)
  2. RSI指标(30分钟信号)
  3. MA指标(60分钟)
  4. 固定比率吊灯止损(分钟)
  1. from __future__ import division
  2. from vnpy.trader.vtConstant import *
  3. from vnpy.trader.app.ctaStrategy import CtaTemplate
  4. import talib as ta
  5. class MultiSignalStrategy(CtaTemplate):
  6. className = 'MultiSignalStrategy'
  7. author = 'ChannelCMT'
  8. amWindow = 20
  9. # 策略参数
  10. smaPeriod = 20; lmaPeriod = 55
  11. cciPeriod = 10; cciThrehold = 10
  12. rsiPeriod = 10; rsiEntry = 12
  13. trailingPct = 0.04
  14. lot = 1
  15. # 策略变量
  16. transactionPrice = {} # 记录成交价格
  17. intraTradeHighDict = {}; intraTradeLowDict = {}
  18. RSI = {}; CCI = {}; MA = {}
  19. # 参数列表,保存了参数的名称
  20. paramList = [
  21. 'amWindow',
  22. 'rsiPeriod', 'rsiEntry',
  23. 'cciPeriod', 'cciThreshold',
  24. 'smaPeriod', 'lmaPeriod',
  25. 'trailingPct']
  26. # 变量列表,保存了变量的名称
  27. varList = ['transactionPrice'
  28. 'intraTradeHighDict', 'intraTradeLowDict'
  29. 'RSI', 'CCI', 'MA']
  30. # 同步列表,保存了需要保存到数据库的变量名称
  31. syncList = ['posDict', 'eveningDict']
  32. #----------------------------------------------------------------------
  33. def __init__(self, ctaEngine, setting):
  34. # 首先找到策略的父类(就是类CtaTemplate),然后把DoubleMaStrategy的对象转换为类CtaTemplate的对象
  35. super().__init__(ctaEngine, setting)
  36. #----------------------------------------------------------------------
  37. def onInit(self):
  38. """初始化策略"""
  39. self.writeCtaLog(u'策略初始化')
  40. self.transactionPrice = {s:0 for s in self.symbolList}
  41. self.intraTradeHighDict = {s:0 for s in self.symbolList}
  42. self.intraTradeLowDict = {s:999999 for s in self.symbolList}
  43. self.RSI = {s:0 for s in self.symbolList}
  44. self.CCI = {s:0 for s in self.symbolList}
  45. self.MA = {s:0 for s in self.symbolList}
  46. self.putEvent()
  47. #----------------------------------------------------------------------
  48. def onStart(self):
  49. """启动策略"""
  50. self.writeCtaLog(u'策略启动')
  51. self.putEvent()
  52. #----------------------------------------------------------------------
  53. def onStop(self):
  54. """停止策略"""
  55. self.writeCtaLog(u'策略停止')
  56. self.putEvent()
  57. #----------------------------------------------------------------------
  58. def onTick(self, tick):
  59. """收到行情TICK推送"""
  60. pass
  61. #----------------------------------------------------------------------
  62. def onBar(self, bar):
  63. """收到Bar推送"""
  64. symbol = bar.vtSymbol
  65. # 洗价器(止盈止损)
  66. if self.posDict[symbol+'_LONG'] == 0 and self.posDict[symbol+'_SHORT'] == 0:
  67. self.intraTradeHighDict[symbol] = 0
  68. self.intraTradeLowDict[symbol] = 999999
  69. # 持有多头仓位
  70. elif self.posDict[symbol+'_LONG'] >0:
  71. self.intraTradeHighDict[symbol] = max(self.intraTradeHighDict[symbol], bar.high)
  72. self.longStop = self.intraTradeHighDict[symbol]*(1-self.trailingPct)
  73. if bar.close<=self.longStop:
  74. self.cancelAll()
  75. self.sell(symbol, bar.close*0.9, self.posDict[symbol+'_LONG'])
  76. # # 持有空头仓位
  77. elif self.posDict[symbol+'_SHORT'] >0:
  78. self.intraTradeLowDict[symbol] = min(self.intraTradeLowDict[symbol], bar.low)
  79. self.shortStop = self.intraTradeLowDict[symbol]*(1+self.trailingPct)
  80. if bar.close>=self.shortStop:
  81. self.cancelAll()
  82. self.cover(symbol, bar.close*1.1, self.posDict[symbol+'_SHORT'])
  83. self.putEvent()
  84. def on30MinBar(self, bar):
  85. symbol = bar.vtSymbol
  86. am30 = self.getArrayManager(symbol, "30m")
  87. if not am30.inited:
  88. return
  89. cci = ta.CCI(am30.high, am30.low, am30.close, self.cciPeriod)
  90. rsi = ta.RSI(am30.close, self.rsiPeriod)
  91. rsiLong = 50 + self.rsiEntry
  92. rsiShort = 50 - self.rsiEntry
  93. if cci[-1]>self.cciThrehold:
  94. self.CCI[symbol] = 1
  95. elif cci[-1]<-self.cciThrehold:
  96. self.CCI[symbol] = -1
  97. else:
  98. self.CCI[symbol] = 0
  99. if rsi[-1]>=rsiLong:
  100. self.RSI[symbol] = 1
  101. elif rsi[-1]<=rsiShort:
  102. self.RSI[symbol] = -1
  103. else:
  104. self.RSI[symbol] = 0
  105. # 发出状态更新事件
  106. self.putEvent()
  107. def on60MinBar(self, bar):
  108. symbol = bar.vtSymbol
  109. am60 = self.getArrayManager(symbol, "60m")
  110. if not am60.inited:
  111. return
  112. SMA = ta.MA(am60.close, self.smaPeriod)
  113. LMA = ta.MA(am60.close, self.lmaPeriod)
  114. if SMA[-1]>LMA[-1]:
  115. self.MA[symbol] = 1
  116. elif SMA[-1]<LMA[-1]:
  117. self.MA[symbol] = -1
  118. else:
  119. self.MA[symbol] = 0
  120. Signal = self.MA[symbol]+self.CCI[symbol]+self.RSI[symbol]
  121. if (Signal>=2) and (self.posDict[symbol+'_LONG']==0):
  122. if self.posDict[symbol+'_SHORT']==0:
  123. self.buy(symbol,bar.close*1.02, self.lot)
  124. elif self.posDict[symbol+'_SHORT'] > 0:
  125. self.cancelAll()
  126. self.cover(symbol,bar.close*1.1, self.posDict[symbol+'_SHORT'])
  127. self.buy(symbol,bar.close*1.1, self.lot)
  128. elif (Signal<=-2) and (self.posDict[symbol+'_SHORT']==0):
  129. if (self.posDict[symbol+'_LONG']==0):
  130. self.short(symbol,bar.close*0.9, self.lot)
  131. elif self.posDict[symbol+'_LONG']>0:
  132. self.cancelAll()
  133. self.sell(symbol,bar.close*0.98, self.posDict[symbol+'_LONG'])
  134. self.short(symbol,bar.close*0.98, self.lot)
  135. self.putEvent()
  136. #----------------------------------------------------------------------
  137. def onOrder(self, order):
  138. """收到委托变化推送(必须由用户继承实现)"""
  139. # 对于无需做细粒度委托控制的策略,可以忽略onOrder
  140. pass
  141. #----------------------------------------------------------------------
  142. def onTrade(self, trade):
  143. """收到成交推送(必须由用户继承实现)"""
  144. symbol = trade.vtSymbol
  145. if trade.offset == OFFSET_OPEN: # 判断成交订单类型
  146. self.transactionPrice[symbol] = trade.price # 记录成交价格
  147. # print(trade.tradeTime, self.posDict)
  148. #----------------------------------------------------------------------
  149. def onStopOrder(self, so):
  150. """停止单推送"""
  151. pass
  1. from vnpy.trader.app.ctaStrategy import BacktestingEngine
  2. import pandas as pd
  3. def runBacktesting(strategyClass, settingDict,
  4. startDate, endDate, slippage, rate):
  5. engine = BacktestingEngine()
  6. engine.setBacktestingMode(engine.BAR_MODE) # 设置引擎的回测模式为K线
  7. engine.setDatabase('VnTrader_1Min_Db') # 设置使用的历史数据库
  8. engine.setStartDate(startDate, initHours=200) # 设置回测用的数据起始日期
  9. engine.setEndDate(endDate) # 设置回测用的数据结束日期
  10. engine.setSlippage(slippage) # 设置滑点
  11. engine.setRate(rate) # 设置手续费万0.3
  12. engine.initStrategy(strategyClass, settingDict)
  13. engine.setCapital(100000) # 设置回测本金
  14. engine.runBacktesting()
  15. #显示逐日回测结果
  16. engine.showDailyResult()
  17. #显示逐笔回测结果
  18. engine.showBacktestingResult()
  19. # 计算回测结果
  20. perfromance = engine.calculateDailyResult()
  21. perfromanceDf , result = engine.calculateDailyStatistics(perfromance)
  22. tradeReport = pd.DataFrame([obj.__dict__ for obj in engine.tradeDict.values()])
  23. tradeDf = tradeReport.set_index('dt')
  24. return perfromanceDf, tradeDf
  1. parameterDict = {'symbolList':['BTCUSDT:binance']}
  2. runBacktesting(MultiSignalStrategy, parameterDict, '20180901 12:00', '20181125 12:00', 0.002, 5/10000)
2018-11-27 17:43:32.023331  计算按日统计结果
2018-11-27 17:43:32.040316  ------------------------------
2018-11-27 17:43:32.040316  首个交易日:  2018-09-01 00:00:00
2018-11-27 17:43:32.040316  最后交易日:  2018-11-25 00:00:00
2018-11-27 17:43:32.040316  总交易日:   86
2018-11-27 17:43:32.040316  盈利交易日   52
2018-11-27 17:43:32.040316  亏损交易日:  33
2018-11-27 17:43:32.040316  起始资金:   100000
2018-11-27 17:43:32.040316  结束资金:   103,607.16
2018-11-27 17:43:32.040316  总收益率:   3.61%
2018-11-27 17:43:32.040316  年化收益:   10.07%
2018-11-27 17:43:32.040316  总盈亏:    3,607.16
2018-11-27 17:43:32.041316  最大回撤:   -308.75
2018-11-27 17:43:32.041316  百分比最大回撤: -0.31%
2018-11-27 17:43:32.041316  总手续费:   356.74
2018-11-27 17:43:32.041316  总滑点:    0.23
2018-11-27 17:43:32.041316  总成交金额:  713,478.68
2018-11-27 17:43:32.041316  总成交笔数:  117
2018-11-27 17:43:32.041316  日均盈亏:   41.94
2018-11-27 17:43:32.041316  日均手续费:  4.15
2018-11-27 17:43:32.041316  日均滑点:   0.0
2018-11-27 17:43:32.041316  日均成交金额: 8,296.26
2018-11-27 17:43:32.041316  日均成交笔数: 1.36
2018-11-27 17:43:32.041316  日均收益率:  0.04%
2018-11-27 17:43:32.041316  收益标准差:  0.16%
2018-11-27 17:43:32.041316  Sharpe Ratio:   3.77

output_4_1.png-53.8kB

2018-11-27 17:43:33.486833  计算回测结果
2018-11-27 17:43:33.496824  ------------------------------
2018-11-27 17:43:33.496824  第一笔交易:  2018-09-05 17:59:00
2018-11-27 17:43:33.496824  最后一笔交易: 2018-11-25 11:58:00
2018-11-27 17:43:33.496824  总交易次数:  59
2018-11-27 17:43:33.496824  总盈亏:    3,605.27
2018-11-27 17:43:33.496824  最大回撤:   -361.43
2018-11-27 17:43:33.496824  平均每笔盈利: 61.11
2018-11-27 17:43:33.497822  平均每笔滑点: 0.0
2018-11-27 17:43:33.497822  平均每笔佣金: 6.08
2018-11-27 17:43:33.497822  胜率      45.76%
2018-11-27 17:43:33.497822  盈利交易平均值 198.05
2018-11-27 17:43:33.497822  亏损交易平均值 -54.44
2018-11-27 17:43:33.497822  盈亏比:    3.64

output_4_3.png-39.7kB

2018-11-27 17:43:34.450847  计算按日统计结果
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注