backtrader數據基礎

cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy2)
codes=['600862.SH','300326.SZ','300394.SZ']
#加載最近兩日交易數據
for code in codes:feed = Addmoredata(dataname = get_data(code,'20200506'),name=code)cerebro.adddata(feed)
cerebro.run()

數據查看:

class TestStrategy(bt.Strategy):def __init__(self):# 打印數據集和數據集對應的名稱print("-------------self.datas-------------")print(self.datas)print("-------------self.data-------------")print(self.data._name, self.data) # 返回第一個導入的數據表格,縮寫形式print("-------------self.data0-------------")print(self.data0._name, self.data0) # 返回第一個導入的數據表格,縮寫形式print("-------------self.datas[0]-------------")print(self.datas[0]._name, self.datas[0]) # 返回第一個導入的數據表格,常規形式print("-------------self.datas[1]-------------")print(self.datas[1]._name, self.datas[1]) # 返回第二個導入的數據表格,常規形式print("-------------self.datas[-1]-------------")print(self.datas[-1]._name, self.datas[-1]) # 返回最后一個導入的數據表格print("-------------self.datas[-2]-------------")print(self.datas[-2]._name, self.datas[-2]) # 返回倒數第二個導入的數據表格
data1 = pd.read_csv('111.csv')      
cerebro = bt.Cerebro()
st_date = datetime.datetime(2019,1,2)
ed_date = datetime.datetime(2021,1,28)
# 添加 600466.SH 的行情數據
datafeed1 = bt.feeds.PandasData(dataname=data1, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed1, name='600466.SH')
# 添加 603228.SH 的行情數據
datafeed2 = bt.feeds.PandasData(dataname=data2, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed2, name='603228.SH')
cerebro.addstrategy(TestStrategy)
rasult = cerebro.run()
# 訪問第一個數據集的 close 線
self.data.lines.close # 可省略 lines 簡寫成:self.data.close
self.data.lines_close # 可省略 lines 簡寫成:self.data_close
# 訪問第二個數據集的 open 線
self.data1.lines.close # 可省略 lines 簡寫成:self.data1.close
self.data1.lines_close # 可省略 lines 簡寫成:self.data1_close
# 注:只有從 self.datas 調用 line 時可以省略 lines,調用 indicators 中的 line 時不能省略

獲取數據方法:

如果你能清楚的記住數據表格中每條線的位置,也可以通過索引位置(整數)來訪問,同樣支持簡寫形式:
1、完整形式:self.datas[X].lines[Y];

2、簡寫形式:self.dataX.lines[Y]、self.dataX_Y;

3、說明:X 對應單個數據表格在數據表格集合中的索引位置,Y 對應某條線在數據表格中的索引位置 。

class TestStrategy(bt.Strategy):def __init__(self):print("--------- 打印 self 策略本身的 lines ----------")print(self.lines.getlinealiases())print("--------- 打印 self.datas 第一個數據表格的 lines ----------")print(self.datas[0].lines.getlinealiases())# 計算第一個數據集的s收盤價的20日均線,返回一個 Data feedself.sma = bt.indicators.SimpleMovingAverage(self.datas[0].close, period=20)print("--------- 打印 indicators 對象的 lines ----------")print(self.sma.lines.getlinealiases())print("---------- 直接打印 indicators 對象的所有 lines -------------")print(self.sma.lines) print("---------- 直接打印 indicators 對象的第一條 lines -------------")print(self.sma.lines[0])def next(self):print('驗證索引位置為 6 的線是不是 datetime')print(bt.num2date(self.datas[0].lines[6][0]))# num2date() 作用是將數字形式的時間轉為 date 形式cerebro = bt.Cerebro()
st_date = datetime.datetime(2019,1,2)
ed_date = datetime.datetime(2021,1,28)
datafeed1 = bt.feeds.PandasData(dataname=data1, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed1, name='600466.SH')
datafeed2 = bt.feeds.PandasData(dataname=data2, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed2, name='603228.SH')
cerebro.addstrategy(TestStrategy)
rasult = cerebro.run()

1、索引規則:索引位置編號結合了時間信息,
0 號位置永遠指向當前時間點的數據,
-1 號位置指向前一個時間點的數據,
然后依次回退 (backwards)-2、-3、-4、-5、......;
1 號位置指向下一天的數據,然后依次向前(forwards)2、3、4、......;

