Block.screener 執行選股
所屬章節:積木 Block 以 2026-08-20 實際執行結果為準(資料日 2026-08-19)
Overview
把一組積木跑成選股結果。多個積木之間是 AND。
api.Block.screener_tw(block_list, pool=None, date='now')
api.Block.screener_us(block_list, date='now')
| 參數 | 型態 | 說明 |
|---|---|---|
block_list |
list[dict] |
con_tw() / con_us() 產生的積木清單,彼此 AND |
pool |
list[str], optional |
股池,僅台股。預設 ['all']。見 股池 |
date |
str |
'now'(預設)、'last',或 'YYYY-MM-DD' |
回傳 dict,四個 key:
| key | 型態 | 說明 |
|---|---|---|
dataframe |
DataFrame |
符合條件的股票,一列一檔,含各積木的中間計算值 |
date |
Timestamp |
這批結果對應的資料日期 |
sig |
DataFrame |
完整訊號矩陣,日期(index)× 股票代號(columns),值為 bool |
code |
str |
等價的可執行 python 程式碼,見 產生的程式碼 |
api.Block 沒有開放 include_values=False,dataframe 一律含中間值。
Manual Sample Input/Output
Example 1:單一積木
input
b1 = api.Block.con_tw('今日收盤價<>開高低P%',
operator='>', ohlc_field='adj_High', percent=3)
r = api.Block.screener_tw([b1])
print(list(r))
print(r['date'], r['dataframe'].shape, r['sig'].shape)
r['dataframe'].head(3)
output
['code', 'dataframe', 'date', 'sig']
2026-08-19 00:00:00 (2343, 8) (1000, 2865)
stock_id sig cond1_sig cond1_close cond1_ohlcData cond1_ohlc_processed cond1_olhc_metrics cond1_comparison_ratio
0 00400A True True 14.7200 14.3600 11.0725 10.7500 1.3294
1 00401A True True 13.3800 13.1500 10.8150 10.5000 1.2372
2 00402A True True 9.7200 9.6300 9.1670 8.9000 1.0603
欄位規則:
stock_id:股票代號sig:最終訊號(全部為True,因為只列出通過的)cond<N>_*:第 N 個積木的中間值。cond1_sig是該積木自己的訊號,其餘欄名由該積木類別決定
sig 是完整矩陣(1000 個交易日 × 2865 檔),不只當日。
Example 2:多積木 AND
input
b1 = api.Block.con_tw('今日收盤價<>開高低P%',
operator='>', ohlc_field='adj_High', percent=3)
b2 = api.Block.con_tw('今日收盤價(開低高)與近D日內最高價<P%',
period=20, percent=5)
print(api.Block.screener_tw([b1])['dataframe'].shape[0], '檔(僅積木1)')
print(api.Block.screener_tw([b2])['dataframe'].shape[0], '檔(僅積木2)')
r = api.Block.screener_tw([b1, b2])
print(r['dataframe'].shape[0], '檔(AND)')
list(r['dataframe'].columns)
output
2343 檔(僅積木1)
1040 檔(僅積木2)
816 檔(AND)
['stock_id', 'sig',
'cond1_sig', 'cond1_close', 'cond1_ohlcData', 'cond1_ohlc_processed',
'cond1_olhc_metrics', 'cond1_comparison_ratio',
'cond2_sig', 'cond2_close', 'cond2_high', 'cond2_rolling_high',
'cond2_distance_pct']
積木數量增加時,cond<N>_* 欄位會累加。
Example 3:date 參數
input
for d in ('now', 'last'):
r = api.Block.screener_tw([b1], date=d)
print(f"date={d!r} -> {r['date']}, {r['dataframe'].shape[0]} 檔")
output
'now':取 ≤ 今天 的最後一個可用日期'last':取矩陣的最後一列,不管是否已過今天- 指定日期字串:取 ≤ 該日期 的最後一個可用日期
盤中執行時 MSMP 只到前一交易日,所以 'now' 與 'last' 通常相同。
兩者會分歧的情況是季頻/月頻積木——那些資料的 index 可能排到未來
(例如 api.MSMP.INDEX['Q'] 最後一筆是 2026-11-16),此時 'last' 會取到未來日期。
Example 4:美股
美股不開放 pool(api.USMSMP 沒有 list)。
input
b = api.Block.con_us('今日收盤價<>開高低P%',
operator='>', field1='Open', percent=1)
r = api.Block.screener_us([b])
print(r['date'], r['dataframe'].shape, r['sig'].shape)
r['dataframe'].head(3)
output
2026-08-18 00:00:00 (1569, 6) (1000, 13169)
stock_id sig cond1_sig cond1_close cond1_rhs cond1_threshold
0 AACG True True 0.9959 0.9605 0.9701
1 AAOZ True True 9.8800 8.4500 8.5345
2 AAPB True True 38.2200 37.6000 37.9760
Example 5:零命中時 dataframe 是 (0, 0)
沒有任何股票通過時,dataframe 是完全空的——連欄位都沒有:
input
b = api.Block.con_us('今日收盤價<>開高低P%',
operator='>', field1='High', percent=3)
r = api.Block.screener_us([b])
print(r['dataframe'].shape, list(r['dataframe'].columns), r['sig'].shape)
output
(收盤價要高於當日最高價的 1.03 倍,本質上不可能成立。)
所以不能無條件存取 r['dataframe']['stock_id'],會 KeyError。安全寫法:
Example 6:選不出股票時,先看 sig 的欄數
「選出 0 檔」有兩種完全不同的意思,看 sig 的欄數就能分辨:
sig 形狀 |
意思 |
|---|---|
(1000, 2865) 但 dataframe 是 (0, 0) |
條件正常,只是當日沒有股票通過 |
(1000, 0) |
訊號矩陣裡根本沒有股票,這個積木壞了 |
input
output
sig 欄數為 0 通常是積木內部把兩個欄位對不起來的矩陣相除或相比
(例如個股矩陣的 columns 是股票代號,另一邊卻是法人類別),
pandas 對齊後交集為空。這是 bug,不是篩選結果。
台股有 20 個積木在 2026-08-19 這天合理地選出 0 檔(孤島晨星、一紅吃三黑、
十字線這類很嚴格的 K 線型態,以及年度股利的緊門檻),它們的 sig 欄數都正常。
Example 7:首次呼叫會下載資料
積木用到的 MSMP 欄位是延遲載入的,第一次碰到某個欄位會即時下載:
正在下載 最高價: 100%|##########| 10.6M/10.6M [00:01<00:00, 5.71MB/s]
下載成功
正在下載 最低價: 100%|##########| 6.63M/6.63M [00:01<00:00, 5.11MB/s]
下載成功
所以同一組積木第一次跑約 6 秒,第二次約 0.8 秒。要量測效能請跑第二次以後。