API 參考
finlab.optimize
本頁內容5
finlab.optimize 把你寫好的幾個選股條件排出所有組合,每個組合各跑一次回測,再並排比較績效。適合用在手上有技術面、基本面、籌碼面好幾個條件,想知道哪幾個放在一起效果最好的時候。
選哪個函式
| 你想做的事 | 用這個 |
|---|---|
| 把多個條件排出所有組合,各自回測 | sim_conditions() |
| 並排比較幾份已經跑好的回測 | ReportCollection |
| 拿到各組合的績效指標表 | report_collection.get_stats() |
| 用棒狀圖或熱力圖比較指標 | report_collection.plot_stats() |
| 比較各組合的累積報酬曲線 | report_collection.plot_creturns() |
測試所有條件組合
把條件放進字典交給 sim_conditions(),字典的 key 會成為組合的名稱(例如 'c1 & c3')。其餘參數會原樣交給 backtest.sim()。
from finlab import data
from finlab.optimize.combinations import sim_conditions
close = data.get("price:收盤價")
rev = data.get('monthly_revenue:當月營收')
營業利益成長率 = data.get('fundamental_features:營業利益成長率')
# 定義 3 個條件
c1 = (close > close.average(20)) & (close > close.average(60))
c2 = 營業利益成長率 > 0
c3 = rev.average(3) / rev.average(12) > 1.1
exits = close < close.average(20)
conditions = {'c1': c1, 'c2': c2, 'c3': c3}
# 測試所有組合(共 7 種:c1, c2, c3, c1&c2, c1&c3, c2&c3, c1&c2&c3)
report_collection = sim_conditions(
conditions=conditions,
hold_until={'exit': exits, 'stop_loss': 0.1},
resample='M',
position_limit=0.1,
upload=False,
)
# 視覺化比較
report_collection.plot_stats('heatmap') # 熱力圖
report_collection.plot_stats('bar').show() # 棒狀圖
report_collection.plot_creturns().show() # 累積報酬率折線圖n 個條件會跑 2^n - 1 次回測:每個條件單獨一次,再加上所有 & 交集。季頻條件會先換成財報公布日再組合;某個組合回測失敗時會記錄下來並跳過,不會中斷其他組合。
finlab.optimize.sim_conditions
sim_conditions(conditions, hold_until, *args, **kwargs) -> ReportCollection取得回測報告集合
將選股條件排出所有的組合並進行回測,方便找出最好條件的交集結果。
參數
conditionsdict選股條件集合,key 為條件名稱,value 為條件變數,ex:
{'c1':c1, 'c2':c2}hold_untildict設定訊號進出場語法糖參數,預設為不使用。ex:
{'exit':exit, 'stop_loss':0.1}*argstuple預設()finlab.backtest.sim()回測參數設定。**kwargsdict預設{}finlab.backtest.sim()回測參數設定。
回傳
finlab.optimize.combination.ReportCollection回測數據報告
範例
from finlab import data
from finlab.backtest import sim
from finlab.optimize.combinations import sim_conditions
close = data.get("price:收盤價")
pe = data.get('price_earning_ratio:本益比')
rev=data.get('monthly_revenue:當月營收').index_str_to_date()
rev_ma3=rev.average(3)
rev_ma12=rev.average(12)
c1 = (close > close.average(20)) & (close > close.average(60))
c2 = (close == close.rolling(20).max())
c3 = pe < 15
c4 = rev_ma3/rev_ma12 > 1.1
c5 = rev/rev.shift(1) > 0.9
exits = close < close.average(20)
conditions = {'c1':c1, 'c2':c2, 'c3':c3, 'c4':c4, 'c5':c5}
report_collection = sim_conditions(conditions=conditions, hold_until={'exit':exits, 'stop_loss':0.1}, resample='M', position_limit=0.1, upload=False)
# 策略分組指標報告
# print(report_collection.stats)
report_collection.plot_creturns().show()
report_collection.plot_stats('bar').show()
report_collection.plot_stats('heatmap')視覺化範例
ex1:
report_collection.plot_creturns().show()
繪製折線圖指標分群棒狀圖

