"""市值營收比「多因子」選股策略 — 可重現的真實 finlab 回測。

實測結果（2013-04 ~ 2026-06，月調倉、等權重、未計手續費）：
    年化報酬 CAGR 21.64%、夏普 1.22、最大回撤 -31.66%
對照同期含息 0050：CAGR 21.01%、最大回撤 -33.96%。

重點警告：把低市值營收比集中在「便宜＋高 ROE」少數股（約 8 檔），最大回撤達 -60.58%、
夏普只有 0.62。低市值營收比真正能用，是當成分散的多因子過濾條件，而不是集中重押。

跑法：先 pip install finlab，執行時 finlab.login() 會自動引導你完成登入。
"""
import numpy as np
import finlab
from finlab import data
from finlab.backtest import sim

finlab.login()

# 市值營收比 ＝ 市值 ÷ 近 12 個月營收（越低代表用越便宜的價格買到同樣的營收）
market_value = data.get("etl:market_value")
monthly_revenue = data.get("monthly_revenue:當月營收")
trailing_revenue = monthly_revenue.rolling(12).sum()
ps_ratio = (market_value / trailing_revenue).replace([np.inf, -np.inf], np.nan)

# 另外兩個與「便宜」低相關的因子：營收成長與價格動能
revenue_yoy = data.get("monthly_revenue:去年同月增減(%)")
close = data.get("price:收盤價")
momentum = close / close.shift(60)  # 近 60 個交易日（約 3 個月）動能

# 三條件同時成立才買進，維持分散（約 120 檔）而非集中重押
position = (
    (ps_ratio.rank(axis=1, pct=True) < 0.3)  # 市值營收比全市場最便宜 30%
    & (revenue_yoy > 0)                       # 月營收年增率為正
    & (momentum > 1)                          # 近三個月股價站上
)

report = sim(position, resample="M", name="市值營收比多因子")
report.display()
