官方說明文件:https://sinotrade.github.io/tutor/market_data/historical/#ticks-data
所謂的tick,就是看盤軟體中的成交明細資料,而證交所也從2020年3月23日實施逐筆交易,不再是以前盤中每五秒才撮合一次。
也因為成交明細的資料會較多,所以Tick資料一次只能抓一個交易日的資料。
api.ticks參數說明
api.ticks(
contract: BaseContract, #傳入所要抓取ticks資料的Contract
date: str = dt.date.today().strftime("%Y-%m-%d"), #交易日期,預設為程式執行當下的日期
query_type: TicksQueryType = TicksQueryType.AllDay, #預設為抓當天一整天的資料
time_start: typing.Union[str, dt.time] = None, #資料開始時間,預設為None,即不指定開始時間
time_end: typing.Union[str, dt.time] = None, #資料結束時間,預設為None,即不指定結束時間
last_cnt: int = 0, #僅回傳最後X筆資料,預設為0,即回傳所有的資料
timeout: int = 30000, #timeout時間,預設為30000ms
cb: typing.Callable[[Ticks], None] = None
)
使用範例如下:
# TicksQueryType.AllDay 抓交易日期全天tick資料
ticks = api.ticks(
contract=api.Contracts.Stocks["2330"], #指定要抓ticks資料的Contract
date="2021-09-17", #交易日期
)
若只要抓取交易日期中,特定時間區間的資料,可以在參數中指定開始時間及結束時間,範例如下:
# TicksQueryType.RangeTime 抓交易日期,特定時段tick資料
ticks = api.ticks(
contract=api.Contracts.Stocks["2330"], #指定要抓ticks資料的Contract
date="2021-09-17", #交易日期
query_type=sj.constant.TicksQueryType.RangeTime, #指定QueryType為RangeTime
time_start="09:10:00", #開始時間
time_end="09:20:00" #結束時間
)
若只要抓取最後5筆tick資料,範例如下:
# TicksQueryType.LastCount 抓交易日期最後X筆tick資料
last_5_ticks = api.ticks(
contract=api.Contracts.Stocks["2330"], #指定要抓ticks資料的Contract
date="2021-09-17", #交易日期
query_type=sj.constant.TicksQueryType.LastCount, #指定QueryType為LastCount
last_cnt=5 #指定要抓最後5筆tick資料
)
TicksQueryType,只有AllDay、RangeTime及LastCount這三種,使用方式就如同上面的這三個範例,但請注意這三種方式無法混用
,因為api.ticks主要是依照query_type這個參數,去決定要抓哪些資料。
例如:
ticks = api.ticks(
contract=api.Contracts.Stocks["2330"], #指定要抓ticks資料的Contract
date="2021-09-17", #交易日期
query_type=sj.constant.TicksQueryType.RangeTime, #指定QueryType為RangeTime
time_start="09:10:00", #開始時間
time_end="09:20:00", #結束時間
last_cnt=5 #指定要抓最後5筆tick資料,但指定TicksQueryType.RangeTime會忽略此參數
)
因為在query_type這個參數,已經指定QueryType為RangeTime,雖然有指定last_cnt=5,但回傳的資料其實跟第二個範例TicksQueryType.RangeTime一樣。
所回傳的資料為shioaji.data.Ticks物件,屬性說明如下:
屬性 | 值 | 說明 |
---|---|---|
ts | [1631889000000000000] | 時間戳 |
close | [600.0] | 收盤價,即成交價格 |
volume | [57] | 成交量 |
bid_price | [600.0] | 委買價(買進) |
bid_volume | [1107] | 委買量 |
ask_price | [601.0] | 委賣價(賣出) |
ask_volume | [3] | 委賣量 |
跟之前抓到的資料不同的地方在於,所回傳的資料是一個shioaji.data.Ticks物件而非List,也就是把所有的tick資料存在一個物件中,而物件中的屬性內容為List,用來放每一個tick的資料。 | ||
若你用上面的範例並執行print(last_5_ticks),會看到以下的資料內容。 |
Ticks(
ts=[1631885096148332000, 1631885098755243000, 1631885098967648000, 1631885400000000000, 1631889000000000000],
close=[609.0, 609.0, 608.0, 600.0, 600.0],
volume=[1, 1, 1, 22082, 57],
bid_price=[608.0, 608.0, 608.0, 600.0, 600.0],
bid_volume=[298, 298, 297, 1107, 1107],
ask_price=[609.0, 609.0, 609.0, 601.0, 601.0],
ask_volume=[164, 164, 162, 3, 3])
使用api.ticks取得資料,若未經過處理,在閱讀上較為困難,此時可以先把tick資料轉換為DataFram。但因為資料內容格式與之前的格式不同,所以在轉換前要先將物件內容先轉換為Dict
程式範例如下:
df = pd.DataFrame({**last_5_ticks}) #先將Ticks物件轉換為Dict,再傳入DataFrame做轉換
df.ts = pd.to_datetime(df.ts) #將原本的ts欄位中的資料,轉換為DateTime格式並回存
print(df) #將DataFrame的資料輸出至console中
在執行print(df)後,原本的資料內容,已變成下列比較方便閱讀的格式
close bid_price ask_volume ask_price ts bid_volume volume
0 609.0 608.0 164 609.0 2021-09-17 13:24:56.148332 298 1
1 609.0 608.0 164 609.0 2021-09-17 13:24:58.755243 298 1
2 608.0 608.0 162 609.0 2021-09-17 13:24:58.967648 297 1
3 600.0 600.0 3 601.0 2021-09-17 13:30:00.000000 1107 22082
4 600.0 600.0 3 601.0 2021-09-17 14:30:00.000000 1107 57