2、切片方法:get(ago=0, size=1) 函數,
其中 ago 對應數據點的索引位置,即從 ago 時間點開始往前取 size 個數據點。
默認情況下是取當前最新時點(ago=0)的那一個數據(size=1);

3、在編寫策略時,上面提到的對數據點的索引切片操作一般在 next() 函數中涉及較多,
而 __init__() 中涉及較少,
因為__init__() 中一般是對 一整條 line 進行操作(運算)。

class TestStrategy(bt.Strategy):def __init__(self):self.count = 0 # 用于計算 next 的循環次數# 打印數據集和數據集對應的名稱print("------------- init 中的索引位置-------------")print("0 索引:",'datetime',self.data1.lines.datetime.date(0), 'close',self.data1.lines.close[0])print("-1 索引:",'datetime',self.data1.lines.datetime.date(-1),'close', self.data1.lines.close[-1])print("-2 索引",'datetime', self.data1.lines.datetime.date(-2),'close', self.data1.lines.close[-2])print("1 索引:",'datetime',self.data1.lines.datetime.date(1),'close', self.data1.lines.close[1])print("2 索引",'datetime', self.data1.lines.datetime.date(2),'close', self.data1.lines.close[2])print("從 0 開始往前取3天的收盤價:", self.data1.lines.close.get(ago=0, size=3))print("從-1開始往前取3天的收盤價:", self.data1.lines.close.get(ago=-1, size=3))print("從-2開始往前取3天的收盤價:", self.data1.lines.close.get(ago=-2, size=3))print("line的總長度:", self.data1.buflen())def next(self):print(f"------------- next 的第{self.count+1}次循環 --------------")print("當前時點(今日):",'datetime',self.data1.lines.datetime.date(0),'close', self.data1.lines.close[0])print("往前推1天(昨日):",'datetime',self.data1.lines.datetime.date(-1),'close', self.data1.lines.close[-1])print("往前推2天(前日)", 'datetime',self.data1.lines.datetime.date(-2),'close', self.data1.lines.close[-2])print("前日、昨日、今日的收盤價:", self.data1.lines.close.get(ago=0, size=3))print("往后推1天(明日):",'datetime',self.data1.lines.datetime.date(1),'close', self.data1.lines.close[1])print("往后推2天(明后日)", 'datetime',self.data1.lines.datetime.date(2),'close', self.data1.lines.close[2])print("已處理的數據點:", len(self.data1))print("line的總長度:", self.data0.buflen())self.count += 1cerebro = bt.Cerebro()
st_date = datetime.datetime(2019,1,2) # 起始時間
ed_date = datetime.datetime(2021,1,28) # 結束時間
datafeed1 = bt.feeds.PandasData(dataname=data1, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed1, name='600466.SH')
datafeed2 = bt.feeds.PandasData(dataname=data2, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed2, name='603228.SH')
cerebro.addstrategy(TestStrategy)
rasult = cerebro.run()

__init__() 中:?
訪問的是整條 line,索引編號也是對整條 line 上所有數據點進行編號的,
所以 0 號位置對應導入的行情數據中最晚的那個時間點 2021-01-28,
然后依次 backwards;
1 號位置對應最早的那個時間點 2019-01-02,
然后依次 forwards ;

通過 get() 切片時,如果是從 ago=0 開始取,不會返回數據,從其他索引位置開始取,能返回數據 。

next() 中:
1、由于 next() 是按回測時間點依次循環運行的,
所以 next() 中數據點的索引位置是隨著回測依次推進而動態變化的:backwards 時對應回測過的、已處理過的那部分 line, forwards 時對應還未回測的那部分 line ;

2、在 next() 中,只要記住 0 是當前回測的時間點(今日),
然后站在當前時刻回首過往:-1 是昨日、-2 是前日,依次類推 ;或者站在當前時刻期盼未來:1 是明日、2 是明后日,以此類推 。
獲取 line 長度:
1、self.data0.buflen() 返回整條線的總長度,固定不變;
2、在 next() 中調用 len(self.data0),返回的是當前已處理(已回測)的數據長度,會隨著回測的推進動態增長。

