Quote Adapter 與資料格式¶
這一頁的目的,是把外部資料來源與內部回測引擎之間的邊界講清楚。
如果你未來要:
- 替換
shioaji - 接自己的資料源
- 寫新的行情 adapter
- 把回測系統抽成可重用架構
這一頁最重要。
專案目前有哪些資料來源¶
目前在 app.py 中可見的資料源有:
shioajidatabento- 部分舊路徑有
polygon
對應實作位於:
src/quote/shioaji_quote.pysrc/quote/databento_quote.py
主流程怎麼選資料源¶
fetch_data(ticker, start_time, end_time) 會依 ticker_list 中設定的 source 決定用哪個 adapter。
因此從系統角度來看:
- 外部資料源本身不是核心
fetch_data()才是主流程真正依賴的資料抽象入口
目前 adapter 的真實介面¶
雖然專案裡沒有正式宣告 Protocol 或 BaseQuoteAdapter,但實際上有一個隱性介面:
- 輸入:
tickerstart_time / start_dateend_time / end_date- 輸出:
pandas.DataFrame
而且這個 DataFrame 至少要有:
datetimeopenhighlowclosevolume
可選欄位常見還有:
symbolamount
內部回測真正吃的是什麼¶
不是原始 DataFrame,而是 DataFeed。
DataFeed 的底層元素是 OHLCV:
class OHLCV(BaseModel):
datetime: str
open: float
high: float
low: float
close: float
volume: float
也就是說,從架構觀點來看:
- Adapter 層輸出
DataFrame - 核心回測層輸入
DataFeed
data_feed_from_dataframe_with_timeframe() 是兩者之間的轉換器。
目前 shioaji 實際用到的套件面¶
你目前不是整個系統都深度依賴 shioaji,而是集中在 ShioajiQuote 裡。
實際依賴很小:
sj.Shioaji(simulation=True)api.login(...)api.Contracts.Futures.TXF.TXFR1api.Contracts.Futures.TXF.TXFR2api.kbars(...)
因此如果你未來想替換成自己的資料來源,有兩種做法。
方案 A:模仿你自己的 adapter¶
最實用的方式是只保留你自己的 adapter 介面,例如:
class QuoteAdapter:
def get_txfr1_data(self, ticker, start_date=None, end_date=None) -> pd.DataFrame:
...
這樣你只要替換 ShioajiQuote,主流程幾乎不用動。
方案 B:正式抽象成 provider interface¶
若要做得更乾淨,建議抽象成類似:
class QuoteProvider(Protocol):
def get_data(
self,
ticker: str,
start_time: str | datetime,
end_time: str | datetime,
) -> pd.DataFrame:
...
然後在 fetch_data() 中統一呼叫 get_data()。
如果你要重構,我建議的標準 adapter 規格¶
輸入¶
ticker: strstart_time: str | datetimeend_time: str | datetime
輸出¶
pd.DataFrame
必備欄位¶
datetimeopenhighlowclosevolume
可選欄位¶
symbolamount
資料要求¶
datetime可被pd.to_datetime()正確解析- 每列代表一根 bar
- 資料按時間升冪排序
- 無重複時間戳
資料標準化責任應放哪裡¶
最好的做法是:
- adapter 自己負責把外部資料轉成標準欄位
fetch_data()只負責選擇資料源與交易時段切片data_feed_from_dataframe_with_timeframe()只負責重採樣與 DataFeed 轉換
這樣分層最乾淨。
現況結論¶
已經清楚的部分¶
- 回測核心要的是
DataFeed OHLCV的欄位非常清楚
還沒正式清楚的部分¶
- adapter 層目前沒有正式 interface
- 只靠實作約定回
DataFrame
如果未來要讓這個系統更可重建,最值得補的一步就是:
- 正式抽出
QuoteProvider/QuoteAdapter介面