跳轉到

finlab.report

回測報告模組,Report 物件由 sim() 函數產生,包含完整的回測績效資訊。

使用情境

  • 查看回測績效(年化報酬、夏普率、最大回撤)
  • 分析交易記錄(進出場時間、持有天數、報酬率)
  • 視覺化淨值曲線與回撤
  • 儲存報告供日後查閱
  • 上傳至 FinLab 雲端進行實盤追蹤
  • 執行深度分析(流動性、選股能力、持股分布)

快速範例

基礎用法:產生並查看報告

from finlab import data
from finlab.backtest import sim

# 建立策略並回測
close = data.get('price:收盤價')
position = close > close.average(20)

# 產生回測報告
report = sim(position, resample='M')

# 顯示報告(包含視覺化圖表)
report.display()

取得績效指標

# 取得績效統計(dict)
stats = report.get_stats()
print(f"年化報酬率: {stats['daily_mean'] * 100:.2f}%")
print(f"夏普率: {stats['daily_sharpe']:.2f}")
print(f"最大回撤: {stats['max_drawdown'] * 100:.2f}%")
print(f"勝率: {stats['win_ratio'] * 100:.2f}%")

# 取得結構化績效指標(nested dict)
metrics = report.get_metrics()
print(f"年化報酬率: {metrics['profitability']['annualReturn']:.2%}")
print(f"夏普率: {metrics['ratio']['sharpeRatio']:.2f}")
print(f"最大回撤: {metrics['risk']['maxDrawdown']:.2%}")

查看交易記錄

# 取得所有交易記錄
trades = report.get_trades()
print(f"總交易次數: {len(trades)}")
print(trades.head())

# 篩選獲利交易
profitable_trades = trades[trades['return'] > 0]
print(f"獲利交易比例: {len(profitable_trades) / len(trades):.1%}")

詳細教學

參考 歷史回測教學,了解: - 完整回測流程 - Report 物件的所有方法 - 績效指標解讀 - 交易記錄分析


API Reference

Report

Report 物件由 sim() 函數產生,包含完整的回測績效資訊。

from finlab.backtest import sim

report = sim(position)

Report 物件主要方法

方法 說明 常用程度
display() 顯示完整報告(含視覺化圖表) ⭐⭐⭐⭐⭐
get_stats() 取得績效統計(dict) ⭐⭐⭐⭐⭐
get_metrics() 取得結構化績效指標(nested dict) ⭐⭐⭐⭐⭐
get_trades() 取得交易記錄(DataFrame) ⭐⭐⭐⭐⭐
get_mae_mfe() 取得最大不利/有利偏移 ⭐⭐⭐⭐
position_info() 取得近期持有部位與換股資訊 ⭐⭐⭐⭐
upload() 上傳至 FinLab 雲端 ⭐⭐⭐
run_analysis() 執行深度分析模組 ⭐⭐⭐
display_mae_mfe_analysis() 顯示波動分析圖組 ⭐⭐⭐
to_text() 文字格式的回測摘要 ⭐⭐
to_terminal() 終端 ASCII 圖表顯示 ⭐⭐
to_html() 匯出 HTML 報告 ⭐⭐
to_pickle() / from_pickle() 儲存/載入報告 ⭐⭐

display()

顯示完整回測報告,包含視覺化圖表與績效指標。

使用範例

# 基礎用法
report.display()

# 回傳 plotly figure 物件供進一步客製化
fig = report.display(return_fig=True)
fig.update_layout(title='我的策略回測')
fig.show()

顯示內容: - 淨值曲線(策略 vs 基準) - 回撤曲線 - 績效指標表格(年化報酬、夏普率、最大回撤等)


get_stats()

取得績效統計資料。

簽名get_stats(resample='1d', riskfree_rate=0.02)

回傳dict

使用範例

stats = report.get_stats()