DataFeeds 數據模塊

默認的導入方式
step1:調用 DataFeeds 模塊中的方法讀取數據;

step2:將讀取的數據傳給大腦。

# 讀取和導入 CSV 文件
data = bt.feeds.GenericCSVData(dataname='filename.csv', ...)
cerebro.adddata(data, name='XXX')
# 讀取和導入 dataframe 數據框 - 方式1
data = bt.feeds.PandasData(dataname=df, ...)
cerebro.adddata(data, name='XXX')
# 讀取和導入 dataframe 數據框 - 方式2
data = bt.feeds.PandasDirectData(dataname=df, ...)
cerebro.adddata(data, name='XXX')# 以 GenericCSVData 為例進行參數說明(其他導入函數參數類似)
bt.feeds.GenericCSVData(dataname='daily_price.csv', # 數據源,CSV文件名 或 Dataframe對象fromdate=st_date, # 讀取的起始時間todate=ed_date, # 讀取的結束時間nullvalue=0.0, # 缺失值填充dtformat=('%Y-%m-%d'), # 日期解析的格式# 下面是數據表格默認包含的 7 個指標,取值對應指標在 daily_price.csv 中的列索引位置datetime=0, # 告訴 GenericCSVData, datetime 在 daily_price.csv 文件的第1列high=3, low=4,open=2,close=5,volume=6,openinterest=-1) # 如果取值為 -1 , 告訴 GenericCSVData 該指標不存在

?Backtrader 中的數據表格默認情況下包含 7 條 line,這 7 條 line 的位置也是固定的,
依次為 ('close', 'low', 'high', 'open', 'volume', 'openinterest', 'datetime') ,
那導入的數據表格必須包含這 7 個指標嗎?指標的排列順序也必須一致嗎?
當然不是!其實你只要告訴 GenericCSVData、PandasData 、PandasDirectData 這 7 個指標在數據源中位于第幾列,如果沒有這個指標,那就將位置設置為 -1?
(如果是dataframe, None 表示指標不存在,-1 表示按位置或名稱自動匹配指標),所以你要做的是讓 Backtrader 知道指標在數據源的哪個位置上 。?

自定義讀取函數
如果你覺得每次都要設置這么多參數來告知指標位置很麻煩,那你也可以重新自定義數據讀取函數,
自定義的方式就是繼承數據加載類 GenericCSVData、PandasData 再構建一個新的類,然后在新的類里統一設置參數:

class My_CSVData(bt.feeds.GenericCSVData):params = (('fromdate', datetime.datetime(2019,1,2)),('todate', datetime.datetime(2021,1,28)),('nullvalue', 0.0),('dtformat', ('%Y-%m-%d')),('datetime', 0),('time', -1),('high', 3),('low', 4),('open', 2),('close', 5),('volume', 6),('openinterest', -1)
)
cerebro = bt.Cerebro()
data = My_CSVData(dataname='daily_price.csv')
cerebro.adddata(data, name='600466.SH')
rasult = cerebro.run()    

?新增指標
在回測時,除了常規的高開低收成交量這些行情數據外,還會用到別的指標,
比如選股回測時會用到很多選股因子(PE、PB 、PCF、......),那這些數據又該如何添加進 Backtrader 的數據表格呢?
往 Backtrader 的數據表格里添加指標,就是給數據表格新增列,也就是給數據表格新增 line:
以導入 DataFrame 為例,
在繼承原始的數據讀取類 bt.feeds.PandasData 的基礎上
,設置 lines 屬性和 params 屬性,
新的 line 會按其在 lines 屬性中的順序依次添加進數據表格中,具體對照下面例子的輸出部分:

class PandasData_more(bt.feeds.PandasData):lines = ('pe', 'pb', ) # 要添加的線# 設置 line 在數據源上的列位置params=(('pe', -1),('pb', -1),) # -1表示自動按列明匹配數據,也可以設置為線在數據源中列的位置索引 (('pe',6),('pb',7),) 
class TestStrategy(bt.Strategy):def __init__(self):print("--------- 打印 self.datas 第一個數據表格的 lines ----------")print(self.data0.lines.getlinealiases())print("pe line:", self.data0.lines.pe)print("pb line:", self.data0.lines.pb)data1['pe'] = 2 # 給原先的data1新增pe指標(簡單的取值為2)
data1['pb'] = 3 # 給原先的data1新增pb指標(簡單的取值為3)
# 導入的數據 data1 中
cerebro = bt.Cerebro()
st_date = datetime.datetime(2019,1,2)
ed_date = datetime.datetime(2021,1,28)
datafeed1 = PandasData_more(dataname=data1, fromdate=st_date, todate=ed_date)
cerebro.adddata(datafeed1, name='600466.SH')
cerebro.addstrategy(TestStrategy)
rasult = cerebro.run()

?

擴展PandasData類,加載更多列數據
#pandas的數據格式
from backtrader.feeds import PandasData
class Addmoredata(PandasData):lines = ('turnover_rate','pe','pb',)params = (('turnover_rate',7),('pe',8),('pb',9),)
擴展GenericCSVData加載csv格式數據
from backtrader.feeds import GenericCSVData
class AddCsvData(GenericCSVData):lines = ('turnover_rate','pe','pb',)params = (('turnover_rate',7),('pe',8),('pb',9),)
import backtrader as bt
from datetime import datetime
class TestStrategy1(bt.Strategy):def log(self, txt, dt=None):dt = dt or self.datas[0].datetime.date(0)print('%s, %s' % (dt.isoformat(), txt))def next(self):self.log(f"換手率:{self.datas[0].turnover_rate[0]},\市凈率:{self.datas[0].pb[0]},市盈率:{self.datas[0].pe[0]}")
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy1)
feed = Addmoredata(dataname = get_data('300002.SZ','20200420'))
#如果是讀取csv數據使用下式
#feed = AddCsvData(dataname = 'test.csv',dtformat=('%Y-%m-%d'))
cerebro.adddata(feed)
cerebro.run()
多只股票數據加載測試:
class TestStrategy2(bt.Strategy):def log(self, txt, dt=None):dt = dt or self.datas[0].datetime.date(0)print('%s, %s' % (dt.isoformat(), txt))def next(self):for data in self.datas:print(data._name)self.log(f"換手率:{data.turnover_rate[0]},\市凈率:{data.pb[0]},市盈率:{data.pe[0]}")
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy2)
codes=['600862.SH','300326.SZ','300394.SZ']
#加載最近兩日交易數據
for code in codes:feed = Addmoredata(dataname = get_data(code,'20200506'),name=code)cerebro.adddata(feed)
cerebro.run()

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

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

