跟我学VNPY 中基于Talib的KDJ量化交易策略实现 -探索更真实的量化交易世界
VNPY的回测过程
新版本的VNPY已经提供了KDJ指标策略,策略文件就存储在strategyfile目录下面,
VNPY开源项目网址:
https://gitee.com/vnpypro/vnpy
1 # KDJ策略 2 import talib 3 import module_backtest 4 from vnctptdType661 import * 5 from PyQt5 import QtCore 6 # CTP行情库 7 from vnctpmd import * 8 import numpy as np 9 import globalType 10 import globalvar 11 12 parlist = [['fastk_period', 3, 5, 1], ['slowk_period', 15, 30, 1], ['slowd_period', 15, 30, 1]] 13 14 15 class MyStrategy(module_backtest.VirtualAccount, QtCore.QThread): 16 def __init__(self, period, slippoint): 17 super(MyStrategy, self).__init__(period, slippoint) 18 self.TradingDay = [] 19 self.klinetime = [] 20 self.open = [] 21 self.high = [] 22 self.low = [] 23 self.close = [] 24 self.volume = [] 25 self.money = [] 26 self.open_interest = [] 27 self.InstrumentID = [] 28 def OnTick(self, marketdata, strategyname): 29 arg = [5, 20, 0, 0, 0, 0] 30 InstrumentID = str(marketdata.InstrumentID, encoding="utf-8") 31 kline = VNKlineData() 32 kline.InstrumentID = marketdata.InstrumentID 33 # kline.TradingDay = globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay 34 kline.TradingDay = int(str(globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay, encoding="utf-8") ) 35 kline.open = globalvar.md.GetKline(InstrumentID, 1)[0].Open 36 kline.high = globalvar.md.GetKline(InstrumentID, 1)[0].High 37 kline.low = globalvar.md.GetKline(InstrumentID, 1)[0].Low 38 kline.close = globalvar.md.GetKline(InstrumentID, 1)[0].Close 39 kline.volume = globalvar.md.GetKline(InstrumentID, 1)[0].Volume 40 kline.klinetime = int(globalvar.md.GetKline(InstrumentID, 1)[0].Minutes) 41 kline.money = 0 42 kline.open_interest = 0 43 print(str(kline.TradingDay) + "," +str(kline.open)) 44 self.OnKline(kline, arg, strategyname) 45 ''' 46 #(1)marketdata 是 实时Tick数据 47 #(2)这是从CTP Tick由vnctpmd.dll 在本机生成的K线,可以直接按下标方式取得,速度快vnctptd.dll、vnctpmd.py、vnctptd.ini 48 #(3)这是从服务器获得当日K线取法,禁止频繁调用 vnklineservice.dll、vnklineservice.py、vnklineservice.ini 49 #(4)这是当前显示K线图数据暂时,数据来自于(2)和(3),策略计算不用这个 50 globalvar.data_kline_M1[0][globalvar.OPEN] 51 globalvar.data_kline_M1[0][globalvar.HIGH] 52 globalvar.data_kline_M1[0][globalvar.LOW] 53 globalvar.data_kline_M1[0][globalvar.CLOSE] 54 globalvar.data_kline_M1[0][globalvar.KLINETIME] 55 globalvar.data_kline_M1[0][globalvar.VOL] 56 globalvar.md.GetKline(marketdata.InstrumentID, 0).contents.Minutes 57 str(globalvar.data_kline_M1[0][globalvar.INSTRUMENT], encoding="utf-8") 58 str(globalvar.data_kline_M1[0][globalvar.TRADINGDAY], encoding="utf-8") 59 ''' 60 61 def OnKline(self, mddata, arg, strategyname): 62 if arg[0] <= 0 or arg[1] <= 0: 63 return 64 # TradingDay = klinedata.TradingDay.decode() 65 # klinetime = klinedata.klinetime.decode() 66 self.InstrumentID = mddata.InstrumentID.decode() 67 # self.exchange=mddata.exchange.decode() 68 self.close.append(float(mddata.close)) 69 self.high.append(float(mddata.high)) 70 self.low.append(float(mddata.low)) 71 try: 72 float_close = [float(x) for x in self.close] 73 float_high = [float(x) for x in self.high] 74 float_low = [float(x) for x in self.low] 75 except Exception as e: 76 pass 77 # Talib中的STOCH就是KDJ指标,Talib中的SMA就是通达信中的MA,所以结果稍有区别 78 # 默认参数 9,3,3 79 K, D = talib.STOCH(np.array(float_high), np.array(float_low), np.array(float_close), fastk_period=arg[0], 80 slowk_period=arg[1], 81 slowk_matype=0, 82 slowd_period=arg[2], 83 slowd_matype=0) 84 # print('结果1:' + str(self.K)) 85 # print('结果2:' + str(self.D)) 86 # print('结果2:' + str(self.J)) 87 thisK = K[len(K) - 1] 88 thisD = D[len(D) - 1] 89 # thisJ = J[len( J) - 1] 90 if thisK < 50 and thisD < 50 and thisK > thisD: 91 # 金叉 92 if self.sellvol + self.sellvol_history > 0: 93 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Buy, THOST_FTDC_OF_Close, VN_OPT_LimitPrice, 94 mddata.close + 1, 1) 95 if self.buyvol + self.buyvol_history < 10: 96 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Buy, THOST_FTDC_OF_Open, VN_OPT_LimitPrice, 97 mddata.close + 1, 1) 98 elif thisK > 50 and thisD > 50 and thisK < thisD: 99 # 死叉 100 if self.buyvol + self.buyvol_history > 0: 101 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Sell, THOST_FTDC_OF_Close, VN_OPT_LimitPrice, 102 mddata.close - 1, 1) 103 if self.sellvol + self.sellvol_history < 10: 104 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Sell, THOST_FTDC_OF_Open, VN_OPT_LimitPrice, 105 mddata.close - 1, 1)
点击回测,会自动生成回测用的策略文件,在strategyfilebacktest目录下
1 # KDJ策略 2 import talib 3 import module_backtest 4 from vnctptdType661 import * 5 from PyQt5 import QtCore 6 # CTP行情库 7 from vnctpmd import * 8 import numpy as np 9 import globalType 10 import globalvar 11 12 parlist = [['fastk_period', 3, 5, 1], ['slowk_period', 15, 30, 1], ['slowd_period', 15, 30, 1]] 13 14 15 class MyStrategy(module_backtest.VirtualAccount, QtCore.QThread): 16 def __init__(self, period, slippoint): 17 super(MyStrategy, self).__init__(period, slippoint) 18 self.TradingDay = [] 19 self.klinetime = [] 20 self.open = [] 21 self.high = [] 22 self.low = [] 23 self.close = [] 24 self.volume = [] 25 self.money = [] 26 self.open_interest = [] 27 self.InstrumentID = [] 28 def OnTick(self, marketdata, strategyname): 29 arg = [5, 20, 0, 0, 0, 0] 30 InstrumentID = str(marketdata.InstrumentID, encoding="utf-8") 31 kline = VNKlineData() 32 kline.InstrumentID = marketdata.InstrumentID 33 # kline.TradingDay = globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay 34 kline.TradingDay = int(str(globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay, encoding="utf-8") ) 35 kline.open = globalvar.md.GetKline(InstrumentID, 1)[0].Open 36 kline.high = globalvar.md.GetKline(InstrumentID, 1)[0].High 37 kline.low = globalvar.md.GetKline(InstrumentID, 1)[0].Low 38 kline.close = globalvar.md.GetKline(InstrumentID, 1)[0].Close 39 kline.volume = globalvar.md.GetKline(InstrumentID, 1)[0].Volume 40 kline.klinetime = int(globalvar.md.GetKline(InstrumentID, 1)[0].Minutes) 41 kline.money = 0 42 kline.open_interest = 0 43 print(str(kline.TradingDay) + "," +str(kline.open)) 44 self.OnKline(kline, arg, strategyname) 45 ''' 46 #(1)marketdata 是 实时Tick数据 47 #(2)这是从CTP Tick由vnctpmd.dll 在本机生成的K线,可以直接按下标方式取得,速度快vnctptd.dll、vnctpmd.py、vnctptd.ini 48 #(3)这是从服务器获得当日K线取法,禁止频繁调用 vnklineservice.dll、vnklineservice.py、vnklineservice.ini 49 #(4)这是当前显示K线图数据暂时,数据来自于(2)和(3),策略计算不用这个 50 globalvar.data_kline_M1[0][globalvar.OPEN] 51 globalvar.data_kline_M1[0][globalvar.HIGH] 52 globalvar.data_kline_M1[0][globalvar.LOW] 53 globalvar.data_kline_M1[0][globalvar.CLOSE] 54 globalvar.data_kline_M1[0][globalvar.KLINETIME] 55 globalvar.data_kline_M1[0][globalvar.VOL] 56 globalvar.md.GetKline(marketdata.InstrumentID, 0).contents.Minutes 57 str(globalvar.data_kline_M1[0][globalvar.INSTRUMENT], encoding="utf-8") 58 str(globalvar.data_kline_M1[0][globalvar.TRADINGDAY], encoding="utf-8") 59 ''' 60 61 def OnKline(self, mddata, arg, strategyname): 62 if arg[0] <= 0 or arg[1] <= 0: 63 return 64 # TradingDay = klinedata.TradingDay.decode() 65 # klinetime = klinedata.klinetime.decode() 66 self.InstrumentID = mddata.InstrumentID.decode() 67 # self.exchange=mddata.exchange.decode() 68 self.close.append(float(mddata.close)) 69 self.high.append(float(mddata.high)) 70 self.low.append(float(mddata.low)) 71 try: 72 float_close = [float(x) for x in self.close] 73 float_high = [float(x) for x in self.high] 74 float_low = [float(x) for x in self.low] 75 except Exception as e: 76 pass 77 # Talib中的STOCH就是KDJ指标,Talib中的SMA就是通达信中的MA,所以结果稍有区别 78 # 默认参数 9,3,3 79 K, D = talib.STOCH(np.array(float_high), np.array(float_low), np.array(float_close), fastk_period=arg[0], 80 slowk_period=arg[1], 81 slowk_matype=0, 82 slowd_period=arg[2], 83 slowd_matype=0) 84 # print('结果1:' + str(self.K)) 85 # print('结果2:' + str(self.D)) 86 # print('结果2:' + str(self.J)) 87 thisK = K[len(K) - 1] 88 thisD = D[len(D) - 1] 89 # thisJ = J[len( J) - 1] 90 if thisK < 50 and thisD < 50 and thisK > thisD: 91 # 金叉 92 if self.sellvol + self.sellvol_history > 0: 93 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Buy, THOST_FTDC_OF_Close, VN_OPT_LimitPrice, 94 mddata.close + 1, 1) 95 if self.buyvol + self.buyvol_history < 10: 96 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Buy, THOST_FTDC_OF_Open, VN_OPT_LimitPrice, 97 mddata.close + 1, 1) 98 elif thisK > 50 and thisD > 50 and thisK < thisD: 99 # 死叉 100 if self.buyvol + self.buyvol_history > 0: 101 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Sell, THOST_FTDC_OF_Close, VN_OPT_LimitPrice, 102 mddata.close - 1, 1) 103 if self.sellvol + self.sellvol_history < 10: 104 self.InsertOrder(self.InstrumentID, '', THOST_FTDC_D_Sell, THOST_FTDC_OF_Open, VN_OPT_LimitPrice, 105 mddata.close - 1, 1)