Databundle
zipline 缺省提供了一些行情的data bundle , 可以通過 zipline bundles
查看
其中 quandl
數據源是從 https://www.quandl.com/ 網站的WIKI dataset獲取數據的,不過通過該api數據較慢,因為逐批獲取之后還要處理后才放到本地。quantopian-quandl
一份備份數據,相當於將處理后的數據打包之后提供,下載下來解壓到 ~/.zipline/data
目錄,所以相對較快,如果有研究美國股市的量化交易,可以使用這些數據源,還有yahoo數據源,它的好處是可以自己定制要抓取的數據集,如果你只需要配置好然后通過 ipline.data.bundles.register
進行注冊即可。
如果列位想引入國內的數據源進行回測,那么恐怕要下點功夫啦,下面可以給出如下幾種方案:
- 不ingest數據源,直接在構建
TradingAlgorithm
的時候引入如從csv
或者數據庫
里讀取出來的pd.Dataframe
信息作為DataPortal
的datasource
(當然最終會轉化為pd.Panel
) - 自己定制
data bundle
,然后ingest
如果你要測試的數據集比較小,股票數量也比較少,那么第一種方案是比較方便的,如果需要大量的數據,還是自己寫data bundle 比較方便(並且貌似使用Dataframe也很難處理有 split或者dividend的股票)
那么如何編寫一個新的bundle的擴展呢?
其實比較簡單,自己實現一個ingest
函數即可
該ingest
函數的參數如下:
ingest(environ,
asset_db_writer,
minute_bar_writer,
daily_bar_writer,
adjustment_writer,
calendar,
start_session,
end_session,
cache,
show_progress,
output_dir)
其中這個函數是被environ
回調的,所以參數列表無法自己指定,下面簡單介紹一下幾個參數的作用
參數 | 作用 |
---|---|
environ | 代表環境變量的一映射,如果你需要一些額外的參數引入,可以在這里通過環境變量指定,如quandl 的API key |
asset_db_writer | AssetDBWriter 的實例,通過它的write函數可以把一個證券(如股票)的基礎信息,主要是碼表,名稱,起止日期等信息寫入到數據庫中,並且為每個證券分配一個sid作為唯一標識,這個sid在系統的其它地方也會成為股票的主要索引方式。默認保存在sqlite數據庫中 |
daily_bar_writer | 寫入每日的行情信息 BcolzDailyBarWriter 的實例,通過調用write方法寫入股票的開高低收和成交量等信息(OHLCV),這里的信息也需要使用sid與基本信息進行關聯。默認使用bcolz的格式保存 |
minute_bar_writer | 寫入每分鍾行情的... |
adjustment_writer | 處理一些拆分,合並,送股,分紅等事件的信息。默認使用sqlite數據庫保存 |
calendar | 你當前使用的交易日歷 ,數據的獲取是以交易日歷作為索引的,也就是說,如果你的交易日歷里那一天存在,可是你無法讀取行情數據,很有可能會出現錯誤,所以calendar 和你的行情信息 的匹配是很關鍵的 |
start_session/end_session | 獲取數據的起止日期 |
cache | dataframe_cache 的實例,你可以使用它來緩存在獲取過程中的原始信息,在多次ingest的時候起到加速的作用 |
show_progress | 一個布爾值,是否顯示ingest的過程,如果你的獲取數據時間較長,可以判斷show_progress變量來顯示進度。 |
output_dir | data bundle的輸出目錄,如果你的data bundle 是類似 quantopian-quandl 這種通過下載遠程已經寫好的數據源,並且解壓到本地的,可以直接使用這個變量獲取最終解壓目錄 |
一般來說,獲取一個行情的數據源,主要需要三方面的信息
- 使用
asset_db_writer
獲取基礎信息 - 使用
daily_bar_writer
/minute_bar_writer
寫入行情信息 - 使用
adjustment_writer
寫入split, dividend信息。
話說這里坑不少,我建議多看看官方的例子,大部分都要講數據處理為pd.Dataframe的結構再進行的。另外我自己也寫了一些簡單的demo,可以參考:
https://github.com/rainx/zipline_cn_databundle
里面代碼比較凌亂,有很多無用代碼,主要參考一下squant_source
模塊
https://github.com/rainx/zipline_cn_databundle/blob/master/zipline_cn_databundle/squant_source.py
不過代碼里用到了我自己寫的一個squant包,是一個私有數據包,因為應用了很多內部數據,不便公開,所以大家恐怕無法直接使用。主要是asset和adjuestment的部分,對於行情,我使用的是通達信的客戶端的本地數據(木有windows , 從別的機器拷貝的 T_T),大家應該可以直接使用,參考里面的TdxReader
(https://github.com/rainx/zipline_cn_databundle/blob/master/zipline_cn_databundle/tdx/reader.py)
Bcolz
zipline的本地行情是寫入到bcolz
的格式的,它是底層使用Blosc
庫的基於列的數據庫,至於為什么使用基於列的數據庫,應該是與行情信息的特質有關,因為行情信息可以通過TradingCalendar和Bcolz的元信息進行索引,並且以時間順序排列,而且是相同的類型,所以非常適合類似數組結構的存儲方式,加之以Blosc的變態級別的壓縮解壓算法(使用CPU L1/L2緩存進行壓縮/解壓,平均速度超過了memcpy
調用),所以對時間和空間上都可以做到比較優化的狀態。
內部的索引結構大概抽象為: