文件
開啟 Studio

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

取得回測報告集合

將選股條件排出所有的組合並進行回測,方便找出最好條件的交集結果。

參數

conditions dict

選股條件集合,key 為條件名稱,value 為條件變數,ex:{'c1':c1, 'c2':c2}

hold_until dict

設定訊號進出場語法糖參數,預設為不使用。ex:{'exit':exit, 'stop_loss':0.1}

*args tuple 預設 ()

finlab.backtest.sim() 回測參數設定。

**kwargs dict 預設 {}

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()

繪製折線圖指標分群棒狀圖

bar
bar

ex2:

report_collection.plot_stats('bar').show()

繪製指標分群棒狀圖

bar
bar

ex3:

report_collection.plot_stats('heatmap')

繪製指標分級熱力圖,數值越大為排名越前面,avg_score為指標平均分數,分數越高為評價較正向的策略。

heatmap
heatmap

比較多份回測報告

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)

回測組合比較報告

判斷策略組合數據優劣,從策略海中快速找到體質最強的策略。 也可以觀察在同條件下的策略疊加更多條件後會有什麼變化?

參數

reports dict

回測物件集合,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

策略指標比較報表視覺化

參數

mode str 預設 'bar'

繪圖模式。'bar' - 指標分群棒狀圖。'heatmap' - 指標分級熱力圖。

heatmap_sort_by str or list of str 預設 'avg_score'

heatmap 降冪排序的決定欄位

indicators list

要顯示的特定指標欄位,預設為將指標全部顯示

回傳

plotly.graph_objects.Figure

長條圖

pd.DataFrame

熱力圖

範例

ex1:

繪製指標分群棒狀圖

bar
bar

ex2:

繪製指標分級熱力圖。

'avg_score': 各指標加總後的平均分數,分數越高為整體評價較正向的策略。

預設以avg_score為排序,數值越大為排名越前面,分數越高為整體評價較優的策略。

heatmap
heatmap
plot_creturns
函式

plot_creturns

plot_creturns() -> go.Figure

繪製策略累積報酬率

比較策略淨值曲線變化

回傳

plotly.graph_objects.Figure

折線圖

範例

line
line

常見問題

熱力圖的 avg_score 是什麼?

plot_stats('heatmap') 會把每個指標換成各策略之間的百分位排名,avg_score 是所有指標排名的平均,分數越高代表整體表現越好。熱力圖預設依 avg_score 由高到低排序,可用 heatmap_sort_by 改成其他欄位或多個欄位。

plot_stats() 回傳什麼?

'bar' 回傳 plotly 的 Figure,要呼叫 .show() 才會畫出來;'heatmap' 回傳加上顏色的 pd.DataFrame,在 Jupyter 直接顯示;其他 mode 回傳 None。

下一步

  • 策略參數優化 為什麼要優化、12 種績效指標怎麼讀、如何避免過度配適、搭配停損停利的技巧。
  • 歷史回測 sim() 的換股頻率、停損停利與交易成本設定。
  • 完整策略開發流程 從研究、優化到實盤的實戰步驟。

原始碼在 GitHub。

↑↓ 選擇 Enter 開啟 Esc 關閉