python多程式簡介,和VNPY多程式引數優化程式碼分析
之前為了實現利用遺傳演算法,進行多程式策略的優化,學習研究了python的多程式庫Multiprocessing。以前感覺真是黑科技,學習後發現,還是python優點,簡單好用,對於一般應用還是很好理解。
首先,由於GIL(全域性解釋鎖)的問題,全域性物件只能一個程式呼叫,python多執行緒並不能充分利用多核處理器,比如有時候用pandas跑大型資料分析,發現只有一核在累死累活。如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多程式。multiprocessing可以給每個程式賦予單獨的Python直譯器,這樣就規避了全域性解釋鎖所帶來的問題。可以理解為多核CPU分配好一個工作任務,這個工作任務包括工作方法和工作內容。
其實python多執行緒很簡單,相對於其他語言來說。其實簡單就是針對需要多執行緒的方法func(a),a是引數。相當於工作內容;使用 Multiprocessing. Process(target = func, args =(a,)),建立一個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多程式優化方法。其實很好理解了,runParallelOptimization是類BacktestingEngine的一個方法。
傳入引數strategyClass就是這個策略類,setting是要優化引數範圍,後面通過optimizationSetting.generateSetting()生成策略引數佇列,做為任務內容;optimizationSetting.optimizeTarget是後面返回值。至於回測品種,回測時間段,交易費用什麼,在 BacktestingEngine建立時候維護了。
然後建立任務池pool,大小剛好是cpu核數,這個也是比較穩妥設定。
之後做一個l佇列來放返回值。
然後打包策略類,回測引數,策略引數做為任務內容,和任務方法optimize一起組合為一個工作任務。然後插入任務池給cpu核心去跑。這個時候在系統監視器可以看到於核心數相同的python虛擬環境運作。
然後就是對返回值排序。後面詳細說說。
df = engine.runParallelOptimization(AtrRsiStrategy, setting) def runParallelOptimization(self, strategyClass, optimizationSetting): """並行優化引數""" # 獲取優化設定 settingList = optimizationSetting.generateSetting() targetName = optimizationSetting.optimizeTarget # 檢查引數設定問題 if not settingList or not targetName: self.output(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環境在跑任務。
這裡會發現是用靜態方法optimize,如果直接呼叫 BacktestingEngine的回測方法更簡潔,為什麼沒有呢,這個是python2.7的Multiprocessing的一個侷限,只能打包靜態方法做為工作方法,如果打包類中的方法,會提示錯誤。
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup builtin .instanceme
如果VNPY2.0基於python3.6版本,應該就會更簡化一些。
下面看看 靜態方法 optimize,其實沒什麼好說,就是新建一個回測引擎BacktestingEngine物件,按照引數跑一遍回測,返回一個元祖,包含了這次回測的引數,針對回測目標的值,和一個包含回測結果的字典,這個字典包括什麼年化收入,sharpe等一堆回測結果。
然後所有的回測結果元祖組成一個回測結果佇列,這個結果佇列按照targetValue反向排序,最大放在第一位。
因為太多了,一般我都是輸出到excel裡面,之前說過怎麼實現。
#---------------------------------------------------------------------- def optimize(strategyClass, setting, targetName, mode, startDate, initDays, endDate, slippage, rate, size, priceTick, dbName, symbol): """多程式優化時跑在每個程式中執行的函式""" 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不算複雜,但是用在回測上效果很好;現在有了遺傳演算法,進行策略優化更加方便了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2641959/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用策略模式優化過多 if else 程式碼模式優化
- Python多程式Python
- Python的多程式和多執行緒Python執行緒
- Python多工程式設計介紹Python程式設計
- 優化If else(簡化程式碼)優化
- 程式碼優化-多型代替IF條件判斷優化多型
- [python] 多程式程式設計Python程式設計
- Python多程式程式設計Python程式設計
- python 多程式和多執行緒學習Python執行緒
- python使用多程式Python
- jscodeshift入門簡介&程式碼重構&程式碼分析&&ReactJSReact
- python:python的多程式Python
- Python 多執行緒多程式Python執行緒
- python爬蟲之多執行緒、多程式+程式碼示例Python爬蟲執行緒
- Python中的多程式Python
- python多程式基礎Python
- python---多工程式Python
- VNPY 批量優化引數,並輸出到excel優化Excel
- linux 程式引數檔案 /proc/pid/cmdline 簡介Linux
- Python 程式碼的效能優化之道Python優化
- 小程式內引數和掃碼引數統一
- 程式碼優化優化
- 入門python多執行緒/多程式Python執行緒
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化
- python獲取命令列引數的程式碼Python命令列
- 優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程式元件化框架-ModularizationArchitecture框架原始碼解耦元件化
- python基礎1 - 多檔案專案和程式碼規範Python
- python多程式取代多執行緒的探究Python執行緒
- [譯] Python 的多執行緒與多程式Python執行緒
- Bash 和 Python 程式語言優缺點分析Python
- javaScript程式碼優化JavaScript優化
- 帶引數的 Python 裝飾器讓你的程式碼更優雅Python
- Python多程式之分享(multiprocessing包)Python
- Python的多工程式設計Python程式設計
- Python學習筆記 - 多程式Python筆記
- python中socket+multiprocessing多程式Python
- Python 多執行緒及程式Python執行緒
- Python——程式、執行緒、協程、多程式、多執行緒(個人向)Python執行緒