利用VNPY回測引擎分析實盤交易,并用excel和pdf輸出分析結(jié)果-創(chuàng)新互聯(lián)

算是之前一篇文章的后續(xù)

我們提供的服務(wù)有:網(wǎng)站設(shè)計制作、做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、徽州ssl等。為千余家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的徽州網(wǎng)站制作公司

http://blog.itpub.net/22259926/viewspace-2564798/

之前寫了一篇文章,在實盤交易時候,用數(shù)據(jù)庫記錄交易信息,其實就是把交易信息類型VtTradeData的實例保存的到數(shù)據(jù)庫中。

之前盤后分析主要是數(shù)據(jù)庫把collection導(dǎo)出到csv文檔,然后下載本地用excel分析,拼湊出sharpe指標(biāo),趨勢圖一些;費(fèi)時費(fèi)力還不準(zhǔn)確;只能說近似正確。

一直想找個什么分析工具,后來一想,其實VNPY回測引擎就很不錯,簡單易用;就是搗鼓搗鼓,利用VNPY回測引擎分析實盤交易,并用excel和pdf輸出分析結(jié)果。

這里所有代碼還是針對VNPY 1.92的,因為現(xiàn)在我的實盤還是這個版本,如果VNPY2的版本,其實應(yīng)該改改也可以用。

完整代碼如下,只要保存到一個本地路徑,執(zhí)行就可以。

整個流程是:

1. 使用方法load_tradedata,傳入交易記錄數(shù)據(jù)庫信息,和collection名稱,讀取交易信息,保存為OrderDict格式

2. 使用initEngine4Deal,初始化一個回測引擎,傳入品種交易參數(shù),比如手續(xù)費(fèi)一類,進(jìn)行更完善計算,滑點可以為0,因為是真實成交數(shù)據(jù); 這里還要提供歷史品種行情數(shù)據(jù),為按日結(jié)算提供參考;同時使用真實歷史交易信息Dict,替換本來是回測生成的交易信息tradeDict,這個也是核心步驟。

3.然后用回測引擎的按比分析方法,和按日分析方法分析;把分析結(jié)果用Dict保存;轉(zhuǎn)為excel輸出;圖像plt用pdf輸出。這里有個中文亂碼問題,比較討厭,可以搜索看看解決方法。

完成后截圖下如,

Excel做了行列轉(zhuǎn)換,方便查看

利用VNPY回測引擎分析實盤交易,并用excel和pdf輸出分析結(jié)果

利用VNPY回測引擎分析實盤交易,并用excel和pdf輸出分析結(jié)果

大部分注釋都解釋了。有幾點要介紹下,代碼如下:

傳入的是用list包Dict的格式,大部分都注釋解釋了。

# encoding: UTF-8
"""
從DEAL數(shù)據(jù)庫中讀取交易記錄,利用回測分析引擎分析,并用excel和pdf輸出分析結(jié)果
"""
from __future__ import division
from __future__ import print_function
from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine, MINUTE_DB_NAME
from vnpy.trader.vtObject import VtTickData, VtBarData
from vnpy.trader.vtGateway import VtTradeData
from vnpy.trader.vtGlobal import globalSetting
import pymongo
from collections import OrderedDict
from datetime import datetime,date
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
def load_tradedata(dbName, collectionName, startDate):
   """
   讀取交易歷史記錄,返回用OrderedDict保存的VtTradeData
   :param dbName:
   :param collectionName:
   :return: {ID:VtTradeData}
   """
   dbClient = pymongo.MongoClient(globalSetting['mongoHost'], globalSetting['mongoPort'])
   collection = dbClient[dbName][collectionName]
   # 載入初始化需要用的數(shù)據(jù)
   flt = {}
   initCursor = collection.find(flt).sort('tradeTime')
   tradeDict = OrderedDict() # 交易記錄字典
   tradeDictID = 0 # 交易編號
   for d in initCursor:
      trade = VtTradeData()
      trade.__dict__ = d
      trade.tradeTime = datetime.strptime(trade.tradeTime, '%Y-%m-%d %H:%M:%S')
      trade.dt = trade.tradeTime
      tradeDictID += 1  # 成交編號自增1
      tradeDict[str(tradeDictID)] = trade
   return tradeDict
def initEngine4Deal(dealCollection,historyCollection,startDate,tradeRate,tradeSize,tradePriceTick,tradeSlipe = 0,
                       tradeCapital = 50000):
   """
   傳入?yún)?shù),返回回測引擎,保護(hù)實際交易數(shù)據(jù),用來分析交易情況,。
   :param dealCollection:
   :param historyCollection:
   :param startDate:
   :param tradeSlipe:
   :param tradeRate:
   :param tradeSize:
   :param tradePriceTick:
   :param tradeCapital:
   :param exportPDF:
   :return:
   """
   # 創(chuàng)建回測引擎對象
   engine = BacktestingEngine()
   # 設(shè)置回測使用的數(shù)據(jù)
   engine.setBacktestingMode(engine.BAR_MODE)  # 設(shè)置引擎的回測模式為K線
   engine.setDatabase(MINUTE_DB_NAME, historyCollection)  # 設(shè)置使用的歷史數(shù)據(jù)庫
   engine.setStartDate(startDate)  # 設(shè)置回測用的數(shù)據(jù)起始日期
   # 配置回測引擎參數(shù)
   engine.setSlippage(tradeSlipe)  # 設(shè)置滑點為1跳
   engine.setRate(tradeRate)  # 設(shè)置手續(xù)費(fèi)萬1
   engine.setSize(tradeSize)  # 設(shè)置合約大小
   engine.setPriceTick(tradePriceTick)  # 設(shè)置最小價格變動
   engine.setCapital(tradeCapital)  # 設(shè)置回測本金
   engine.loadHistoryData()
   bar = None
   for d in engine.dbCursor:
      data = VtBarData()
      data.__dict__ = d
      engine.updateDailyClose(data.datetime, data.close)
      bar = data
   # # 構(gòu)建每日收盤價
   # for bar in engine.BackTestData:
   #  engine.updateDailyClose(bar.datetime, bar.close)
   # 是回測數(shù)據(jù)后一個bar,用于未結(jié)束持倉計算收益
   engine.bar = bar
   #  讀取歷史交易數(shù)據(jù),塞入回測引擎
   tradeDict = load_tradedata("VnTrader_DEAL_Db",dealCollection,startDate)
   engine.tradeDict = tradeDict
   # 顯示成交記錄
   # for i in range(len(tradeDict)):
   #  d = engine.tradeDict[str(i + 1)].__dict__
   #  print('TradeID: %s, Time: %s, Direction: %s, Price: %s, Volume: %s' % (
   #  d['tradeID'], d['dt'], d['direction'], d['price'], d['volume']))
   return engine
def tradeResultAnalysis(engine,dealCollection):
   """
   傳入回測引擎,和deal名稱,按deal進(jìn)行回測分析,返回回測分析結(jié)果DICT格式,和plt圖標(biāo)用于pdf輸出
   :param engine:
   :param dealCollection:
   :return:
   """
   TradeResult = {}
   d = engine.calculateBacktestingResult()
   TradeResult[u"第一筆交易/FirstDeal"] =  d['timeList'][0]
   TradeResult[u"最后一筆交易/LastDeal"] = d['timeList'][-1]
   TradeResult[u"總交易次數(shù)/DealNumber"] = (d['totalResult'])
   TradeResult[u"總盈虧/DealPnL"] = (d['capital'])
   TradeResult[u"大回撤/MaxDrawdown"] = (min(d['drawdownList']))
   TradeResult[u"平均每筆盈利/AveragePnL"] = (d['capital'] / d['totalResult'])
   TradeResult[u"平均每筆滑點/AverageSlip"] = (d['totalSlippage'] / d['totalResult'])
   TradeResult[u"平均每筆傭金/AverageCommisson"] = (d['totalCommission'] / d['totalResult'])
   TradeResult[u"勝率/WinRate%"] =(d['winningRate'])
   TradeResult[u"盈利交易平均值/AverageProfit"] = (d['averageWinning'])
   TradeResult[u"虧損交易平均值/AverageLoss"] = (d['averageLosing'])
   TradeResult[u"盈虧比/ProfitLossRatio"] = (d['profitLossRatio'])
   plt = tradeResult2Plt(d,TradeResult,dealCollection)
   return TradeResult, plt
def dailyResultAnalysis(engine, dealCollection):
   """
   傳入回測引擎,和deal名稱,按每日進(jìn)行回測分析,返回回測分析結(jié)果DICT格式,和plt圖標(biāo)用于pdf輸出
   :param engine:
   :param dealCollection:
   :return:
   """
   engine.calculateDailyResult()
   dx, dailyResult = engine.calculateDailyStatistics()
   plt = dailyResult2Plt(dx, dailyResult, dealCollection)
   return dailyResult,plt
def tradeResult2Plt(d,TradeResult,dealCollection):
   # 輸出按交易統(tǒng)計 plt 圖標(biāo)
   # 繪圖
   fig = plt.figure(figsize=(10, 18))
   pText = plt.subplot(5, 1, 1)
   pText.set_title("TradeResultAnalysis " + dealCollection)
   pText.text(0,0.1,str(TradeResult),fontsize=12, bbox={'facecolor':'white'},wrap=True)
   pCapital = plt.subplot(5, 1, 2)
   pCapital.set_ylabel("capital")
   pCapital.plot(d['capitalList'], color='r', lw=0.8)
   pDD = plt.subplot(5, 1, 3)
   pDD.set_ylabel("DD")
   pDD.bar(range(len(d['drawdownList'])), d['drawdownList'], color='g')
   pPnl = plt.subplot(5, 1, 4)
   pPnl.set_ylabel("pnl")
   pPnl.hist(d['pnlList'], bins=50, color='c')
   pPos = plt.subplot(5, 1, 5)
   pPos.set_ylabel("Position")
   if d['posList'][-1] == 0:
      del d['posList'][-1]
   tradeTimeIndex = [item.strftime("%m/%d %H:%M:%S") for item in d['tradeTimeList']]
   xindex = np.arange(0, len(tradeTimeIndex), np.int(len(tradeTimeIndex) / 10))
   tradeTimeIndex = list(map(lambda i: tradeTimeIndex[i], xindex))
   pPos.plot(d['posList'], color='k', drawstyle='steps-pre')
   pPos.set_ylim(-1.2, 1.2)
   plt.sca(pPos)
   # plt.rcParams['font.sans-serif'] = ['SimSun']  # 用來正常顯示中文標(biāo)簽
   plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負(fù)號
   plt.tight_layout()
   plt.xticks(xindex, tradeTimeIndex, rotation=30)  # 旋轉(zhuǎn)15
   return plt
def dailyResult2Plt(d, dailyResult,dealCollection):
   # 繪圖
   fig = plt.figure(figsize=(10, 18))
   pText = plt.subplot(5, 1, 1)
   pText.set_title("DailyResultAnalysis " + dealCollection)
   pText.text(0,0.1,str(dailyResult),fontsize=12 , bbox={'facecolor':'white'},wrap=True)
   pBalance = plt.subplot(5, 1, 2)
   pBalance.set_title('Balance')
   plt.plot(d['date'], d['balance'])
   pDrawdown = plt.subplot(5, 1, 3)
   pDrawdown.set_title('Drawdown')
   pDrawdown.fill_between(range(len(d['drawdown'])), d['drawdown'])
   pPnl = plt.subplot(5, 1, 4)
   pPnl.set_title('Daily Pnl')
   plt.bar(range(len(d['drawdown'])), d['netPnl'])
   pKDE = plt.subplot(5, 1, 5)
   pKDE.set_title('Daily Pnl Distribution')
   plt.hist(d['netPnl'], bins=50)
   return plt
def toExcel(resultlist, path="C:\data\datframe.xlsx"):
   # 按照輸入統(tǒng)計數(shù)據(jù)隊列和路徑,輸出excel,這里不提供新增模式,如果想,可以改
   # dft.to_csv(path,index=False,header=True, mode = 'a')
   summayKey = resultlist[0].keys()
   df = pd.DataFrame(columns=summayKey)
   for result in resultlist:
      new = pd.DataFrame(result, index=["0"])
      df = df.append(new, ignore_index=True,sort=True)
   dft = pd.DataFrame(df.values.T, index=df.columns, columns=df["DealCollection"])
   dft.to_excel(path, index=True, header=True)
   print("回測統(tǒng)計結(jié)果輸出到" + path)
if __name__ == "__main__":
   DealCollectionList = [
      {
         "historyCollection": "rb9999",
         "dealCollection": "ATRStrategy RB",
         "StartDate": "20200301",
         "Size": 10,
         "Rate": 0.0001,
         "PriceTick":1
      },
      {
         "historyCollection": "fu8888",
         "dealCollection": "CCIStrategy fu",
         "StartDate": "20200301",
         "Size": 10,
         "Rate": 0.0001,
         "PriceTick": 1
      },
   ]
   resultList = []
   pdf = PdfPages("DealResultAnalysisPDF" + str(date.today())+ "v1.pdf")
   for dealCollction in DealCollectionList:
      ResultDict = {}
      # 加入交易集名稱
      dealCollctionName = dealCollction["dealCollection"]
      ResultDict["DealCollection"] = dealCollctionName
      # 初始回測引擎
      engine = initEngine4Deal(
         dealCollection = dealCollction["dealCollection"],
         historyCollection = dealCollction["historyCollection"],
         startDate = dealCollction["StartDate"],
         tradeSize = dealCollction["Size"],
         tradeRate =  dealCollction["Rate"],
         tradePriceTick = dealCollction["PriceTick"]
      )
      # 按deal進(jìn)行分析,傳入resultDict,和pdf
      tradeResult,plt=tradeResultAnalysis(engine,dealCollctionName)
      ResultDict.update(tradeResult)
      pdf.savefig()
      plt.close()
      # 按每日進(jìn)行分析,傳入resultDict,和pdf
      dailyResult,plt= dailyResultAnalysis(engine,dealCollctionName)
      ResultDict.update(dailyResult)
      pdf.savefig()
      plt.close()
      resultList.append(ResultDict)
   pdf.close()
   path = "DealResultAnalysisExcel" + str(date.today()) + "v2.xls"
   toExcel(resultList, path)

網(wǎng)站名稱:利用VNPY回測引擎分析實盤交易,并用excel和pdf輸出分析結(jié)果-創(chuàng)新互聯(lián)
文章鏈接:http://bm7419.com/article2/dichic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、Google、網(wǎng)站設(shè)計、小程序開發(fā)移動網(wǎng)站建設(shè)、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)