溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

在VNPY2的進(jìn)行CTA批量回測(cè),支持Json和Excel格式導(dǎo)入策略

發(fā)布時(shí)間:2020-08-09 14:51:46 來源:ITPUB博客 閱讀:377 作者:張國(guó)平 欄目:編程語(yǔ)言

之前VNPY 1版本中,我的個(gè)人代碼很多是直接在VNPY庫(kù)代碼直接修改或者增加的。每次VNPY升級(jí)就是非常頭疼,要做代碼對(duì)比,在一些可能被更新覆蓋的地方再次維護(hù)測(cè)試。而且因?yàn)楦碌牡胤胶軄y,造成后面生產(chǎn)版本一致停留在VNPY1.92。

這次準(zhǔn)備不在VNPY的庫(kù)文件代碼上修改,而是像引用NUMPY或者Pandas這樣,采用調(diào)用繼承的方式,把自己的代碼和VNPY的庫(kù)代碼隔離;這樣即使VNPY升級(jí),個(gè)人代碼不用太擔(dān)心,只要簡(jiǎn)單測(cè)試,保證繼承引用VNPY的類或方法正常工作就可以了。

也是之前VNPY 1版本實(shí)現(xiàn)的功能,批量回測(cè),結(jié)果Excel導(dǎo)出。這次支持策略參數(shù)用Json或Excel導(dǎo)入,同時(shí)支持多個(gè)策略的組合portfolio收益計(jì)算;其實(shí)都是VNPY2提供好的,調(diào)用而已。只要VNPY2.0 正確安裝,歷史數(shù)據(jù)存在,這些代碼就可以運(yùn)行。

代碼包括這幾個(gè)文件:

- BatchCTABacktesting.py:批量回測(cè)代碼文件,在這個(gè)代碼里面定義和下面?zhèn)€關(guān)聯(lián)文件路徑,默認(rèn)路徑都在一個(gè)文件夾。

- vtSymbol.json:這個(gè)是定義品種交易屬性,回測(cè)時(shí)候從vtSymbol.json文檔讀取品種的交易屬性,比如費(fèi)率,交易每跳,比率,滑點(diǎn);這樣不用在回測(cè)時(shí)候維護(hù)。示例格式如下;有心的可以改成通配符,這樣減少維護(hù)量。

{
  "MA2009.CZCE": {
    "rate": 0.0001,
    "slippage": 1,
    "size": 10,
    "pricetick": 1
  },
  "rb2010.SHFE": {
    "rate": 0.0001,
    "slippage": 1,
    "size": 10,
    "pricetick": 1
  }
}

- ctaStrategy.json:定義要批量回測(cè)策略,其實(shí)和VNPY2默認(rèn)的CTA策略文件是一樣的,這樣就可以直接用實(shí)盤CTA策略文件進(jìn)行批量回測(cè)了,或著計(jì)算組合收益。示例格式如下:

{
  "BollChannelStrategy_MA8888.CZCE": {
    "class_name": "BollChannelStrategy",
    "vt_symbol": "MA8888.CZCE",
    "setting": {
      "boll_window": 40,
      "boll_dev": 3
    }
  },
  "DoubleMaStrategy2_CTA_rb8888.SHFE": {
    "class_name": "DoubleMaStrategy",
    "vt_symbol": "rb8888.SHFE",
    "setting": {
      "fast_window": 10,
      "slow_window": 40
    }
}

- ctaStrategy.xls:用xls格式定義的批量回測(cè)數(shù)據(jù),示例格式如下;有三列, class_name是策略類, setting是參數(shù),v t_symbol是品種。主要是有時(shí)候用excel做策略批量維護(hù)或者生成,然后就可以直接批量回測(cè)了。

class_name setting vt_symbol
AtrRsiStrategy {"atr_length": 10, "atr_ma_length": 50} MA8888.CZCE
DoubleMaStrategy {"fast_window": 10, "slow_window": 40} rb8888.SHFE

現(xiàn)在回來看看代碼。其實(shí)注釋都比較清楚了。注意的幾點(diǎn)是

  1.  策略類是用字符串格式記錄的,然后用eval方法關(guān)聯(lián)類,所以必須引用,雖然編輯器提示未使用

  2. 在excel保存setting必須雙引號(hào),因?yàn)閖son文件默認(rèn)只能識(shí)別雙引號(hào)。

  3. 批量回測(cè)結(jié)果會(huì)用excel輸出,示例就是這樣。

  4. 默認(rèn)json導(dǎo)入會(huì)計(jì)算組合收入,excel不會(huì)計(jì)算組合收益,可以直接修改代碼。

在VNPY2的進(jìn)行CTA批量回測(cè),支持Json和Excel格式導(dǎo)入策略