相關文章

談判學:三招了解對方底線

導讀:談判者都希望能了解對方的底線,最直接的一招就是將對手變成“朋友”,只是這種“內奸法”畢竟不是常規之法。大多數情況下,談判雙方也不可能像《無間道》一樣在對方陣營安放臥底,但是我們完全可以通過一些辦法來揣…

JSLint檢測Javascript語法規范

前端javascript代碼編寫中,有一個不錯的工具叫JSLint,可以檢查代碼規范化,壓縮JS,CSS等,但是他的語法規范檢查個人覺得太“苛刻”了,會提示各種各樣的問題修改建議,有時候提示的信息我們看的莫名…

Apt 命令解說(apt-get update、apt-cache search package、apt-get install package、apt-get remove )

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 高級打包工具(英語:Advanced Packaging Tools,縮寫為APT)是Debian及其派生發行版的軟件包…

SQL SERVER 2012 AlwaysOn - 維護篇 03

搭建 AlwaysOn 是件非常繁瑣的工作,需要從兩方面考慮,操作系統層面和數據庫層面,AlwaysOn 非常依賴于操作系統,域控,群集,節點等概念; DBA 不但要熟悉數據庫也要熟悉操作系統的一些概念&#xf…

指標研究與多周期

哪些地方會用到指標 ? 回顧一下 Backtrader 的主要功能模塊和回測流程(見:Backtrader 來了!)可以發現,只有在編寫策略Strategy 時才會涉及到指標的計算和使用,而且是 Strategy 中的 __init__()…

區塊鏈BAAS平臺:公共或私人區塊鏈編程以用于各種用途

