# -*- coding: utf-8 -*-
"""roe-pb-stock-selection-strategy 文中兩個策略的完整重現程式。

- 策略一(只看 ROE):ROE > 5% 且 收盤價 > 10 元,約 240 檔等權。
- 策略二(ROE + PB):策略一再加 PB < 1.2,約 16 檔等權。

每 60 個日曆日換股(resample="60D"),含交易成本(手續費 1.425‰ 未打折
+ 賣出證交稅 3‰)。統計視窗 2013-06-18 ~ 2026-08-07(兩策略首個共同
持倉日起算,與文中及 data.csv 同口徑;ROE 資料的可得起點決定了視窗,
所以 2008 金融海嘯不在可檢驗範圍內)。
基準請用 0050 含息(etl:adj_close)買進持有,不要用未還原收盤價。
finlab 會在需要資料時自動引導登入。過去績效不代表未來,不構成投資建議。
"""
import finlab
from finlab import data
from finlab.backtest import sim

finlab.login()

START, END = "2008-01-01", "2026-08-07"
STATS_START = "2013-06-18"  # 統計起點:所有變體與基準的首個共同日

# 載入資料
close = data.get("price:收盤價")
pb = data.get("price_earning_ratio:股價淨值比")
roe = data.get("fundamental_features:ROE稅後")


def run(position, name):
    position = position.loc[START:END]
    report = sim(position, resample="60D",
                 fee_ratio=0.001425, tax_ratio=0.003,
                 upload=False, name=name)
    cr = report.creturn.loc[STATS_START:END]
    cr = cr / cr.iloc[0]
    yrs = (cr.index[-1] - cr.index[0]).days / 365.25
    cagr = cr.iloc[-1] ** (1 / yrs) - 1
    mdd = (cr / cr.cummax() - 1).min()
    held = position.loc[STATS_START:END].sum(axis=1)
    print(f"{name}: 年化 {cagr:.1%} | 最大回撤 {mdd:.1%} | 平均持股 {held[held > 0].mean():.0f} 檔")
    return report


# 策略一:只看 ROE
pos_roe = (roe > 5) & (close > 10)
run(pos_roe, "策略一(只看 ROE>5)")

# 策略二:ROE 搭配 PB
pos_roe_pb = (roe > 5) & (close > 10) & (pb < 1.2)
run(pos_roe_pb, "策略二(ROE>5 + PB<1.2)")
