還沒有Tushare賬號?注冊由此去:官網注冊Tushare
本篇為vnpy-tushare-ctp系列文章之一,其他文章請前往:
ubuntu 18.04 安裝 vnpy2.0.9 吐血總結
一、緣起
為vnpy制作tushare數據接口,實際上是為了日線級別的均線策略。目前的思路是在每天的9:30分時候策略開始生效,讀取之前一天的數據,而這些數據可以通過tushare獲取存入數據庫。讀取到數據之后立馬就可以進行計算並產生策略信號。
因為rqdata是付費產品,雖然vnpy官方對於rqdata支持比較好,但對於本屌,最好的還是免費產品。
所以新開坑,在vnpy中使用tushare代替rqdata一部分功能,最終達到日線級別的基於tushare的cta策略運行。
在vnpy的源代碼中尋找rqdata,找到/vnpy/app/cta_strategy/engine.py中的
def query_bar_from_rq( self, symbol: str, exchange: Exchange, interval: Interval, start: datetime, end: datetime ): """ Query bar data from RQData. """ req = HistoryRequest( symbol=symbol, exchange=exchange, interval=interval, start=start, end=end ) data = rqdata_client.query_history(req)
這就是cta_strategy調用rqdata的直接入口了。
設想,在這個類中,可以通過另外增加一個參數的方式,從上層指導:到底數據取得是通過米筐還是通過tushare。
二、實現
2.1 tushare獲取數據
要想用起tushare,必先獲取token。在官網社區注冊后到“個人主頁”->“接口token”獲取。另外,要想獲取期貨日線數據,現在需要至少200積分。小白有一百,填上個人信息再拉兩個人頭,積分到達220,就可以用了。
在Ubuntu系統下,安裝好的miniconda可以讓你舒舒服服地用上python,安裝配置過程見前文《ubuntu 18.04 安裝 vnpy2.0.9 吐血總結》,此處略過。用pip安裝好tushare之后,還要再裝一個lxml庫,還有bs4,接下來開始寫文件讀取數據。
import tushare as ts ts.set_token('你的token') pro = ts.pro_api() df = pro.fut_daily(ts_code='CU1811.SHF', start_date='20180101', end_date='20181113') print(df)
這個demo運行正常,之后,我們試圖將它以正確的姿勢寫進數據庫。
為什么要寫進數據庫呢,直接在策略里使用tushare讀取的數據不是也挺好嗎?使用數據庫能夠將數據獲取與使用分離,可以日后單獨將數據獲取做得更健壯。
2.2 vnpy的sqlite
vnpy在2020年1月20日正在寫這篇文章的時候的最新版本是vnpy-2.0.9,默認的數據庫是sqlite3。連接到sqlite,需要找到vnpy的設置文件,用find命令找到了在/hom/han目錄下的.vntrader文件夾,在這個文件夾下有vnpy的設置文件(各種.json)和sqlite文件database.db。
sqlite是一個無需配置的輕量數據庫,默認情況下連密碼都不需要的。我們直接在.vntrader下打開一個終端,運行
sqlite3 database.db
即可打開數據庫,之后用.tables命令查看數據庫的表,查到有兩個,分別是dbbardata和dbtickdata,繼續查詢表的內容:
select * from dbbardata
終端輸出了數據,類似
3878|rb1910|SHFE|2019-10-15 00:00:00|d|7260.0|0.0|3610.0|3650.0|3550.0|3650.0
這樣的形式。我們可以把數據的形式弄得好看一點,繼續使用命令.header on和.mode column,再次查詢表,得到下面的輸出:

繼續在稍高的層次上操作數據庫,下面是從vnpy社區中找到的數據調用分析圖:

2.3 在回測引擎中找到數據庫插入位置
在更上層的vnpy的app層面,對數據庫的調用可以在/app/cta_backtester/engine.py中找到。在run_downloading中,先找到合約,再尋找它在原有數據庫中存不存在,如果存在,則直接main_engine.query_history(req, contract.gateway_name),否則就要去米筐那里取數據data = rqdata_client.query_history(req)。取到數據之后進行存儲
database_manager.save_bar_data(data)
進行操作就應該在這里把rqdata的語句用tushare加以補充。
仔細地分析vnpy的回測引擎,CtaBacktesterApp可以得到調取數據庫操作的途徑。我們進行如下操作
from vnpy.event import EventEngine from vnpy.trader.engine import MainEngine from vnpy.app.cta_backtester import CtaBacktesterApp from datetime import datetime def main(): event_engine = EventEngine() main_engine = MainEngine(event_engine) app = CtaBacktesterApp main_engine.add_app(app) back_engine = main_engine.get_engine("CtaBacktester") back_engine.init_engine() vt_symbol = "rb1908.SHFE" interval = "d" start = datetime(2019,6,1) end = datetime(2019,8,31) back_engine.start_downloading(vt_symbol,interval,start,end)
之后,可以看到sqlite數據庫增加了rb1908.SHFE的相關記錄,證明調用成功。並且,當我們再次運行同樣的程序,發現sqlite並沒有把重復的數據再插入,重復數據的擔心也可以省了。
三、tushare-vnpy綜合
3.1 將tushare獲取的數據集成到vnpy中,並且放到數據庫里面。經過了很多次調試,暫定如下代碼。在/vnpy/trader目錄下建立tuquery.py文件,輸入以下內容:
import tushare as ts from vnpy.trader.object import HistoryRequest,BarData from vnpy.trader.constant import Exchange from datetime import datetime class TushareData: def __init__(self): ts.set_token('你的token') return def exchange_bond(self,exchange:Exchange): if exchange.value == "SHFE": return "SHF" elif exchange.value == "CZCE": return "ZCE" else : return exchange.value def tuquery(self,req:HistoryRequest): symbol = req.symbol exchange = req.exchange interval = req.interval start = req.start.strftime('%Y%m%d') end = req.end.strftime('%Y%m%d') tcode = f'{symbol}'+'.'+ self.exchange_bond(exchange) pro = ts.pro_api(); df = pro.fut_daily(ts_code= tcode, start_date= start, end_date= end) data: List[BarData] = [] if df is not None: for ix, row in df.iterrows(): date = datetime.strptime(row.trade_date,'%Y%m%d') bar = BarData( symbol=symbol, exchange=exchange, interval=interval, datetime=date, open_price=row["open"], high_price=row["high"], low_price=row["low"], close_price=row["close"], volume=row["amount"], gateway_name="TU" ) print(bar) data.append(bar) return data tusharedata = TushareData()
同時在/vnpy/app/cta_backtester目錄下找到engine.py,導入包
from vnpy.trader.tuquery import tusharedata
在run_downloading函數下找到“try:”,if……else:這里將原來的
data = rqdata_client.query_history(req)
替換為
tq = tusharedata
data = tq.tuquery(req)
最后在最頂層的主文件中添加調用代碼即可:
vt_symbol = "fg1909.CZCE" interval = "d" start = datetime(2019,6,1) end = datetime(2019,8,1) back_engine.start_downloading(vt_symbol,interval,start,end)
我們可以看到,最終在sqlite數據庫中,得到了使用tushare獲取的數據:

至此,我們已經完成了在vnpy中使用tushare作為數據源進行期貨日線級別支持。后面的工作即可提取數據並編制策略,留待后面再續……
四、后記
4.1 rqdata后續
新問題出現了,之前我運行程序一直是在學校,而回到家后,學生試用的賬號受到了限制,運行出現了如下錯誤:
rqdatac.share.errors.PermissionDenied: this license is only allowed to access through the education network
這意味着,我們還沒有完全繞過rqdata,我們必須再次進行修改,修改的辦法就是將/vnpy/app/cta_backtester/engine.py中的init_engine函數的
self.init_rqdata()
注釋掉。
4.2 為數據替換順序
我們最后插入的數據的順序與之前vnpy默認的日期順序是反的,可以在tuquery.py中加入一行,將數據順序調整過來:
df= df.sort_values( by = 'trade_date', ascending= True)