print(f"回測期間: {stats['start']} ~ {stats['end']}")
print(f"年化報酬: {stats['daily_mean'] * 100:.2f}%")
print(f"夏普率: {stats['daily_sharpe']:.2f}")
print(f"索提諾比率: {stats['daily_sortino']:.2f}")
print(f"最大回撤: {stats['max_drawdown'] * 100:.2f}%")
print(f"平均回撤: {stats['avg_drawdown'] * 100:.2f}%")
print(f"勝率: {stats['win_ratio'] * 100:.2f}%")

主要回傳欄位

欄位 說明
start 回測開始日期(str)
end 回測結束日期(str)
daily_mean 年化報酬率
daily_sharpe 夏普率
daily_sortino 索提諾比率
max_drawdown 最大回撤
avg_drawdown 平均回撤
win_ratio 勝率
return_table 年月報酬率表(dict)
drawdown_details 最大回撤詳情

get_metrics()

取得結構化績效指標(nested dict),適合上傳雲端或程式化處理。

簽名get_metrics(stats_=None, riskfree_rate=0.02)

回傳dict,包含以下分類:

使用範例

metrics = report.get_metrics()

# 盈利指標
print(f"年化報酬: {metrics['profitability']['annualReturn']:.2%}")
print(f"Alpha: {metrics['profitability']['alpha']:.4f}")
print(f"Beta: {metrics['profitability']['beta']:.4f}")

# 風險指標
print(f"最大回撤: {metrics['risk']['maxDrawdown']:.2%}")
print(f"VaR: {metrics['risk']['valueAtRisk']:.2%}")

# 比率指標
print(f"夏普率: {metrics['ratio']['sharpeRatio']:.2f}")
print(f"索提諾比率: {metrics['ratio']['sortinoRatio']:.2f}")

# 勝率指標
print(f"勝率: {metrics['winrate']['winRate']:.2%}")

回傳結構

分類 欄位 說明
backtest startDate, endDate, feeRatio, taxRatio, tradeAt, market, freq 回測設定
profitability annualReturn, alpha, beta, avgNStock, maxNStock 盈利指標
risk maxDrawdown, avgDrawdown, avgDrawdownDays, valueAtRisk, cvalueAtRisk 風險指標
ratio sharpeRatio, sortinoRatio, calmarRatio, volatility, profitFactor, tailRatio 比率指標
winrate winRate, m12WinRate, expectancy, mae, mfe 勝率指標
liquidity capacity, disposalStockRatio, warningStockRatio, fullDeliveryStockRatio 流動性指標

get_trades()

取得所有交易記錄的詳細資訊。

回傳pd.DataFrame

使用範例

trades = report.get_trades()

# 分析交易表現
print(f"總交易次數: {len(trades)}")
print(f"平均報酬率: {trades['return'].mean():.2%}")
print(f"勝率: {(trades['return'] > 0).mean():.2%}")

# 篩選大賺或大賠的交易
big_wins = trades[trades['return'] > 0.2]
big_losses = trades[trades['return'] < -0.1]

# 按股票統計
trades_by_stock = trades.groupby('stock_id')['return'].agg(['count', 'mean'])
print(trades_by_stock.sort_values('mean', ascending=False).head())

DataFrame 欄位

欄位 說明
symbol / stock_id 股票代號(含名稱)
entry_sig_date 進場訊號產生日
exit_sig_date 出場訊號產生日
entry_date 進場日
exit_date 出場日
position 持有佔比
period 持有天數
return 報酬率
trade_price@entry_date 進場價
trade_price@exit_date 出場價
mae 持有期間最大不利報酬率幅度
gmfe 持有期間最大有利報酬率幅度
bmfe mae 發生前的最大有利報酬率幅度
mdd 持有期間最大回撤
pdays 處於獲利時的天數
industry 產業別

get_mae_mfe()

取得最大不利偏移(MAE)與最大有利偏移(MFE)分析。

使用範例

# 取得 MAE/MFE 資料
mae_mfe = report.get_mae_mfe()

# 視覺化 MAE/MFE 分布
report.display_mae_mfe_analysis()

