在部署完 DolphinDB 後,需要将曆史資料批量導入資料庫,再進行資料查詢、計算和分析等操作。為便于使用者快速導入通聯曆史 Level-2 行情資料,DolphinDB 開發了 DolphinDBModules::easyTLDataImport 子產品(簡稱 easyTLDataImport 子產品),主要用于通聯曆史 Level-2 行情資料的自動化導入,目前已支援的資料源包括:
- 滬深 Level-2 快照行情
- 滬深逐筆委托
- 滬深逐筆成交
注意:本教程代碼基于 DolphinDB 2.00.9.4 開發,建議使用者使用 2.00.9.4 及以上版本進行功能測試。
1. 曆史資料檔案結構
在使用本教程功能子產品時,需要使用者自行将通聯資料解壓,并確定在主目錄下建立了以日期命名的日期目錄,每個日期目錄下包含所有該日期的 csv 檔案。
例如,主目錄是 level2,則檔案結構可以設定如下:
|—— level2
| |—— 20211201
| | |—— xxx.csv
| | |—— …
| |—— 20211202
| | |—— xxx.csv
| | |—— …
| |—— …
資料也可以按年組織,則檔案結構如下
|—— level2
| |—— 2021
| | |—— 20211201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— 2022
| | |—— 20221201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— …
注意:日期這一層目錄之前的檔案結構和日期目錄下的檔案結構都沒有要求。
2. 行情資料存儲模型設計
通聯資料提供了上交所和深交所兩個交易所的資料。使用者使用 easyTLDataImport 子產品時可以選擇将兩個交易所的資料分開存儲為兩張表,或合并存為一張表。如果選擇存為一張表,則表中的字段是兩個交易所資料字段的并集,并新增字段 Market 用于辨別資料來自哪個交易所。
上交所和深交所兩個交易所資料的結構不同,且不同時期同一個交易所的資料結構也不同。根據《滬深 L2 高頻行情檔案說明》,我們整理了通聯提供的兩個交易所各個時期的資料結構,最終确定以下述的表結構将資料存入資料庫。
2.1 Level-2 快照資料
- 深交所資料(總共 37 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2010.05 - 2016.05.06(MarketData.csv) | 2016.05.07 - 2019.06.04(mdl_6_28_0.csv) | 2019.06.05 - 至今(mdl_6_28_0.csv) |
資料生成時間 | TradeTime | TIMESTAMP | DataTimeStamp | UpdateTime | UpdateTime |
行情類别 | MDStreamID | SYMBOL | MDStreamID | MDStreamID | |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | SecurityIDSource | |
交易階段 | TradingPhaseCode | SYMBOL | EndOfDayMaker | TradingPhaseCode | TradingPhaseCode |
昨日收盤價 | PreCloPrice | DOUBLE | PreClosePx | PreCloPrice | PreCloPrice |
成交筆數 | NumTrades | INT | NumTrades | TurnNum | TurnNum |
成交總量 | TotalVolumeTrade | INT | TotalVolumeTrade | Volume | Volume |
成交總金額 | TotalValueTrade | DOUBLE | TotalValueTrade | Turnover | Turnover |
最近價 | LastPrice | DOUBLE | LastPx | LastPrice | LastPrice |
開盤價 | OpenPrice | DOUBLE | OpenPx | OpenPrice | OpenPrice |
最高價 | HighPrice | DOUBLE | HighPx | HighPrice | HighPrice |
最低價 | LowPrice | DOUBLE | LowPx | LowPrice | LowPrice |
升跌1(最新價-昨收價) | DifPrice1 | DOUBLE | DifPrice1 | DifPrice1 | |
升跌2(最新價-上一最新價) | DifPrice2 | DOUBLE | DifPrice2 | DifPrice2 | |
股票市盈率1 | PE1 | DOUBLE | PERatio1 | PE1 | PE1 |
股票市盈率2 | PE2 | DOUBLE | PERatio2 | PE2 | PE2 |
基金T-1淨值 | PreCloseIOPV | DOUBLE | PreCloseIOPV | PreCloseIOPV | |
基金實時參考淨值 | IOPV | DOUBLE | IOPV | IOPV | |
委托買入總量 | TotalBidQty | INT | TotalBidQty | TotalBidQty | TotalBidQty |
權重平均買入價格 | WeightedAvgBidPx | DOUBLE | WeightedAvgBidPx | WeightedAvgBidPx | WeightedAvgBidPx |
委托賣出總量 | TotalOfferQty | INT | TotalOfferQty | TotalOfferQty | TotalOfferQty |
權重平均賣出價格 | WeightedAvgOfferPx | DOUBLE | WeightedAvgOfferPx | WeightedAvgOfferPx | WeightedAvgOfferPx |
漲停價 | UpLimitPx | DOUBLE | HighLimitPrice | HighLimitPrice | |
跌停價 | DownLimitPx | DOUBLE | LowLimitPrice | LowLimitPrice | |
持倉量 | OpenInt | INT | TotalLongPosition | OpenInt | OpenInt |
權證溢價率 | OptPremiumRatio | DOUBLE | OptPremiumRatio | OptPremiumRatio | |
賣價10檔 | OfferPrice | DOUBLE[] | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 |
買價10檔 | BidPrice | DOUBLE[] | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 |
賣量10檔 | OfferOrderQty | INT[] | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 |
買量10檔 | BidOrderQty | INT[] | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 |
申買10檔委托筆數 | BidNumOrders | INT[] | NumOrdersB1..NumOrdersB10 | ||
申賣10檔委托筆數 | OfferNumOrders | INT[] | NumOrdersS1..NumOrdersS10 | ||
入庫時間 | LocalTime | TIME | LocalTime | LocalTime | LocalTime |
消息序列号 | SeqNo | INT | SeqNo | SeqNo | SeqNo |
委托賣量50檔 | OfferOrders | INT[] | OrderQty1..OrderQty50 (OrderQueue.csv) | OrderQty1..OrderQty50 (mdl_6_28_1.csv) | OrderQty1..OrderQty50 (mdl_6_28_1.csv) |
委托買量50檔 | BidOrders | INT[] | OrderQty1..OrderQty50 (OrderQueue.csv) | OrderQty1..OrderQty50 (mdl_6_28_2.csv) | OrderQty1..OrderQty50 (mdl_6_28_2.csv) |
- 上交所資料(總共 52 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2019.06.05 以前(MarketData.csv) | 2019.06.06 - 至今(MarketData.csv) |
資料生成時間 | TradeTime | TIMESTAMP | UpdateTime | UpdateTime |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID |
快照類型(全量/更新) | ImageStatus | INT | ImageStatus | ImageStatus |
昨日收盤價 | PreCloPrice | DOUBLE | PreCloPrice | PreCloPrice |
開盤價 | OpenPrice | DOUBLE | OpenPrice | OpenPrice |
最高價 | HighPrice | DOUBLE | HighPrice | HighPrice |
最低價 | LowPrice | DOUBLE | LowPrice | LowPrice |
最近價 | LastPrice | DOUBLE | LastPrice | LastPrice |
今收盤價 | ClosePrice | DOUBLE | ClosePrice | ClosePrice |
交易階段 | TradingPhaseCode | SYMBOL | InstruStatus | InstruStatus |
成交筆數 | NumTrades | INT | TradNumber | TradNumber |
成交總量 | TotalVolumeTrade | INT | TradVolume | TradVolume |
成交總金額 | TotalValueTrade | DOUBLE | Turnover | Turnover |
委托買入總量 | TotalBidQty | INT | TotalBidVo | TotalBidVo |
權重平均買入價格 | WeightedAvgBidPx | DOUBLE | WAvgBidPri | WAvgBidPri |
債券權重平均委買價格 | AltWAvgBidPri | DOUBLE | AltWAvgBidPri | AltWAvgBidPri |
委托賣出總量 | TotalOfferQty | INT | TotalAskVol | TotalAskVol |
權重平均賣出價格 | WeightedAvgOfferPx | DOUBLE | WAvgAskPri | WAvgAskPri |
債券權重平均委賣價格 | AltWAvgAskPri | DOUBLE | AltWAvgAskPri | AltWAvgAskPri |
ETF申購筆數 | ETFBuyNumber | INT | ETFBuyNumber | ETFBuyNumber |
ETF申購數量 | ETFBuyAmount | INT | EtfBuyVolume | EtfBuyVolume |
ETF申購金額 | ETFBuyMoney | DOUBLE | ETFBuyMoney | ETFBuyMoney |
ETF贖回筆數 | ETFSellNumber | INT | ETFSellNumber | ETFSellNumber |
ETF贖回數量 | ETFSellAmount | INT | ETFSellVolume | ETFSellVolume |
ETF贖回金額 | ETFSellMoney | DOUBLE | ETFSellMoney | ETFSellMoney |
債券到期收益率 | YieldToMatu | DOUBLE | YieldToMatu | YieldToMatu |
權證執行的總數量 | TotWarExNum | DOUBLE | TotWarExNum | TotWarExNum |
漲停價 | UpLimitPx | DOUBLE | WarUpperPri | WarUpperPri |
跌停價 | DownLimitPx | DOUBLE | WarLowerPri | WarLowerPri |
買入撤單筆數 | WithdrawBuyNumber | INT | WiDBuyNum | WiDBuyNum |
買入撤單數量 | WithdrawBuyAmount | INT | WiDBuyVo | WiDBuyVo |
買入撤單金額 | WithdrawBuyMoney | DOUBLE | WiDBuyMon | WiDBuyMon |
賣出撤單筆數 | WithdrawSellNumber | INT | WiDSellNum | WiDSellNum |
賣出撤單數量 | WithdrawSellAmount | INT | WiDSellVol | WiDSellVol |
賣出撤單金額 | WithdrawSellMoney | DOUBLE | WiDSellMon | WiDSellMon |
買入總筆數 | TotalBidNumber | INT | TotBidNum | TotBidNum |
賣出總筆數 | TotalOfferNumber | INT | TotSellNum | TotSellNum |
買入委托成交最大等待時間 | MaxBidDur | INT | MaxBidDur | MaxBidDur |
賣出委托最大等待時間 | MaxSellDur | INT | MaxSellDur | MaxSellDur |
買方委托價位數 | BidNum | INT | BidNum | BidNum |
賣方委托價位數 | SellNum | INT | SellNum | SellNum |
基金實時參考淨值 | IOPV | DOUBLE | IOPV | IOPV |
賣價10檔 | OfferPrice | DOUBLE[] | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 |
買價10檔 | BidPrice | DOUBLE[] | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 |
賣量10檔 | OfferOrderQty | INT[] | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 |
買量10檔 | BidOrderQty | INT[] | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 |
申買10檔委托筆數 | BidNumOrders | INT[] | NumOrdersB1..NumOrdersB10 | |
申賣10檔委托筆數 | OfferNumOrders | INT[] | NumOrdersS1..NumOrdersS10 | |
入庫時間 | LocalTime | TIME | LocalTime | LocalTime |
消息序列号 | SeqNo | INT | SeqNo | SeqNo |
委托賣量50檔 | OfferOrders | INT[] | OrderQty1..OrderQty50 (OrderQueue.csv) | OrderQty1..OrderQty50 (OrderQueue.csv) |
委托買量50檔 | BidOrders | INT[] | OrderQty1..OrderQty50 (OrderQueue.csv) | OrderQty1..OrderQty50 (OrderQueue.csv) |
- 滬深資料合并(總共 62 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 深交所 2010.05 - 2016.05.06(MarketData.csv) | 深交所 2016.05.07 - 2019.06.04(mdl_6_28_0.csv) | 深交所 2019.06.05 - 至今(mdl_6_28_0.csv) | 上交所 2019.06.05 以前(MarketData.csv) | 上交所 2019.06.06 - 至今(MarketData.csv) |
交易所名稱 | Market | SYMBOL | “SZ“ | “SZ“ | “SZ“ | “SH“ | “SH“ |
資料生成時間 | TradeTime | TIMESTAMP | DataTimeStamp | UpdateTime | UpdateTime | UpdateTime | UpdateTime |
行情類别 | MDStreamID | SYMBOL | MDStreamID | MDStreamID | |||
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID | SecurityID | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | SecurityIDSource | |||
交易階段 | TradingPhaseCode | SYMBOL | EndOfDayMaker | TradingPhaseCode | TradingPhaseCode | InstruStatus | InstruStatus |
快照類型(全量/更新) | ImageStatus | INT | ImageStatus | ImageStatus | |||
昨日收盤價 | PreCloPrice | DOUBLE | PreClosePx | PreCloPrice | PreCloPrice | PreCloPrice | PreCloPrice |
成交筆數 | NumTrades | INT | NumTrades | TurnNum | TurnNum | TradNumber | TradNumber |
成交總量 | TotalVolumeTrade | INT | TotalVolumeTrade | Volume | Volume | TradVolume | TradVolume |
成交總金額 | TotalValueTrade | DOUBLE | TotalValueTrade | Turnover | Turnover | Turnover | Turnover |
最近價 | LastPrice | DOUBLE | LastPx | LastPrice | LastPrice | LastPrice | LastPrice |
開盤價 | OpenPrice | DOUBLE | OpenPx | OpenPrice | OpenPrice | OpenPrice | OpenPrice |
最高價 | HighPrice | DOUBLE | HighPx | HighPrice | HighPrice | HighPrice | HighPrice |
最低價 | LowPrice | DOUBLE | LowPx | LowPrice | LowPrice | LowPrice | LowPrice |
今收盤價 | ClosePrice | DOUBLE | ClosePrice | ClosePrice | |||
升跌1(最新價-昨收價) | DifPrice1 | DOUBLE | DifPrice1 | DifPrice1 | |||
升跌2(最新價-上一最新價) | DifPrice2 | DOUBLE | DifPrice2 | DifPrice2 | |||
股票市盈率1 | PE1 | DOUBLE | PERatio1 | PE1 | PE1 | ||
股票市盈率2 | PE2 | DOUBLE | PERatio2 | PE2 | PE2 | ||
基金T-1淨值 | PreCloseIOPV | DOUBLE | PreCloseIOPV | PreCloseIOPV | |||
基金實時參考淨值 | IOPV | DOUBLE | IOPV | IOPV | IOPV | IOPV | |
委托買入總量 | TotalBidQty | INT | TotalBidQty | TotalBidQty | TotalBidQty | TotalBidVo | TotalBidVo |
權重平均買入價格 | WeightedAvgBidPx | DOUBLE | WeightedAvgBidPx | WeightedAvgBidPx | WeightedAvgBidPx | WAvgBidPri | WAvgBidPri |
債券權重平均委買價格 | AltWAvgBidPri | DOUBLE | AltWAvgBidPri | AltWAvgBidPri | |||
委托賣出總量 | TotalOfferQty | INT | TotalOfferQty | TotalOfferQty | TotalOfferQty | TotalAskVol | TotalAskVol |
權重平均賣出價格 | WeightedAvgOfferPx | DOUBLE | WeightedAvgOfferPx | WeightedAvgOfferPx | WeightedAvgOfferPx | WAvgAskPri | WAvgAskPri |
債券權重平均委賣價格 | AltWAvgAskPri | DOUBLE | AltWAvgAskPri | AltWAvgAskPri | |||
漲停價 | UpLimitPx | DOUBLE | HighLimitPrice | HighLimitPrice | WarUpperPri | WarUpperPri | |
跌停價 | DownLimitPx | DOUBLE | LowLimitPrice | LowLimitPrice | WarLowerPri | WarLowerPri | |
持倉量 | OpenInt | INT | TotalLongPosition | OpenInt | OpenInt | ||
權證溢價率 | OptPremiumRatio | DOUBLE | OptPremiumRatio | OptPremiumRatio | |||
賣價10檔 | OfferPrice | DOUBLE[] | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 | AskPrice1..AskPrice10 |
買價10檔 | BidPrice | DOUBLE[] | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 | BidPrice1..BidPrice10 |
賣量10檔 | OfferOrderQty | INT[] | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 | AskVolume1..AskVolume10 |
買量10檔 | BidOrderQty | INT[] | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 | BidVolume1..BidVolume10 |
申買10檔委托筆數 | BidNumOrders | INT[] | NumOrdersB1..NumOrdersB10 | NumOrdersB1..NumOrdersB10 | |||
申賣10檔委托筆數 | OfferNumOrders | INT[] | NumOrdersS1..NumOrdersS10 | NumOrdersS1..NumOrdersS10 | |||
ETF申購筆數 | ETFBuyNumber | INT | ETFBuyNumber | ETFBuyNumber | |||
ETF申購數量 | ETFBuyAmount | INT | EtfBuyVolume | EtfBuyVolume | |||
ETF申購金額 | ETFBuyMoney | DOUBLE | ETFBuyMoney | ETFBuyMoney | |||
ETF贖回筆數 | ETFSellNumber | INT | ETFSellNumber | ETFSellNumber | |||
ETF贖回數量 | ETFSellAmount | INT | ETFSellVolume | ETFSellVolume | |||
ETF贖回金額 | ETFSellMoney | DOUBLE | ETFSellMoney | ETFSellMoney | |||
債券到期收益率 | YieldToMatu | DOUBLE | YieldToMatu | YieldToMatu | |||
權證執行的總數量 | TotWarExNum | DOUBLE | TotWarExNum | TotWarExNum | |||
買入撤單筆數 | WithdrawBuyNumber | INT | WiDBuyNum | WiDBuyNum | |||
買入撤單數量 | WithdrawBuyAmount | INT | WiDBuyVo | WiDBuyVo | |||
買入撤單金額 | WithdrawBuyMoney | DOUBLE | WiDBuyMon | WiDBuyMon | |||
賣出撤單筆數 | WithdrawSellNumber | INT | WiDSellNum | WiDSellNum | |||
賣出撤單數量 | WithdrawSellAmount | INT | WiDSellVol | WiDSellVol | |||
賣出撤單金額 | WithdrawSellMoney | DOUBLE | WiDSellMon | WiDSellMon | |||
買入總筆數 | TotalBidNumber | INT | TotBidNum | TotBidNum | |||
賣出總筆數 | TotalOfferNumber | INT | TotSellNum | TotSellNum | |||
買入委托成交最大等待時間 | MaxBidDur | INT | MaxBidDur | MaxBidDur | |||
賣出委托最大等待時間 | MaxSellDur | INT | MaxSellDur | MaxSellDur | |||
買方委托價位數 | BidNum | INT | BidNum | BidNum | |||
賣方委托價位數 | SellNum | INT | SellNum | SellNum | |||
入庫時間 | LocalTime | TIME | LocalTime | LocalTime | LocalTime | LocalTime | LocalTime |
消息序列号 | SeqNo | INT | SeqNo | SeqNo | SeqNo | SeqNo | SeqNo |
委托賣量50檔 | OfferOrders | INT[] | OrderQty1..OrderQty50(OrderQueue.csv) | OrderQty1..OrderQty50(mdl_6_28_1.csv) | OrderQty1..OrderQty50(mdl_6_28_1.csv) | OrderQty1..OrderQty50(OrderQueue.csv) | OrderQty1..OrderQty50(OrderQueue.csv) |
委托買量50檔 | BidOrders | INT[] | OrderQty1..OrderQty50(OrderQueue.csv) | OrderQty1..OrderQty50(mdl_6_28_2.csv) | OrderQty1..OrderQty50(mdl_6_28_2.csv) | OrderQty1..OrderQty50(OrderQueue.csv) | OrderQty1..OrderQty50(OrderQueue.csv) |
2.2 逐筆委托資料
- 深交所資料(總共 12 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2012.10 - 2016.05.06(Order.csv) | 2016.05.07 - 至今(mdl_6_33_0.csv) |
頻道代碼 | ChannelNo | INT | SetNo | ChannelNo |
委托索引 | ApplSeqNum | LONG | RecNo | ApplSeqNum |
行情類别 | MDStreamID | SYMBOL | MDStreamID | |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | |
委托價格 | Price | DOUBLE | Price | Price |
委托數量 | OrderQty | INT | OrderQty | OrderQty |
買賣方向 | Side | SYMBOL | FunctionCode | Side |
報價時間 | TradeTime | TIMESTAMP | OrderEntryTime | TransactTime |
委托類别 | OrderType | SYMBOL | OrderKind | OrdType |
入庫時間 | LocalTime | TIME | LocalTime | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo | SeqNo |
- 上交所資料(總共 13 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2021.06.07 - 至今(mdl_4_19_0.csv) |
資料狀态 | DataStatus | INT | DataStatus |
委托序号 | ApplSeqNum | LONG | OrderIndex |
頻道代碼 | ChannelNo | INT | OrderChannel |
證券代碼 | SecurityID | SYMBOL | SecurityID |
委托時間 | TradeTime | TIMESTAMP | OrderTime |
訂單類型 | OrderType | SYMBOL | OrderType |
原始訂單号 | OrderNO | INT | OrderNO |
委托價格 | Price | DOUBLE | OrderPrice |
委托數量 | OrderQty | INT | Balance |
委托辨別 | Side | SYMBOL | OrderBSFlag |
業務序列号 | BizIndex | LONG | BizIndex |
入庫時間 | LocalTime | TIME | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo |
- 滬深資料合并(總共 16 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 深交所 2012.10 - 2016.05.06(Order.csv) | 深交所 2016.05.07 - 至今(mdl_6_33_0.csv) | 上交所 2021.06.07 - 至今(mdl_4_19_0.csv) |
頻道代碼 | ChannelNo | INT | SetNo | ChannelNo | OrderChannel |
委托索引 | ApplSeqNum | LONG | RecNo | ApplSeqNum | OrderIndex |
行情類别 | MDStreamID | SYMBOL | MDStreamID | ||
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | ||
委托價格 | Price | DOUBLE | Price | Price | OrderPrice |
委托數量 | OrderQty | INT | OrderQty | OrderQty | Balance |
買賣方向 | Side | SYMBOL | FunctionCode | Side | OrderBSFlag |
報價時間 | TradeTime | TIMESTAMP | OrderEntryTime | TransactTime | OrderTime |
委托類别 | OrderType | SYMBOL | OrderKind | OrdType | OrderType |
入庫時間 | LocalTime | TIME | LocalTime | LocalTime | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo | SeqNo | SeqNo |
委托訂單号 | OrderNO | INT | OrderNO | ||
資料狀态 | DataStatus | INT | DataStatus | ||
業務序列号 | BizIndex | LONG | BizIndex | ||
交易所名稱 | Market | SYMBOL | “SZ“ | “SZ“ | “SH“ |
2.3 逐筆成交資料
- 深交所資料(總共 14 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2010.05 - 2016.05.06(Trade.csv) | 2016.05.07 - 至今(mdl_6_36_0.csv) |
頻道代碼 | ChannelNo | INT | SetNo | ChannelNo |
消息記錄号 | ApplSeqNum | LONG | RecNo | ApplSeqNum |
行情類别 | MDStreamID | SYMBOL | MDStreamID | |
買方委托索引 | BidApplSeqNum | LONG | BuyOrderRecNo | BidApplSeqNum |
賣方委托索引 | OfferApplSeqNum | LONG | SellOrderRecNo | OfferApplSeqNum |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | |
委托價格 | TradPrice | DOUBLE | Price | LastPx |
委托數量 | TradeQty | DOUBLE | TradeQty | LastQty |
成交代碼 | ExecType | SYMBOL | FunctionCode | ExecType |
成交時間 | TradeTime | TIMESTAMP | TradeTime | TransactTime |
接收時間戳 | LocalTime | TIME | LocalTime | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo | SeqNo |
成交類别 | OrderKind | SYMBOL | OrderKind |
- 上交所資料(總共 14 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 2021.04.25 以前(Transaction.csv) | 2021.04.26 - 至今(Transaction.csv) |
資料狀态 | DataStatus | INT | DataStatus | DataStatus |
消息記錄号 | ApplSeqNum | LONG | TradeIndex | TradeIndex |
頻道代碼 | ChannelNo | INT | TradeChan | TradeChan |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID |
成交時間 | TradeTime | TIMESTAMP | TradTime | TradTime |
委托價格 | TradPrice | DOUBLE | TradPrice | TradPrice |
委托數量 | TradeQty | DOUBLE | TradVolume | TradVolume |
成交金額 | TradeMoney | DOUBLE | TradeMoney | TradeMoney |
買方委托索引 | BidApplSeqNum | LONG | TradeBuyNo | TradeBuyNo |
賣方委托索引 | OfferApplSeqNum | LONG | TradeSellNo | TradeSellNo |
内外盤标志 | TradeBSFlag | SYMBOL | TradeBSFlag | TradeBSFlag |
業務序列号 | BizIndex | LONG | BizIndex | |
接收時間戳 | LocalTime | TIME | LocalTime | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo | SeqNo |
- 滬深資料合并(總共 19 列)
字段含義 | 入庫字段名 | 入庫資料類型 | 深交所 2010.05 - 2016.05.06(Trade.csv) | 2016.05.07 - 至今(mdl_6_36_0.csv) | 上交所 2021.04.25 以前(Transaction.csv) | 2021.04.26 - 至今(Transaction.csv) |
頻道代碼 | ChannelNo | INT | SetNo | ChannelNo | TradeChan | TradeChan |
消息記錄号 | ApplSeqNum | LONG | RecNo | ApplSeqNum | TradeIndex | TradeIndex |
行情類别 | MDStreamID | SYMBOL | MDStreamID | |||
買方委托索引 | BidApplSeqNum | LONG | BuyOrderRecNo | BidApplSeqNum | TradeBuyNo | TradeBuyNo |
賣方委托索引 | OfferApplSeqNum | LONG | SellOrderRecNo | OfferApplSeqNum | TradeSellNo | TradeSellNo |
證券代碼 | SecurityID | SYMBOL | SecurityID | SecurityID | SecurityID | SecurityID |
證券代碼源 | SecurityIDSource | SYMBOL | SecurityIDSource | |||
委托價格 | TradPrice | DOUBLE | Price | LastPx | TradPrice | TradPrice |
委托數量 | TradeQty | DOUBLE | TradeQty | LastQty | TradVolume | TradVolume |
成交代碼 | ExecType | SYMBOL | FunctionCode | ExecType | ||
成交時間 | TradeTime | TIMESTAMP | TradeTime | TransactTime | TradTime | TradTime |
接收時間戳 | LocalTime | TIME | LocalTime | LocalTime | LocalTime | LocalTime |
接收序列号 | SeqNo | LONG | SeqNo | SeqNo | SeqNo | SeqNo |
資料狀态 | DataStatus | INT | DataStatus | DataStatus | ||
成交金額 | TradeMoney | DOUBLE | TradeMoney | TradeMoney | ||
内外盤标志 | TradeBSFlag | SYMBOL | TradeBSFlag | TradeBSFlag | ||
業務序列号 | BizIndex | LONG | BizIndex | |||
成交類别 | OrderKind | SYMBOL | OrderKind | |||
交易所名稱 | Market | SYMBOL | “SZ“ | “SZ“ | “SH“ | “SH“ |
2.4 去重方案
- 為避免重複送出任務或重複導入資料每次導入前,應将庫内已有的對應日期的資料删除
- 為避免當天資料中存在重複,将當天市場所有資料(一個大 csv)讀入記憶體,使用 isDuplicated([...], LAST) 函數進行去重後再導入資料庫
資料源 | isDuplicated 去重字段 |
Level-2 快照行情 | TradeTime, SecurityID, ImageStatus |
逐筆委托 | ChannelNo, ApplSeqNum |
逐筆快照 | ChannelNo, ApplSeqNum |
3. 子產品介紹
easyTLDataImport 子產品主要包含資料表結構、資料庫和分區表建立和資料導入三部分。
3.1 資料表結構
tbSchema 檔案夾下的子產品是根據本文第二章節中的合并規則整理的資料結構。該檔案夾包含以 CsvSchema.dos 和 CsvSchema.dos 結尾的兩種子產品檔案,作用如下:
- CsvSchema.dos 用于指定 DolphinDB 讀取 csv 檔案時的資料格式
- Schema.dos 用于指定資料存入資料庫的資料格式
3.2 資料庫和分區表建立
資料庫和分區表建立包括兩個子產品檔案:createDB.dos 和 createTB.dos。
- createDB.dos 用于建立存儲通聯資料的資料庫
- createTB.dos 用于建立存儲通聯資料的分布式表
基于客戶的實踐經驗,确定了如下的分區方案:
滬深是否分開存儲 | 分區方案 | 分區列 | 排序列 |
滬深分開存儲 | 時間次元按天分區 + 證券代碼次元 HASH 25 分區 | TradeTime 和 SecurityID | SecurityID + TradeTime |
滬深合并存儲 | 時間次元按天分區 + 證券代碼次元 HASH 50 分區 | TradeTime 和 SecurityID | Market+SecurityID+TradeTime |
3.3 資料導入
資料導入部分包含 loadOneDayData 檔案夾和 loadTLData.dos,作用如下:
- loadOneDayData 包含了 loadOneDaySnapshot.dos 、loadOneDayEntrust.dos、loadOneDayTrade.dos 三個子產品檔案,分别用于導入通聯一天的行情快照、逐筆委托和逐筆成交資料。
- loadTLData.dos 用于導入指定目錄下的所有通聯資料,是對前面所有子產品的整合。在應用層面,使用者隻需要了解該子產品中的主要函數即可。
下面列出 loadTLData.dos 子產品中的主要函數。
3.3.1 autoLoadTongLianData
文法
autoLoadTongLianData(fileDir, dataSource, dbName="dfs://TL_Level2", tableName=NULL, market="ALL", startDate=NULL, endDate=NULL, parallel=1, initialDB=false, initialTB=false)
參數
- fileDir 指定的存放資料的路徑,該目錄下必須有一層目錄是形如 “20221201” 的日期。
- dataSource 資料源,隻能 “TLSnapshot”, “TLEntrsut“, “TLTrade“ 三選一
- dbName 資料庫名稱,預設 ”dfs://TL_Level2“
- tableName 分布式表名稱,如果使用者沒有額外指定表名,則預設表名 “snapshot“, “entrust“, “trade“
- market 交易所,目前隻能 “ALL“, ”SZ“, ”SH“ 三選一。當 market=”ALL” 時,會将滬深的資料全部導入一張名為 tableName 的分布式表;否則,會以分開存儲的形式建立名為 tableName+market 的一張分布表(比如 ”snapshotSZ“)并隻導入 market 一個交易所的資料。
- startDate 字元串,導入資料的起始日期,比如 “20220101”(包括這一天)。若 startDate=NULL,則對起始日期不做判斷。
- endDate 字元串,導入資料的結束日期,比如 “20221231”(包括這一天)。若 endDate=NULL,則對結束日期不做判斷。
- parallel 并行度,控制背景送出的任務數目
- initialDB 一個布爾值,是否需要初始化資料庫。如果已經存在名為 dbName 的資料庫,當 initialDB=true 時,會删除原來的資料庫并重新建立;否則會保留原來的資料庫并輸出 "[dbName] 資料庫已經存在" 的提示
- initialTB 一個布爾值,是否需要初始化分布式表。如果在 dbName 資料庫下已經存在名為 tbName 的表,當 initialTB=true 時,會删除原來的表并重新建立;否則會保留原來的表并輸出 "資料庫 [dbName] 已經存在表 [tbName]" 的提示。
詳情
将 fileDir 路徑下從 startDate 到 endDate 日期的 dataSource 資料導入 dbName 資料庫中的 tableName 表裡
3.3.2 getJobStatus
文法
getJobStatus(jobid)
參數
jobid 背景任務描述
詳情
查詢背景任務中任務描述為 jobid 的任務狀态
3.3.3 getJobDetails
文法
getJobDetails(jobid)
參數
jobid 背景任務描述
詳情
輸出背景任務中任務描述為 jobid 的中間資訊
4. 異常處理
對于導入過程中可能出現的問題,會在日志中輸出對應的報錯提示資訊。
異常情況 | 輸出資訊 |
建立資料庫時,名為 dbName 的資料庫已經存在且 initialDB=false | {"code": "warning","message": "[dbName] 資料庫已經存在"} |
建立分布式表時,名為 tableName 的表已經存在且 initialDB=false | {"code": "warning","message": "資料庫 [dbName] 已經存在表 [tableName]"} |
資料導入時,fileDir 目錄下沒有形如 “20221201” 的檔案夾 | {"code": "warning","message": "[fileDir] 路徑下沒有找到指定日期的檔案夾,請确認檔案路徑"} |
資料導入時,dataSource 不是 "TLSnapshot", "TLEntrust", "TLTrade" 三者之一 | {"code": "error","message": "資料源 [dataSource] 暫時不支援"} |
資料導入時,market 不屬于 “ALL“, ”SZ“, ”SH“ | {"code": "error","message": "市場 [market] 暫時不支援"} |
資料導入時,startDate 和 endDate 不是 NULL 或者形如 “20220101” 的字元串 | {"code": "error","message": "開始日期 [startDate] 格式有誤"}{"code": "error","message": "結束日期 [endDate] 格式有誤"} |
實際 csv 檔案的資料列數和 CsvSchema.dos 子產品裡面預設的表結構的列數不一緻 | {"code": "error","message": "[csvPath] 的資料格式有誤,列數不比對"} |
日期檔案夾下,沒有對應的 csv 檔案 | {"code": "error","message": "深交所 [day] 日期的 [csvNames] 的 csv 檔案不全或者不存在"}{"code": "error","message": "上交所 [day] 日期的 [csvNames] 的 csv 檔案不全或者不存在"} |
其他錯誤【通過 try{}catch(ex){} 捕獲異常】 | {"code": "error","message": 輸出報錯資訊 ex} |
5. 使用示例
- 第一步:使用者按照第 1 章檔案結構中的要求解壓并準備好資料。假設資料放在 /hdd/hdd1/factorCalDev/server/TLData/ 目錄下,檔案結構如下圖:
- 第二步:将子產品同步到 DolphinDB 的 sever/modules 的目錄下。
- 第三步:載入子產品和導入資料方法如下:
use DolphinDBModules::easyTLDataImport::loadTLData
// 登陸賬戶
login("admin", "123456")
// 設定檔案目錄
fileDir = "/hdd/hdd1/factorCalDev/server/TLData/"
/** 滬深合并*/
// 導入快照資料,單線程
jobid1 = autoLoadTongLianData(fileDir=fileDir, dataSource="TLSnapshot", parallel=1)
getJobStatus(jobid1) // 檢視任務狀态
// 導入逐筆委托,3 并發
jobid2 = autoLoadTongLianData(fileDir=fileDir, dataSource="TLEntrust", parallel=3)
getJobStatus(jobid2) // 檢視任務狀态
// 導入逐筆成交,3 并發
jobid3 = autoLoadTongLianData(fileDir=fileDir, dataSource="TLTrade", parallel=3)
getJobStatus(jobid3) // 檢視任務狀态
- 第四步:查詢任務狀态。
(1)使用 getJobStatus(jobid) 可以查詢任務狀态,當 endTime 有值的時候表示任務結束。例如:
getJobStatus(jobid3)
(2)使用 getJobDetails(jobid) 可以查詢任務的中間資訊。例如:
getJobDetails(jobid3)
(3)可以通過查詢日志内容,檢視任務執行結果。例如:
cat dolphindb.log | grep message
- 第五步:查詢資料。
(1)快照資料
select * from loadTable("dfs://TL_Level2", "snapshot") limit 10
(2)逐筆委托
select * from loadTable("dfs://TL_Level2", "entrust") limit 10
(3)逐筆成交
select * from loadTable("dfs://TL_Level2", "trade") limit 10
6. 注意事項
6.1 資料檔案路徑 fileDir的設定
在子產品中資料檔案查找的方法如下:
- 從 fileDir 目錄下遞歸查找所有由 8 位數字組成的檔案夾(即形如 “20221201” 的日期)。
- 再将找到的所有日期和 startDate、endDate 進行字元串比較,進而達到導入資料日期篩選的目的。
- 最後在每個日期檔案夾下,遞歸查找所有以 csv 結尾的檔案,進而擷取該日期下的所有 csv 檔案的絕對路徑。
因為第一步是查找所有 8 位數字組成的檔案夾,是以 autoLoadTongLianDataTest 函數的 fileDir 的路徑下必須有一層目錄是以形如 “20221201” 的日期命名。
是以如果使用者想要導入一天的資料,需要通過 startDate、endDate 參數控制導入日期,而不是通過 fileDir 參數。
以上一章第五步圖中的檔案結構為例,假設隻導入 2021.12.01 這一天的資料。不能如此設定導入日期:fileDir = "/hdd/hdd1/factorCalDev/server/TLData/2021/20211201"。否則會因為該目錄下隻有 csv 而找不到日期檔案夾。
正确用法如下:
// 滬深分開存儲:上交所, 導入快照資料,單線程,導入20211201 一天的資料
fileDir = "/hdd/hdd1/factorCalDev/server/TLData/" // 或者 fileDir = "/hdd/hdd1/factorCalDev/server/TLData/2021/"
jobid1 = autoLoadTongLianData(fileDir=fileDir, dataSource="TLSnapshot", dbName="dfs://TL_SH_Level2", market="SH", startDate="20211201", endDate="20211201")
getJobStatus(jobid1) // 檢視任務狀态
6.2 最低資源配置(并行度 parallel 的設定)
6.2.1 快照行情導入資源使用情況
通聯資料的快照行情資料和最優買賣盤前 50 筆委托資料是兩個分開的 csv 檔案。為将二者結合,是以先将快照行情資料和最優買賣盤前 50 筆委托資料進行左連接配接後,再進行入庫。
以滬深合并存儲的方式導入深交所一天的快照資料為例,具體實作方案如下:
(1)将一天的單市場的快照行情資料和最優買賣盤前 50 筆委托資料的 csv 檔案全部讀入 DolphinDB 資料庫中。此步驟中:
- 2023.02.16 的深交所快照資料 mdl_6_28_0.csv 共有 13,608,508 行 89 列,讀入後占用記憶體約 7.1 GB;
- 最優賣價前 50 筆委托資料 mdl_6_28_1.csv 共有 13,608,508 行 62 列,讀入後占用記憶體約 3.5 GB;
- 最優買價前 50 筆委托資料 mdl_6_28_2.csv 共有 13,611,993 行 62 列,讀入後占用記憶體約 3.5 GB。
(2)将資料處理成滬深合并的表結構,包括将 10 檔量價資料和 50 檔委托資料合并組成 array vector,并将上交所有的字段但深交所沒有的字段用空值 NULL 填充。此步驟中:
- array vector + 填充 NULL 值後的快照表總共 13,608,508 行 60 列,占用記憶體約 8.7 GB;
- 最優賣價前 50 筆委托總共 13,608,508 行 4 列,讀入後占用記憶體約 2.8 GB;
- 最優買價前 50 筆委托總共 13,611,993 行 4 列,占用記憶體約 2.8 GB)
(3)根據 TradeTime / SecurityID / ImageStatus 三個字段對資料進行去重。此步驟中:
- 去重後的快照表總共 13,608,508 行 60 列,占用記憶體約 8.7 GB;
- 最優賣價前 50 筆委托總共 13,608,508 行 4 列,讀入後占用記憶體約 2.8 GB;
- 最優賣價前 50 筆委托總共 13,611,993 行 4 列,占用記憶體約 2.8 GB)
(4)根據 TradeTime / SecurityID / ImageStatus 三個字段将買賣的 50 檔資料進行左連接配接。此步驟中:
- 連接配接後的買賣 50 檔委托表總共 13,608,508 行 5 列,占用記憶體約 5.4 GB。
- 将資料根據股票代碼 SecurityID 的哈希值分成 50 份,每一份分别和最優買賣盤前 50 筆委托資料進行左連接配接,将連接配接後的資料直接加入資料庫。該任務通過 ploop 實作并發執行。此步驟中:
- 根據 hashBucket(SecurityID, 50) 算出哈希值,在快照資料中取出對應哈希值的資料。比如哈希值為 40 的快照資料共 343,461 行 60 列,占用記憶體約 225 MB;
- 最優買賣盤前 50 筆委托資料共 343,461 行 5 列,占用記憶體約 144 MB;
- 左連接配接後結果表共 343,461 行 62 列,占用記憶體約 364 MB,直接向庫内 append 這部分資料)
(5)深交所和上交所串行導入,先完成深交所一天資料的導入,再按上述流程導入上交所一天的快照資料。
注意:因為快照資料的導入需要讀入整個 csv,再記憶體裡并發進行 join 和寫入操作,是以記憶體消耗較高。
經測試,單并發導入快照資料占用記憶體資源約:53 GB
6.2.2 逐筆委托導入資源使用情況
為了實作資料去重的目的,會将一個市場一天的逐筆委托資料全部讀入記憶體,進行去重後,再進行入庫。
以滬深合并存儲的方式導入深交所一天的逐筆委托為例,具體實作方案如下:
(1)将一天的單市場的逐筆委托的 csv 檔案全部讀入 DolphinDB 資料庫中。此步驟中:
- 2023.02.16 的深交所逐筆委托資料 mdl_6_33_0.csv 共有 99,798,969 行 12 列,讀入後占用記憶體約 5.7 GB。
(2)将逐筆成交資料處理成滬深合并的表結構,包括将上交所有的字段但深交所沒有的字段用空值 NULL 填充和根據 ChannelNo , ApplSeqNum 兩個字段進行去重。此步驟中:
- 填充 NULL 值 + 去重後的逐筆委托表總共 99,798,969 行 16 列,占用記憶體約 13.1 GB。
(3)将處理完的深交所逐筆委托資料導入資料庫。
- 深交所和上交所串行導入,先導完一天深交所,再按上述流程導入一天上交所快照資料。
子產品中的資料庫采用 TSDB 存儲引擎,其寫入政策是:
- 資料先寫入 Cache Engine,在 Cache Engine 内進行分區。
- 按照 sortColumns 進行排序。
- 當寫入的資料達到 TSDBCacheEngineSize 時,進行刷盤。此時:
- 若有資料繼續寫入,系統會再配置設定一塊記憶體來接收新資料;
- 若不滿足該條件, 超過十分鐘會強制刷盤。
是以使用 TSDB 引擎導入大量資料的時候,使用 LevelFileIndexCache,TSDBCacheEngine,異步排序,背景的 flush 等環節都會造成記憶體使用的增加。
注意:為了能夠按照 ChannelNo , ApplSeqNum 這兩個字段對資料進行去重,需要讀入整個 csv 讀入記憶體,使用 TSDB 引擎持續導入大量資料。是以導入時記憶體消耗較高。
經測試,單并發導入逐筆委托資料占用記憶體資源約:55 GB
6.2.3 逐筆成交導入資源使用情況
為了實作資料去重的目的,會将一個市場一天的逐筆成交資料全部讀入記憶體,進行去重後,再進行入庫。
以滬深合并存儲的方式導入深交所一天的逐筆成交為例,具體實作方案如下:
(1)将一天的單市場的逐筆成交的 csv 檔案全部讀入 DolphinDB 資料庫中。此步驟中:
- 2023.02.16 的深交所逐筆成交資料 mdl_6_36_0.csv 共有 91,230,221 行 13 列,讀入後占用記憶體約 6.4 GB。
(2)将逐筆成交資料處理成滬深合并的表結構,包括将上交所有的字段但深交所沒有的字段用空值 NULL 填充和根據 ChannelNo , ApplSeqNum 兩個字段進行去重。此步驟中:
- 填充 NULL 值 + 去重後的逐筆委托表總共 91,230,221 行 19 列,占用記憶體約 15.7 GB。
(3)将處理完的深交所逐筆委托資料導入資料庫。
- 深交所和上交所串行導入,先導完一天深交所,再按上述流程導入一天上交所快照資料。
注意:為了能夠按照 ChannelNo , ApplSeqNum 這兩個字段對資料進行去重,需要讀入整個 csv 讀入記憶體,使用 TSDB 引擎持續導入大量資料。是以導入時記憶體消耗較高。
經測試,單并發導入逐筆成交資料占用記憶體資源約:58 GB
綜上,控制并發的參數 parallel 需要根據實際的記憶體情況設定。**建議配置 maxMemSize 至少為 64 GB,**這超過了社群版 License 記憶體的限制,可以前往 DolphinDB 官網申請企業版試用授權許可。
7. 性能測試
7.1 測試環境
單節點 8 核 256 GB 的環境來測試導入性能,環境配置資源如下:
軟硬體項 | 資訊 |
OS(作業系統) | CentOS Linux 7 (Core) |
核心 | 3.10.0-1160.el7.x86_64 |
CPU | Intel(R) Xeon(R) Gold 5220R CPU @ 2.20GHz |
記憶體 | 256 GB |
磁盤 | 2 塊 SSD,3.84 TB 固态硬碟 SATA 讀取密集型 6 Gbps 512 2.5 英寸 Flex Bay AG 硬碟 1 DWPD單盤測試随機寫- 平均寫入IO:266MB/s |
7.2 性能結果
隻測試了通聯資料滬深合并存儲的導入性能:
資料源 | 資料量 | 資料天數 | 耗時(min) | RPS(W/s) | 吞吐量(MB/s) | 原始 csv 大小(GB) | 單副本磁盤占用大小(GB) | 壓縮比 | 并發數 | 最大記憶體占用(GB) |
snapshot | 475,469,670 | 20 | 49.63 | 15.97 | 153.86 | 447.40 | 37.41 | 11.96 | 7 | 185 |
entrust | 2,712,071,019 | 20 | 28.12 | 160.73 | 131.45 | 216.60 | 60.00 | 3.61 | 7 | 240 |
trade | 2,067,012,875 | 20 | 24.41 | 141.14 | 132.17 | 189.02 | 49.05 | 3.85 | 7 | 253 |
7.3 吞吐量提升建議
如需提高資料導入的吞吐量,可參考以下優化政策:
(1)通過設定參數 parallel,增加背景導入任務的資料,提高導入的并行度。注意環境記憶體資源的使用。
(2)使用讀寫性能更好的硬碟。
附錄
https://gitee.com/dolphindb/Tutorials_CN/blob/master/script/Module_easyTLDataImport/DolphinDBModules.zip