同時第三方資料來源和資料庫歷史資料,作為cta策略初始化

張國平發表於2021-10-19

首先個人推薦使用第三方資料來源,如果資料來源質量有保證的話。

如果啟動第三方資料來源,在cta策略啟動時候,會從資料來源下載load_bar所需要的預期的資料,看策略需求,下載日期或長或短。

如果策略較少沒關係,如果策略較多,尤其是同一合約有多個策略時候,每次啟動就花費非常多時間,而且很多是重複下載,比如如果有多個螺紋鋼策略,就要下載多次螺紋鋼資料,還是不太方法。


這裡思路很簡單,策略啟動時候,對比啟動需要資料是否在資料庫內,如果有使用資料庫資料,如果沒有,下載再使用。

對比是按照需要資料的開始結束和資料庫內bar overview表的開始和結束。查詢結束時候可能大於bar結束時候,比如下午8點半啟動,但是bar結束資料是下午3點;這樣可能有差異取讀取,想想為了安全,冗餘一些沒有關係。


程式碼如下,只要用這個替代cta_engine裡面同名方法即可。這個是基於vntrade 2.3 的,2.6 的版本,改為 query_bar_from_datafeed即可

from vnpy.trader.database import database_manager
from tzlocal import get_localzone
LOCAL_TZ = get_localzone()
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
    )
    bar_start = None
    bar_end = None
    bar_overview_list = database_manager.get_bar_overview()
    for bar_overview in bar_overview_list:
        if bar_overview.symbol == symbol and bar_overview.exchange == exchange and bar_overview.interval == interval:
            bar_start = bar_overview.start.astimezone(LOCAL_TZ)
            bar_end = bar_overview.end.astimezone(LOCAL_TZ)
            if bar_start <= start:
                req = HistoryRequest(
                    symbol=symbol,
                    exchange=exchange,
                    interval=interval,
                    start= bar_end,
                    end=end + timedelta(minutes=1)
                )
    data =  rqdata_client.query_history(req)
    if data:
        database_manager.save_bar_data(data)
        if bar_end:
            self.write_log(f"{symbol}.{exchange}-{interval.value},資料庫已有 {bar_start} 到 {bar_end}資料,從 {bar_end} 到{end}歷史資料下載完成")
        else:
            self.write_log(
                f"{symbol}.{exchange}-{interval.value},從 {start} 到{end}歷史資料下載完成")
    else:
        if bar_end:
            self.write_log(f"{symbol}.{exchange}-{interval.value},資料庫已有 {bar_start} 到 {bar_end}資料,從 {bar_end} 到{end}或無歷史資料")
        else:
            self.write_log(
                f"{symbol}.{exchange}-{interval.value},從 {start} 到{end}歷史資料下載失敗")
    bars = database_manager.load_bar_data(
        symbol=symbol,
        exchange=exchange,
        interval=interval,
        start=start,
        end=end,
    )
    return bars


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2838063/,如需轉載,請註明出處,否則將追究法律責任。

相關文章