多股回測(backtrader+quantstats+akshare)

導包

#引入技術指標數據
from __future__ import (absolute_import ,division,print_function,unicode_literals)
import datetime #用于datetime對象操作
import os.path  #用于管理路徑
import sys      #用于在argvTo[0]中找到腳本名稱
import backtrader as bt #引入backtrader框架
%matplotlib inline

策略

#創建策略
class TestStrategy(bt.Strategy):params = (('maperiod1',5),('maperiod2',13),('maperiod3',21),('maperiod4',34),('maperiod5',55),('printlog',True),('poneplot' , False),#是否打印到同一張圖('pstake' , 100000) #單筆交易股票數據)def log(self,txt,dt=None,doprint = False):dt = dt or self.datas[0].datetime.date(0)#print('%s,%s' % (dt.isoformat(),txt))"""策略的日志函數"""if self.params.printlog or doprint:dt = dt or self.datas[0].datetime.date(0)print('%s,%s' % (dt.isoformat(),txt))def __init__(self):self.inds = dict()for i, d in enumerate(self.datas):self.inds[d] = dict()self.inds[d]['ma1'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod1)self.inds[d]['ma2'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod2)self.inds[d]['ma3'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod3)self.inds[d]['ma4'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod4)self.inds[d]['ma5'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod5)self.inds[d]['D1'] = bt.ind.CrossOver(self.inds[d]['ma5'],self.inds[d]['ma4']) #交叉信號self.inds[d]['A1'] = bt.ind.CrossOver(self.inds[d]['ma1'],self.inds[d]['ma2']) #交叉信號   self.inds[d]['C1'] = bt.ind.CrossOver(self.inds[d]['ma2'],self.inds[d]['ma3'])#跳過第一只股票data,第一只股票data作為主圖數據if i > 0:if self.p.poneplot:d.plotinfo.plotmaster = self.datas[0]def notify_trade(self,trade):if not trade.isclosed:returnself.log('OPERATION PROFIT,GROSS %.2F,NET %.2F' %(trade.pnl,trade.pnlcomm))#多股回測時使用,數據讀取。 def prenext(self):self.next()def next(self):# 獲取當天日期date = self.datas[0].datetime.date(0)# 獲取當天valuevalue = self.broker.getvalue()for i , d in enumerate(self.datas):            dt,dn = self.datetime.date(),d._name             #獲取時間及股票代碼        pos = self.getposition(d).size sig1 = ((self.inds[d]['D1'][-1]>0) and (self.inds[d]['A1'][0]>0)) and (self.inds[d]['ma2'][0] >self.inds[d]['ma4'][0])and (self.inds[d]['ma4'][0] >self.inds[d]['ma4'][-1])sig2 = ((self.inds[d]['D1'][-1]>0)  or (self.inds[d]['A1'][0]>0 ))and(self.inds[d]['ma2'][0] >self.inds[d]['ma2'][-1])and(d.close[0]/d.open[0]>1.05)and(d.volume[0] /d.volume[-1]>2)sig3 = ((self.inds[d]['D1'][-1]>0)  or (self.inds[d]['A1'][0]>0 ))and(self.inds[d]['ma2'][0] >self.inds[d]['ma3'][0] )and(self.inds[d]['ma3'][0] >self.inds[d]['ma4'][0] )and(self.inds[d]['ma4'][0] >self.inds[d]['ma4'][-1] )sig4 = self.inds[d]['C1'][0]<0#print('sig1',sig1)if not pos:                                      # 不在場內,則可以買入  vol成交量, ref日前if sig1 or sig2 and sig3: #如果金叉self.buy(data =d,size =self.p.pstake)    #買self.log('%s,BUY CREATE, %.2f ,%s' % (dt, d.close[0] ,d._name))#self.order = self.buy()elif sig4:              #在場內。且死叉self.close(data = d)                     #賣self.log('%s,SELL CREATE,%.2f,%s' % (dt, d.close[0] ,d._name))#self.order = self.sell()

印花稅

class stampDutyCommissionScheme(bt.CommInfoBase):params = (('stamp_duty',0.005),#印花稅率('percabs',True),)def _gotcommission(self,size,price,pseudoexec):if size >0:#買入,不考慮印花稅return size*price * self.p.commissionelif size<0:#賣出,考慮印花稅return -size*price*(self.p.stamp_duty + self.p.commission)else:return 0

開始回測

#創建cerebro實體
cerebro = bt.Cerebro()
#添加策略
cerebro.addstrategy(TestStrategy)

添加數據

#創建價格數據
import akshare as ak
import baostock as bs
import pandas as pd
import datetime#獲取股票池數據
from os import listdir
filename = listdir('D:/stock_data')
stk_pools = filenamefor i in stk_pools[:]:try:datapath = 'D:/stock_data/'+idf = pd.read_csv('D:/stock_data/'+i)#將數據長度不足的股票刪去if len(df)<55:passelse:try:data = bt.feeds.GenericCSVData(dataname = datapath,fromdate = datetime.datetime(2010,4,1),todate = datetime.datetime(2021,7,8),nullvalue = 0.0,dtformat = ('%Y-%m-%d'),datetime = 1,open =2,high = 3,low = 4,close = 5,volume = 6,openinterest = -1)cerebro.adddata(data,name = i)except:continue except:continue

?設置參數

#設置啟動資金
cerebro.broker.setcash(len(stk_pools[:50])*10000)
#設置交易單位大小
cerebro.addsizer(bt.sizers.FixedSize,stake = 100)
#設置傭金為千分之一
comminfo = stampDutyCommissionScheme(stamp_duty=0.005,commission=0.001)
cerebro.broker.addcommissioninfo(comminfo)
#不顯示曲線
for d in cerebro.datas:d.plotinfo.plot = False
#打印開始信息
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

回測數據分析

#查看策略效果
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
back  = cerebro.run(maxcpus=12,exactbars=True,stdstats=False)import warnings
warnings.filterwarnings('ignore')
strat = back[0]
portfolio_stats = strat.analyzers.getbyname('pyfolio')
returns, positions, transactions, gross_lev = portfolio_stats.get_pf_items()
returns.index = returns.index.tz_convert(None)import quantstats
quantstats.reports.html(returns, output='stats.html', title='Stock Sentiment')import webbrowser
f = webbrowser.open('stats.html')
#打印最后結果
print('Final Profolio Value : %.2f' %cerebro.broker.getvalue())

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449778.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449778.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449778.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Cron表達式、定時任務

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Cron表達式。但這個表示式本身就夠復雜了。下面會有說明。 例子&#xff1a; cronSchedule("0 0/2 8-17 * * ?") // 每天8:0…

【轉載】ASP.NET自定義404和500錯誤頁面

在ASP.NET網站項目實際上線運行的過程中&#xff0c;有時候在運行環境下會出現400錯誤或者500錯誤&#xff0c;這些錯誤默認的頁面都不友好&#xff0c;比較簡單單調&#xff0c;其實我們可以自行設置這些錯誤所對應的頁面&#xff0c;讓這些錯誤跳轉到我們指定的路徑。此文將介…

年薪15萬的80后小本科:只要6分鐘,告訴你少走6年彎路

這個社會是很殘酷的&#xff0c;尤其是對于那些剛剛步入社會的80后而言。當很多人都在抱怨這個社會競爭壓力太大、沒有自己的追求&#xff0c;并因此而喪失斗志的時候&#xff0c;一個年薪15W的80后小本卻發出了這個的感慨&#xff0c;“一個人的成就&#xff0c;與歲月無關&am…

Google Go Programming In Eclipse

http://www.tutorialsavvy.com/2013/04/google-go-programming-in-eclipse.html/ Google Go Programming In Eclipse The new “Go” programming language is from Google co.It has many features better then other languages.Go language features are:-– High Speed Comp…

pycharm打開ipynb顯示為文本格式解決辦法

然后進入 添加類型 jupyter notebook 然后下方添加 *.ipynb

quartz各版本MySQL數據庫存儲建表SQL語句

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 用quartz管理任務計劃很方便&#xff0c;但是當使用數據庫作為存儲介質的時候&#xff0c;必須要先創建表&#xff0c;不然就會報錯。1.…

[基礎篇]ESP32-RTOS-SDK教程(一)之Windows環境搭建

當下正是物聯網最好的時代&#xff0c;學習新的技術怎么能只學習ESP8266呢&#xff1f;要知道ESP8266還有一個孿生兄弟呢&#xff0c;最重要的是這個孿生兄弟要比ESP8266是更厲害的&#xff0c;所以我們也是非常有必要學習一下的&#xff0c;其實這篇文章去年就已經寫了&#x…

對話Linus Torvalds:大多黑客甚至連指針都未理解

摘要&#xff1a;Linus Torvalds坦言那些狡詐的通過文件名查找高速緩存&#xff0c;然后又抱怨自己能力一般的內核“惡魔”才是他欣賞的&#xff1b;相反&#xff0c;很多人連低水平的內核編程都還沒學好。 幾周前&#xff0c; Linus Torvalds在Slashdot上回答了一些問題。其中…

總結學習(提綱)

之前在私募做期權量化學習了那么久&#xff0c;趁著畢業找工作這段時間&#xff0c;對之前學習的東西&#xff0c;制作的函數等進行一個系統性的總結&#xff0c;順便每天更新的時候&#xff0c;記錄下自己的體重與波比跳次數。 1.MC的學習與策略編寫 2.python基礎學習資料的…

安卓系統上的遠程 JS 調試 Remote JavaScript Debugging on Android

每當在 Android 移動設備上調試網頁時&#xff0c;開發人員往往都會不自覺陷入調試的泥潭中去。《Android開發指南》提供了一個解決方案&#xff0c;卻有點繁瑣復雜。因此&#xff0c;許多 Web 開發人員會傾向于使用類似 Firefox Firebug 的或像 WebKit 的 Web Inspector 之類的…

js關于表單校驗完善

<!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>注冊頁面</title> <style type"text/css"> .left{ width: 100px; …

Python高效編程技巧

摘要&#xff1a;作者有多年的Python編程經驗&#xff0c;并且有很多的編程小技巧和知識&#xff0c;其中大多數是通過閱讀很流行的開源軟件&#xff0c;如Django, Flask, Requests中獲得的。 我已經使用Python編程有多年了&#xff0c;即使今天我仍然驚奇于這種語言所能讓代碼…

quartz 任務調試 建表 sql 語句、create table語句

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; DROP TABLE IF EXISTS QRTZ_SCHEDUL…

關于ttk的使用與安裝

ttk是tkinter中的子模塊&#xff0c;在python2.x中是作為獨立模塊。但是在python3.x中則是成為了tkinter的子模塊&#xff0c;因此調用時&#xff0c;轉變為 from Tkinter import ttk

SEO藝術

SEO藝術 編輯推薦 在本書中&#xff0c;四位搜索引擎優化&#xff08;SEO&#xff09;領域最受矚目的專家闡述了制訂以及執行一個完善的SEO策略時應遵循的一些實用指南與最新技術。 基本信息 原書名&#xff1a; The Art of SEO原出版社&#xff1a; OReilly作者&#xff1a; (…

ActiveMQ支持的傳輸協議

連接到ActiveMQ Connector:ActiveMQ提供的&#xff0c;用來實現連接通信的功能。包括:client-to-broker、broker-to-broker。ActiveMQ允許客戶端使用多種協議來進行連接。 client-to-broker模式一般是配置文件中的transportConnector配置 broker-to-broker:一般是指網絡(networ…

http狀態碼301和302詳解及區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一直對http狀態碼301和302的理解比較模糊&#xff0c;在遇到實際的問題和翻閱各種資料了解后&#xff0c;算是有了一定的理解。這里記錄下…

哪些編程語言需要修復?

摘要&#xff1a;編程語言有十全十美的嗎&#xff1f;每種語言都有缺陷嗎&#xff1f;這不&#xff0c;Java、C、C、Python都中槍了。語言之間也可相互“掐架”&#xff0c;一起來看下。 原文作者Kevin Kelleher采用一種比較新穎的方式來比較編程語言&#xff1a;即描述每個編程…

時間修改,學習

設定時間格式 import datetime print datetime.datetime.now().strftime("%Y-%m-%d %H:%M") # 2018-05-08 16:54 時間增加 import datetime print (datetime.datetime.now()datetime.timedelta(days1)).strftime("%Y-%m-%d %H:%M:%S") days改為hours m…

Python標準庫

《Python標準庫》基本信息原書名&#xff1a; The Python Standard Library by Example 原出版社&#xff1a; Pearson Education 作者&#xff1a; (美)Doug Hellmann 譯者&#xff1a; 劉熾 出版社&#xff1a;機械工業出版社 ISBN&#xff1a;9787111378105上架時間&#xf…