2019獨角獸企業重金招聘Python工程師標準>>> 人們可以為公共或私人區塊鏈編程以用于各種用途。理論上,我認為犧牲權力下放的方面可以解決區塊鏈技術背后的許多當前問題。區塊鏈仍然可以包容,而不是分散。這如何解決當前的一些問題&#xff1f…

CURL 是什么

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 cURL是一個利用URL語法在命令行下工作的文件傳輸工具,1997年首次發行。 它支持文件上傳和下載,所以是綜合傳輸工…

易用性問題回復

針對淘寶網為例,以一次完整的購物流程為背景,我們分析了在淘寶網中的一些易用性的體現,主要場景如下圖所示: 在本場景中,新用戶下載淘寶app時,第一次打開應用,淘寶app會出現新手指引,教會用戶如…

易盛極星期貨量化教學

我目前量化實盤做期貨交易用的是這個軟件。主要就是因為它可以做套利合約,還有就是國企的外包,安全(vnpy的狗咬狗害怕)。 策略模板: 設置全局參數變量: #導入包 import talib #選擇合約代碼 code1 #設…

eBay是如何進行大數據集元數據發現的

很多大數據系統每天都會收集數PB的數據。這類系統通常主要用于查詢給定時間范圍內的原始數據記錄,并使用了多個數據過濾器。但是,要發現或識別存在于這些大型數據集中的唯一屬性可能很困難。 在大型數據集上執行運行時聚合(例如應用程序在特定…

職業發展 先“立功”還是先“安內”?

導讀:職業生涯更上一層樓,章良躊躇滿志,想在短期內建功立業,奠定江湖地位。但他清楚,自己運籌中的分公司服務升級計劃,對公司整體和自己的職業生涯都非常有利,卻將不可避免地轉移老將掌握的部分…

網關 Kong 折騰筆記 - 相關技術清單

背景 前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 公司準備更好的實現微服務架構,我前期的任務主要是 API 開發相關的技術學習,微服務會隨著業務的增加不斷增加…

Quantaxis更新數據到最新

登錄QQ群:563280067 安裝方法: 1.進入命令界面, 2.pip install pytdx-1.72r2-py3-none-any.whl 3. pip install quantaxis-1.10.19r1-py3-none-any.whl 之后輸入save save all 即可看到所有的數據全部安裝到位

Java各進制之間的轉換

十進制轉成十六進制: Integer.toHexString(int i) 十進制轉成八進制 Integer.toOctalString(int i) 十進制轉成二進制 Integer.toBinaryString(int i) 十六進制轉成十進制 Integer.valueOf("FFFF",16).toString() 八進制轉成十進制 Integer.valueOf("…

mingW與cygwin 異同

首先MingW和cygwin都可以用來跨平臺開發。 MinGW是Minimalistic GNU for Windows的縮寫,也就是Win版的GCC。 Cygwin則是全面模擬了Linux的接口,提供給運行在它上面的的程序使用,并提供了大量現成的軟件,更像是一個平臺。 相…

shell字符串的用法

shell字符串的用法 注意:shell4.2和shell4.1會有差別,較低版本的shell可能不支持某些功能 獲取字符串長度:${#string}獲取子串: 注:(左邊的第一個字符是用 0 表示,右邊的第一個字符用 0-1 表示&…

backtrader期權回測框架

使用backtrader數據進行回測,數據源來自于交易所爬取。 效果還行,我相信各位通過這個的框架學習,會對backtrader的應用有更深的領悟。包括數據的連接,新指標的加入。 導入框架: __future__ import (absolute_import…

kong入門實戰

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 安裝kong-database docker run -d --name kong-database \-p 5432:5432 \-e "POSTGRES_USERkong" \-e "POSTGRES_DBkong&…

PAT A1048

示例思想中提到了二分以及two point概念,這個需要后面進行總結;這個示例也給出了一個新的思路。對于兩個數字和m,查找兩個加數,可以進行i和m-i的枚舉,通過遍歷數組查看兩個加數是否存在,來進行遍歷&#xf…

linux 32位平臺,文件大小受限于2G的解決方法

公司的asterisk系統已經發生了兩次crash,檢查日志,都是在日志文件寫滿到2G后自動執行轉儲時,日志還在寫繼續寫入而導致的。google以后,發現了下面這邊文章,贊!解決了文件大小限于2G的問題,轉帖到…