# encoding: UTF-8
import json
import traceback
from datetime import datetime, date
import pandas as pd
from pandas import DataFrame
from vnpy.app.cta_strategy.backtesting import BacktestingEngine
# 策略類是用字符串格式記錄的,然后用eval方法關(guān)聯(lián)類,所以必須引用,雖然編輯器提示未使用
from vnpy.app.cta_strategy.strategies.boll_channel_strategy import BollChannelStrategy
from vnpy.app.cta_strategy.strategies.turtle_signal_strategy import TurtleSignalStrategy
from vnpy.app.cta_strategy.strategies.double_ma_strategy import DoubleMaStrategy
class BatchCTABackTest:
   """
   提供批量CTA策略回測(cè),輸出結(jié)果到excel或pdf,和CTA策略批量?jī)?yōu)化,輸出結(jié)果到excel或pdf,
   """
   def __init__(self, vtSymbolconfig="vtSymbol.json", exportpath=".\\"):
      """
      加載配置路徑
      """
      config = open(vtSymbolconfig)
      self.setting = json.load(config)
      self.exportpath = exportpath
   def addParameters(self, engine, vt_symbol: str, startDate, endDate, interval="1m", capital=1_000_000):
      """
      從vtSymbol.json文檔讀取品種的交易屬性,比如費(fèi)率,交易每跳,比率,滑點(diǎn)
      """
      if vt_symbol in self.setting:
         engine.set_parameters(
            vt_symbol=vt_symbol,
            interval=interval,
            start=startDate,
            end=endDate,
            rate=self.setting[vt_symbol]["rate"],
            slippage=self.setting[vt_symbol]["slippage"],
            size=self.setting[vt_symbol]["size"],
            pricetick=self.setting[vt_symbol]["pricetick"],
            capital=capital
         )
      else:
         print("symbol %s hasn't be maintained in config file" % vt_symbol)
      return engine
   def runBatchTest(self, strategy_setting, startDate, endDate, portfolio):
      """
      進(jìn)行回測(cè)
      """
      resultDf = DataFrame()
      dfportfolio = None
      for strategy_name, strategy_config in strategy_setting.items():
         engine = BacktestingEngine()
         vt_symbol = strategy_config["vt_symbol"]
         engine = self.addParameters(engine, vt_symbol, startDate, endDate)
         if type(strategy_config["setting"]) is str:
            print(strategy_config["setting"])
            engine.add_strategy(
               eval(strategy_config["class_name"]),
               json.loads(strategy_config["setting"], )
            )
         else:
            engine.add_strategy(
               eval(strategy_config["class_name"]),
               strategy_config["setting"]
            )
         engine.load_data()
         engine.run_backtesting()
         df = engine.calculate_result()
         if portfolio == True:
            if dfportfolio is None:
               dfportfolio = df
            else:
               dfportfolio = dfportfolio + df
         resultDict = engine.calculate_statistics(df, False)
         resultDict["class_name"] = strategy_config["class_name"]
         resultDict["setting"] = strategy_config["setting"]
         resultDict["vt_symbol"] = strategy_config["vt_symbol"]
         resultDf = resultDf.append(resultDict, ignore_index=True)
      if portfolio == True:
         # dfportfolio = dfportfolio.dropna()
         engine = BacktestingEngine()
         engine.calculate_statistics(dfportfolio)
         engine.show_chart(dfportfolio)
      return resultDf
   def runBatchTestJson(self, jsonpath="ctaStrategy.json", startDate=datetime(2019, 7, 1),
                        endDate=datetime(2020, 1, 1), exporpath=None, portfolio=True):
      """
      從ctaStrategy.json去讀交易策略和參數(shù),進(jìn)行回測(cè)
      """
      with open(jsonpath, mode="r", encoding="UTF-8") as f:
         strategy_setting = json.load(f)
      resultDf = self.runBatchTest(strategy_setting, startDate, endDate, portfolio)
      self.ResultExcel(resultDf, exporpath)
      return strategy_setting
   def runBatchTestExcecl(self, path="ctaStrategy.xls", startDate=datetime(2019, 7, 1),
                          endDate=datetime(2020, 1, 1), exporpath=None, portfolio=False):
      """
      從ctaStrategy.excel去讀交易策略和參數(shù),進(jìn)行回測(cè)
      """
      df = pd.read_excel(path)
      strategy_setting = df.to_dict(orient='index')
      resultDf = self.runBatchTest(strategy_setting, startDate, endDate, portfolio)
      self.ResultExcel(resultDf, exporpath)
      return strategy_setting
   def ResultExcel(self, result, export=None):
      """
      輸出交易結(jié)果到excel
      """
      if export != None:
         exportpath = export
      else:
         exportpath = self.exportpath
      try:
         path = exportpath + "CTABatch" + str(date.today()) + "v0.xls"
         result.to_excel(path, index=False)
         print("CTA Batch result is export to %s" % path)
      except:
         print(traceback.format_exc())
      return None
if __name__ == '__main__':
   bts = BatchCTABackTest()
   bts.runBatchTestJson()

最后可以去我的Github下載代碼,比較方便

https://github.com/BillyZhangGuoping/VNPY2_BILLY

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI