這篇文章主要講解了“python多進程和VNPY多進程參數優(yōu)化舉例分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“python多進程和VNPY多進程參數優(yōu)化舉例分析”吧!
創(chuàng)新互聯(lián)公司專注于雁江企業(yè)網站建設,成都響應式網站建設公司,商城網站開發(fā)。雁江網站建設公司,為雁江等地區(qū)提供建站服務。全流程按需網站設計,專業(yè)設計,全程項目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務首先,由于GIL(全局解釋鎖)的問題,全局對象只能一個進程調用,python多線程并不能充分利用多核處理器,比如有時候用pandas跑大型數據分析,發(fā)現只有一核在累死累活。如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。multiprocessing可以給每個進程賦予單獨的Python解釋器,這樣就規(guī)避了全局解釋鎖所帶來的問題??梢岳斫鉃槎嗪薈PU分配好一個工作任務,這個工作任務包括工作方法和工作內容。
其實python多線程很簡單,相對于其他語言來說。其實簡單就是針對需要多線程的方法func(a),a是參數。相當于工作內容;使用Multiprocessing.Process(target = func, args =(a,)),創(chuàng)建一個Prcoess對象,也就是工作任務,再啟動這個對象,這樣一個多進程任務就完成了。等CPU分配一個獨立核去干活,func(a)就開動了。這里唯一要注意args是默認輸入元祖參數。
P = Multiprocessing.Process(target = func, args =(a,)) P.start()
Multiprocessing提供了更簡潔的pool做為進程池,其實叫任務池更為恰當。把需要干的工作任務打包好,放在這個池子里面,這樣空閑下來的核心就撿pool的任務干活。
常見的pool的使用如下,其中prcesses = 4 是定義任務池大小,不一定要小于或者等于cpu核心數量,可以大于cpu核心數量,不過這樣就有幾個任務空掛著還占用內存。
然后使用pool方法apply_async(task, args=(x,)),把打包好的任務插入池中。apply_asyncs是異步的帶返回值。如果用apply也可以正常,但是會沒有返回值,此處不仔細研究了。
之后close()是把這個任務池關閉,不再接受新的任務;但是還有一些已有任務在跑,所以用pool.join(),吊著主程序,直到所有任務完成才進入下一步。
if __name__ == '__main__': Multiprocessing.pool = Pool(processes=4) for x in range(10): pool.apply_async(task, args=(x,)) pool.close() pool.join()
下面看看VNPY多進程優(yōu)化方法。其實很好理解了,runParallelOptimization是類BacktestingEngine的一個方法。
傳入參數strategyClass就是這個策略類,setting是要優(yōu)化參數范圍,后面通過optimizationSetting.generateSetting()生成策略參數隊列,做為任務內容;optimizationSetting.optimizeTarget是后面返回值。至于回測品種,回測時間段,交易費用什么,在BacktestingEngine創(chuàng)建時候維護了。
然后創(chuàng)建任務池pool,大小剛好是cpu核數,這個也是比較穩(wěn)妥設置。
之后做一個l隊列來放返回值。
然后打包策略類,回測參數,策略參數做為任務內容,和任務方法optimize一起組合為一個工作任務。然后插入任務池給cpu核心去跑。這個時候在系統(tǒng)監(jiān)視器可以看到于核心數相同的python虛擬環(huán)境運作。
然后就是對返回值排序。后面詳細說說。
df = engine.runParallelOptimization(AtrRsiStrategy, setting) def runParallelOptimization(self, strategyClass, optimizationSetting): """并行優(yōu)化參數""" # 獲取優(yōu)化設置 settingList = optimizationSetting.generateSetting() targetName = optimizationSetting.optimizeTarget # 檢查參數設置問題 if not settingList or not targetName: self.output(u'優(yōu)化設置有問題,請檢查') # 多進程優(yōu)化,啟動一個對應CPU核心數量的進程池 pool = multiprocessing.Pool(multiprocessing.cpu_count()) l = [] for setting in settingList: l.append(pool.apply_async(optimize, (strategyClass, setting, targetName, self.mode, self.startDate, self.initDays, self.endDate, self.slippage, self.rate, self.size, self.priceTick, self.dbName, self.symbol))) pool.close() pool.join() # 顯示結果 resultList = [res.get() for res in l] resultList.sort(reverse=True, key=lambda result:result[1]) return resultList
像現在雙核四線程就有四個python環(huán)境在跑任務。
這里會發(fā)現是用靜態(tài)方法optimize,如果直接調用BacktestingEngine的回測方法更簡潔,為什么沒有呢,這個是python2.7的Multiprocessing的一個局限,只能打包靜態(tài)方法做為工作方法,如果打包類中的方法,會提示錯誤。
cPickle.PicklingError: Can't pickle
如果VNPY2.0基于python3.6版本,應該就會更簡化一些。
下面看看靜態(tài)方法optimize,其實沒什么好說,就是新建一個回測引擎BacktestingEngine對象,按照參數跑一遍回測,返回一個元祖,包含了這次回測的參數,針對回測目標的值,和一個包含回測結果的字典,這個字典包括什么年化收入,sharpe等一堆回測結果。
然后所有的回測結果元祖組成一個回測結果隊列,這個結果隊列按照targetValue反向排序,大放在第一位。
因為太多了,一般我都是輸出到excel里面,之前說過怎么實現。
#---------------------------------------------------------------------- def optimize(strategyClass, setting, targetName, mode, startDate, initDays, endDate, slippage, rate, size, priceTick, dbName, symbol): """多進程優(yōu)化時跑在每個進程中運行的函數""" engine = BacktestingEngine() engine.setBacktestingMode(mode) engine.setStartDate(startDate, initDays) engine.setEndDate(endDate) engine.setSlippage(slippage) engine.setRate(rate) engine.setSize(size) engine.setPriceTick(priceTick) engine.setDatabase(dbName, symbol) engine.initStrategy(strategyClass, setting) engine.runBacktesting() engine.calculateDailyResult() d, result = engine.calculateDailyStatistics() try: targetValue = result[targetName] except KeyError: targetValue = 0 return (str(setting), targetValue, result)
其實python的多進程庫Multiprocessing不算復雜,但是用在回測上效果很好;現在有了遺傳算法,進行策略優(yōu)化更加方便了。
感謝各位的閱讀,以上就是“python多進程和VNPY多進程參數優(yōu)化舉例分析”的內容了,經過本文的學習后,相信大家對python多進程和VNPY多進程參數優(yōu)化舉例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!