ex2:
report_collection.plot_stats('bar').show()
繪製指標分群棒狀圖

ex3:
report_collection.plot_stats('heatmap')
繪製指標分級熱力圖,數值越大為排名越前面,avg_score為指標平均分數,分數越高為評價較正向的策略。

比較多份回測報告
sim_conditions() 回傳的就是 ReportCollection。你也可以自己把幾份回測報告放進字典建立一個,用同樣的方法比較:
from finlab import data, backtest
from finlab.optimize.combinations import ReportCollection
close = data.get('price:收盤價')
position = close >= close.rolling(300).max()
collection = ReportCollection({
'月換股': backtest.sim(position, resample='M', upload=False),
'週換股': backtest.sim(position, resample='W', upload=False),
})
collection.get_stats()get_stats() 回傳的表每一欄是一個策略、每一列是一個指標,同時存進 collection.stats;呼叫之前 stats 是 None。
finlab.optimize.ReportCollection
ReportCollection(reports)回測組合比較報告
判斷策略組合數據優劣,從策略海中快速找到體質最強的策略。 也可以觀察在同條件下的策略疊加更多條件後會有什麼變化?
參數
reportsdict回測物件集合,ex:
{'strategy1': finlab.backtest.sim(),'strategy2': finlab.backtest.sim()}
方法與屬性
get_stats
get_stats
get_stats() -> pd.DataFrame取得策略指標比較表
指標欄位說明:
'cagr': 策略年化報酬(複利,CAGR)'daily_sharpe': 策略年化夏普率'daily_sortino': 策略年化索提諾比率'max_drawdown': 策略報酬率最大回撤率(負向)'avg_drawdown': 策略平均回撤(負向)'ytd': 今年度策略報酬率'win_ratio': 每筆交易勝率'avg_return': 每筆交易平均獲利率'avg_mae': 每筆交易平均最大不利方向幅度(負向)'avg_bmfe': 最大不利方向發生前的"每筆交易平均最大有利方向幅度",若數值越高,越有機會在停損之前操作停利。'avg_gmfe': 每筆交易平均最大有利方向幅度'avg_mdd': 每筆交易平均的最大回撤率(負向)
回傳
pd.DataFrame策略指標比較報表
plot_stats
plot_stats
plot_stats(mode, heatmap_sort_by, indicators) -> go.Figure | pd.DataFrame | None策略指標比較報表視覺化
參數
modestr預設'bar'繪圖模式。
'bar'- 指標分群棒狀圖。'heatmap'- 指標分級熱力圖。heatmap_sort_bystr or list of str預設'avg_score'heatmap 降冪排序的決定欄位
indicatorslist要顯示的特定指標欄位,預設為將指標全部顯示
回傳
plotly.graph_objects.Figure長條圖
pd.DataFrame熱力圖
範例
ex1:
繪製指標分群棒狀圖

ex2:
繪製指標分級熱力圖。
'avg_score': 各指標加總後的平均分數,分數越高為整體評價較正向的策略。
預設以avg_score為排序,數值越大為排名越前面,分數越高為整體評價較優的策略。

plot_creturns
plot_creturns
plot_creturns() -> go.Figure繪製策略累積報酬率
比較策略淨值曲線變化
回傳
plotly.graph_objects.Figure折線圖
範例

常見問題
熱力圖的 avg_score 是什麼?
plot_stats('heatmap') 會把每個指標換成各策略之間的百分位排名,avg_score 是所有指標排名的平均,分數越高代表整體表現越好。熱力圖預設依 avg_score 由高到低排序,可用 heatmap_sort_by 改成其他欄位或多個欄位。
plot_stats() 回傳什麼?
'bar' 回傳 plotly 的 Figure,要呼叫 .show() 才會畫出來;'heatmap' 回傳加上顏色的 pd.DataFrame,在 Jupyter 直接顯示;其他 mode 回傳 None。
下一步
原始碼在 GitHub。
這一頁有幫到你嗎?