[关闭]
@Channelchan 2018-09-19T20:16:16.000000Z 字数 8339 阅读 1143

Xiezhenghang-二号策略(一号策略改进版本)

策略逻辑:设定唐安奇通道上线,为50分钟收盘最大值,当分钟的最大值突破上一分钟通道的上线1.01倍时认为有上涨趋势并做多,分钟最小值突破上线0.99倍且上一分钟是在上线之上时判断有下跌趋势并做空(若有仓位,突破时平仓,并且反向开仓)。

在一号的海龟策略基础上,增加了仓位管理操作,利用ATR判断波动率,波动率小的时候重仓,波动率大的时候弱仓。

  1. # coding: utf-8
  2. from vnpy.trader.vtConstant import *
  3. from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
  4. BarGenerator,
  5. ArrayManager)
  6. from collections import defaultdict
  7. import numpy as np
  8. import talib as ta
  9. import pandas as pd
  10. from datetime import datetime
  11. class wangge_Strategy(CtaTemplate):
  12. #单边海龟策略+波动率仓位管理
  13. className = 'wangge_Strategy'
  14. author = 'sky'
  15. symbol = EMPTY_STRING
  16. # 策略变量
  17. posSize = 1 # 每笔下单的数量
  18. fastWindow = 20 # 快速均线参数
  19. slowWindow = 80 # 慢速均线参数
  20. stopRatio = 0.06 # 止损比例
  21. fixsize = 1
  22. transactionPrice = EMPTY_FLOAT # 记录成交价格
  23. wave = EMPTY_FLOAT
  24. ##########
  25. # 参数列表,保存了参数的名称
  26. paramList = ['name',
  27. 'className',
  28. 'author',
  29. 'symbol',
  30. 'fastWindow',
  31. 'slowWindow',
  32. 'stopRatio',
  33. 'profitMultiplier']
  34. # 变量列表,保存了变量的名称
  35. varList = ['inited',
  36. 'trading',
  37. 'posDict',
  38. 'transactionPrice',
  39. 'maTrend']
  40. # 同步列表,保存了需要保存到数据库的变量名称
  41. syncList = ['posDict',
  42. 'eveningDict',
  43. 'bondDict']
  44. #----------------------------------------------------------------------
  45. def __init__(self, ctaEngine, setting):
  46. # 首先找到策略的父类(就是类CtaTemplate),然后把DoubleMaStrategy的对象转换为类CtaTemplate的对象
  47. super(wangge_Strategy, self).__init__(ctaEngine, setting)
  48. #----------------------------------------------------------------------
  49. def onInit(self):
  50. """初始化策略(必须由用户继承实现)"""
  51. self.writeCtaLog(u'海龟策略初始化')
  52. # 初始化仓位字典
  53. self.symbol = self.symbolList[0]
  54. self.generateBarDict(self.onBar)
  55. self.generateBarDict(self.onBar,5,self.on5MinBar,size =100)
  56. if self.ctaEngine.engineType == 'trading':
  57. # 实盘载入1分钟历史数据,并采用回放计算的方式初始化策略参数
  58. # 通用可选参数:["1min","5min","15min","30min","60min","4hour","1day","1week","1month"]
  59. pastbar1 = self.loadHistoryBar(self.Symbol,
  60. type_ = "1min", size = 1000)
  61. # 更新数据矩阵(optional)
  62. for bar1 in zip (pastbar1):
  63. self.amDict[self.symbol].updateBar(bar1)
  64. elif self.ctaEngine.engineType == 'backtesting':
  65. # 获取回测设置中的initHours长度的历史数据
  66. self.initBacktesingData()
  67. self.putEvent()
  68. #----------------------------------------------------------------------
  69. def onStart(self):
  70. """启动策略(必须由用户继承实现)"""
  71. self.writeCtaLog(u'网格策略初始化')
  72. #print('start',file=test)
  73. self.putEvent()
  74. #----------------------------------------------------------------------
  75. def onStop(self):
  76. """停止策略(必须由用户继承实现)"""
  77. self.putEvent()
  78. #----------------------------------------------------------------------
  79. def onTick(self, tick):
  80. """收到行情TICK推送(必须由用户继承实现)"""
  81. pass
  82. def onBar(self, bar):
  83. """收到Bar推送(必须由用户继承实现)"""
  84. self.writeCtaLog('stg_onbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,bar.close))
  85. self.bg5Dict[bar.vtSymbol].updateBar(bar)
  86. am = self.am5Dict[self.symbol]
  87. # fastMa = ta.MA(am.close, self.fastWindow)
  88. # slowMa = ta.MA(am.close, self.slowWindow)
  89. # if fastMa[-2] < slowMa[-2] and fastMa[-1] > slowMa[-1]:
  90. # self.Trend = 1
  91. # else:
  92. # self.Trend = 0
  93. # if slowMa[-1]>slowMa[-2]:
  94. # self.wave = 1
  95. # else:
  96. # self.wave = 0
  97. # if (self.posDict[self.symbol+"_LONG"] >0 and self.posDict[self.symbol+"_LONG"] <10):
  98. # if self.wave == 0:
  99. # self.sell(self.symbol, bar.close*0.98, self.posDict[self.symbol+"_LONG"], priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  100. # n = int((bar.close-self.transactionPrice)/0.001)
  101. # print('n:%s,bar.close:%s,self.transactionPrice:%s'%(n,bar.close,self.transactionPrice))
  102. # if n>0:
  103. # self.sell(self.symbol, bar.close, n,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  104. # if self.posDict[self.symbol+"_LONG"] == 0:
  105. # if self.wave == 1:
  106. # self.buy(self.symbol, bar.close*0.98, 5, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  107. # elif n<0:
  108. # self.buy(self.symbol, bar.close*0.98, -n, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  109. if self.posDict[self.symbol+"_LONG"] ==5:
  110. self.sell(self.symbol, bar.close, 5,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  111. def on5MinBar(self, bar):
  112. """15分钟K线推送"""
  113. self.writeCtaLog('stg_on5Minbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,self.am5Dict[bar.vtSymbol].close))
  114. self.am5Dict[bar.vtSymbol].updateBar(bar)
  115. am5 = self.am5Dict[self.symbol]
  116. fastMa = ta.MA(am5.close, self.fastWindow)
  117. slowMa = ta.MA(am5.close, self.slowWindow)
  118. if fastMa[-2] < fastMa[-1] and slowMa[-2] > slowMa[-1]:
  119. self.Trend = 1
  120. else:
  121. self.Trend = 0
  122. if (self.posDict[self.symbol+"_LONG"] == 0) and (self.posDict[self.symbol+"_SHORT"] == 0):
  123. if self.Trend == 1:
  124. self.buy(self.symbol, bar.close*1.02 , 5 ,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
  125. ######### 计算策略需要的信号-------------------------------------------------####################################
  126. self.putEvent()
  127. def onOrder(self, order):
  128. """收到委托变化推送(必须由用户继承实现)"""
  129. # 对于无需做细粒度委托控制的策略,可以忽略onOrder
  130. pass
  131. #----------------------------------------------------------------------
  132. def onTrade(self, trade):
  133. """收到成交推送(必须由用户继承实现)"""
  134. self.transactionPrice = trade.price
  135. #print('price:%s, direction:%s,offset:%s,self.Cross:%s,tradeVolume: %s'
  136. #%(trade.price, trade.direction, trade.offset,self.Cross,trade.volume),file=test0)
  137. pass
  138. #----------------------------------------------------------------------
  139. def onStopOrder(self, so):
  140. """停止单推送"""
  141. pass
  1. from __future__ import division
  2. from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine
  3. from vnpy.trader.app.ctaStrategy.ctaBase import *
  4. if __name__ == '__main__':
  5. # 创建回测引擎
  6. engine = BacktestingEngine()
  7. # 设置引擎的回测模式为K线
  8. engine.setBacktestingMode(engine.BAR_MODE)
  9. # 设置回测用的数据起始日期
  10. engine.setStartDate('20180820 01:01',initHours=1) # 设置回测用的数据起始日期
  11. engine.setEndDate('20180823 16:01')
  12. # 设置产品相关参数
  13. engine.setSlippage(0.2) # 股指1跳
  14. engine.setRate(0.3/10000) # 万0.3
  15. engine.setSize(300) # 股指合约大小
  16. engine.setPriceTick(0.2) # 股指最小价格变动
  17. # 设置使用的历史数据库
  18. engine.setDatabase('OANDA_M1')
  19. # 在引擎中创建策略对象
  20. d = {'symbolList':['AUD_USD:oanda']}
  21. engine.initStrategy(wangge_Strategy, d)
  22. # 开始跑回测
  23. engine.runBacktesting()
  24. # 输出策略的回测日志
  25. import pandas as pd
  26. from datetime import datetime
  27. import os
  28. log = engine.logList
  29. dataframe = pd.DataFrame(log)
  30. filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'
  31. filename = os.path.abspath(filename)
  32. dataframe.to_csv(filename,index=False,sep=',')
  33. # 显示回测结果
  34. engine.showBacktestingResult()
  35. 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'
  1. def test(symboll):
  2. from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine, OptimizationSetting, MINUTE_DB_NAME
  3. # 创建回测引擎对象
  4. engine = BacktestingEngine()
  5. # 设置回测使用的数据
  6. engine.setBacktestingMode(engine.BAR_MODE) # 设置引擎的回测模式为K线
  7. engine.setDatabase(MINUTE_DB_NAME) # 设置使用的历史数据库
  8. engine.setStartDate('2018001 01:01',initHours=1) # 设置回测用的数据起始日期
  9. engine.setEndDate('20180905 16:01')
  10. # 配置回测引擎参数
  11. engine.setSlippage(0.2) # 设置滑点为股指1跳
  12. engine.setRate(0.3/10000) # 设置手续费万0.3
  13. engine.setSize(300) # 设置股指合约大小
  14. engine.setPriceTick(0.2) # 设置股指最小价格变动
  15. engine.setCapital(1000000) # 设置回测本金
  16. # # 在引擎中创建策略对象
  17. d = {'symbolList':[symboll]} # 策略参数配置
  18. engine.initStrategy(DeStrategy, d) # 创建策略对象
  19. engine.runBacktesting()
  20. import pandas as pd
  21. from datetime import datetime
  22. import os
  23. log = engine.logList
  24. dataframe = pd.DataFrame(log)
  25. filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'
  26. filename = os.path.abspath(filename)
  27. dataframe.to_csv(filename,index=False,sep=',')
  28. # 显示回测结果
  29. # 显示逐日回测结果
  30. engine.showDailyResult()
  31. # 显示逐笔回测结果
  32. engine.showBacktestingResult()
  1. test('EOSUSDT:binance')
  1. symbol = ['EOSUSDT:binance','BTCUSDT:binance','ETCUSDT:binance','ETHUSDT:binance','LTCUSDT:binance']
  1. for i in symbol:
  2. test(i)
  1. # # 显示前10条成交记录
  2. # for i in range(1000):
  3. # d = engine.tradeDict[str(i+1)].__dict__
  4. # print('TradeID: %s, Time: %s, Direction: %s, Price: %s, Volume: %s' %(d['tradeID'], d['dt'], d['direction'], d['price'], d['volume']))
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注