應用場景: - 設定停損點:觀察 MAE 分布,決定合理的停損幅度 - 設定停利點:觀察 MFE 分布,決定合理的停利幅度 - 優化進出場:若 MFE 大但最終報酬小,表示停利過晚

MAE/MFE 解讀

  • MAE (Maximum Adverse Excursion): 持倉期間的最大未實現虧損
  • MFE (Maximum Favorable Excursion): 持倉期間的最大未實現獲利
  • 理想情況:MFE 大、MAE 小,表示進場時機佳

upload()

上傳回測報告至 FinLab 雲端,供實盤追蹤使用。

使用範例

# 上傳報告
report.upload(name='我的動能策略')

# 之後可在 FinLab 網站查看:
# https://ai.finlab.tw/strategies

上傳前提

  • 需登入 FinLab 帳號(finlab.login()
  • 需為 VIP 會員
  • 上傳後可用於實盤下單、績效追蹤

run_analysis()

執行策略分析外掛模組。

簽名run_analysis(analysis, display=True, **kwargs)

使用範例

# 傳入分析模組名稱(字串)
report.run_analysis('Liquidity')
report.run_analysis('MaeMfe')
report.run_analysis('AlphaBeta')
report.run_analysis('PeriodStats')
report.run_analysis('Drawdown')

# 不顯示圖表,只取得結果
result = report.run_analysis('Liquidity', display=False)

詳細說明請參考 策略分析模組


to_text()

將回測報告以文字方式呈現,適合 Line 通知、日誌記錄等場景。

簽名to_text(name=None)

使用範例

text = report.to_text(name='我的策略')
print(text)

to_terminal()

在終端顯示累積報酬 ASCII 圖表與回撤。

簽名to_terminal(height=12, width=80, show_benchmark=True, show_drawdown=True)

使用範例

report.to_terminal()

# 自訂高度與寬度
report.to_terminal(height=8, width=60)

# 不顯示 benchmark 和 drawdown
report.to_terminal(show_benchmark=False, show_drawdown=False)

安裝

需安裝 asciichartpypip install 'finlab[terminal]'


to_pickle() / from_pickle()

儲存與載入報告。

使用範例

# 儲存報告
report.to_pickle('my_strategy_report.pkl')

# 載入報告
from finlab.core.report import Report
loaded_report = Report.from_pickle('my_strategy_report.pkl')
loaded_report.display()

使用時機

  • 回測需要很長時間,想保存結果
  • 需要對比不同時期的回測報告
  • 與他人分享回測結果

常見問題

Q: 如何對比多個策略的績效?

report1 = sim(position1, resample='M')
report2 = sim(position2, resample='M')

stats1 = report1.get_stats()
stats2 = report2.get_stats()

import pandas as pd
comparison = pd.DataFrame({
    '策略 A': {
        '年化報酬': stats1['daily_mean'],
        '夏普率': stats1['daily_sharpe'],
        '最大回撤': stats1['max_drawdown'],
    },
    '策略 B': {
        '年化報酬': stats2['daily_mean'],
        '夏普率': stats2['daily_sharpe'],
        '最大回撤': stats2['max_drawdown'],
    }
})
print(comparison)

Q: 為什麼我的報告顯示不出來?

# 原因 1:忘記呼叫 .display()
report  # ❌ 不會顯示

report.display()  # ✅ 正確

# 原因 2:Jupyter Notebook 環境問題
# 在 notebook 開頭加入:
%matplotlib inline

# 原因 3:資料為空(無任何交易)
trades = report.get_trades()
if len(trades) == 0:
    print("策略無任何交易記錄,請檢查進場條件")

Q: 如何調整報告的視覺化樣式?

# 取得 plotly figure 物件
fig = report.display(return_fig=True)

# 修改標題
fig.update_layout(title='我的策略回測報告')

# 修改顏色
fig.update_traces(line_color='blue', selector=dict(name='策略'))

# 調整圖表大小
fig.update_layout(width=1200, height=600)

# 顯示
fig.show()

參考資源