月營收動能避開可轉債發行公司
月營收動能選股(近三月平均營收高於近十二月平均、站上 20/60/120 日均線、五日平均漲跌幅最強 10 檔,每月營收公布後換股、10% 停損),排除當天有流通在外可轉債的公司。2010 年至 2026 年台股回測年化報酬 42.2%、日夏普 1.43、最大回撤 -43.5%;同視窗 0050 含息年化 16.8%、日夏普 0.95。
投資警語:本文僅供教學參考,不構成投資建議。過去績效不代表未來表現,投資有風險。
回測績效
- 年化報酬率
- 42.2%
- 日夏普
- 1.43
- 最大回撤
- -43.5%
- 總報酬率
- 34836%
- 平均持股
- 10.0 檔
回測含手續費 0.1425% 與賣出證交稅 0.3%(finlab 套件 sim() 預設成本),日夏普未扣無風險利率。策略淨值自資料可得日(2010-03-11)起算。
淨值曲線(對數座標)
月營收動能避開可轉債發行公司0050 買進持有(含息)
與 0050 買進持有(含息)對照
| 對象 | 年化報酬率 | 日夏普 | 最大回撤 | 統計視窗 |
|---|---|---|---|---|
| 月營收動能避開可轉債發行公司 | 42.2% | 1.43 | -43.5% | 2010-03-11 〜 2026-10-27 |
| 0050 買進持有(含息) | 16.8% | 0.95 | -34.0% | 2010-03-11 〜 2026-10-27 |
完整策略程式碼
安裝 finlab 套件後即可直接執行重現(finlab.login() 會自動引導登入,不需手動填 token)。想用 AI 輔助安裝與跑第一次回測,可以走安裝教學。
展開程式碼(strategy.py)
"""可轉債選股:月營收動能選股,避開有流通在外可轉債的公司。
與 https://finlab.finance/blog/convertible-bond-stock-selection 同一份程式。
回測從 2010-02 起(FinLab 可轉債每日報表從 2009-12-30 開始)到最新資料。
執行前先安裝 finlab,需要資料時 finlab 會自動引導登入:
pip install finlab
python strategy.py
"""
from finlab import data
from finlab.backtest import sim
close = data.get("price:收盤價")
rev = data.get("monthly_revenue:當月營收")
cb = data.get("cb_published_info")
# 1. 月營收動能:近三個月平均營收高於近十二個月平均營收
rev_up = rev.average(3) > rev.average(12)
# 2. 股價趨勢:收盤價同時站上 20、60、120 日均線
trend = (
(close > close.average(20))
& (close > close.average(60))
& (close > close.average(120))
)
# 3. 當天有流通在外可轉債的公司
# 可轉債代號前四碼是發行公司股票代號;債券簡稱含「E + 數字」的是交換債
# (例如遠紡E1,標的是別家公司股票),不算發行公司自己的可轉債。
own_cb = cb[~cb["債券簡稱"].astype(str).str.contains(r"E\d")]
own_cb = own_cb.assign(stock_id=own_cb["symbol"].astype(str).str[:4])
has_cb = own_cb.groupby(["date", "stock_id"]).size().unstack().notna()
has_cb = has_cb.reindex(close.index).ffill(limit=5).fillna(False).astype(bool)
has_cb = has_cb.reindex(columns=close.columns, fill_value=False).astype(bool)
# 4. 五日平均漲跌幅最強的 10 檔,排除有可轉債的公司
pct_change = (close / close.shift() - 1).rolling(5).mean()
position = pct_change[trend & rev_up & ~has_cb].is_largest(10).loc["2010-02-01":]
# 每月營收公布後(月初第 11 天)換股,單檔 10% 停損,手續費與證交稅用 sim 預設
report = sim(
position,
resample="M",
resample_offset="11D",
stop_loss=0.1,
upload=False,
name="月營收動能避開可轉債發行公司",
)
print(report.get_stats())
在 Studio 裡用同一套真實資料調整條件、重跑回測。