大家好,我是新來的小編邦寧。本篇將會從菲式思考最後一章的「即將開法說會」作為原始策略,並在此基礎上加強策略的表現。
簡介法說會策略
策略是基於「押寶法說會即將公布重大利多」的理念,然而,逐家訪問公司過於費時。因此,策略採取撒網思維,直接搜尋「具備某些特徵,可能會宣布重大利多消息的公司」。
書中選股條件
- 營收 YoY (月營收年增長率) > 0 或是營收 MoM (月營收月增長率) > 0
- 近二十天漲幅不超過 7%
- 從法說會前十天 Buy & Hold 到法說會當天
FinLab 回測驗證
程式碼
from pandas.core.indexing import convert_from_missing_indexer_tuple
from finlab import data
from finlab.backtest import sim
import pandas as pd
import numpy as np
import datetime
close = data.get("price:收盤價")
# Extend the dataset from monthly to daily with * (close >= 0)
rev_yy = data.get("monthly_revenue:去年同月增減(%)") * (close >= 0)
rev_mm = data.get("monthly_revenue:上月比較增減(%)") * (close >= 0)
no_grow = ((close - close.shift(-5)) / close < 1.07)
investor_conference = data.get('investors_conference').reset_index()
investor_conference = investor_conference.pivot(index='date', columns='stock_id')["公司名稱"].notna()
position = investor_conference * (close >= 0)
# Buy and Hold from last 10 days
position = position.shift(-10).fillna(False)
position = position & ((rev_yy > 0) | (rev_mm > 0)) & no_grow
position = position.rolling(10).sum().fillna(0)
report = sim(position, trade_at_price="close", fee_ratio=1.425/1000/3, upload=True)
回測結果
如同書中所提及的,Sharpe Ratio 跟 MDD (Maximum Draw Down) 都不夠理想,還能再加強。
Sharpe Ratio 是衡量投資報酬和風險平衡的指標,越高表示風險調整後的報酬較好。最大跌幅(MDD, Maximum Draw Down)則評估投資組合在一段時間內最大的價值下跌。夏普比率看風險和報酬,MDD (Maximum Draw Down)看最壞時的損失。
策略優化
加入季營收增長率
通常營收增長率越高的公司,越容易是飆股,詳細請見 FinLab 的營收動能策略。
順著營收 YoY, MoM > 0 的思路,如果再加入營收 QoQ (營收年增率) > 0 這個條件的話,是否會更好呢?
答案是肯定的,只要 YoY, QoQ, MoM 三者中滿足一個 > 0,就去打這檔股票,最終效果是能增加 Sharpe Ratio 的。
營收的 YoY, QoQ, MoM 必須都要增長才行
在前面,做法是 YoY, QoQ, MoM 只要有一個 > 0,就交易這支股票;如果將濾網收緊,令營收 YoY, QoQ, MoM 都要 > 0 的話,會更好嗎?
就結果而言,影響不大,但是能有效降低交易次數,也代表每筆的期望報酬會增加。
營收 YoY, QoQ, MoM 至少要有一個亮眼才行
或者說,營收的增加不僅僅要有增長,更需要達到相當引人注目的程度,才能真正改善績效?比如至少要達到50%以上的增長。經過實驗證實,這樣的調整或許能稍微提高夏普比率,但並不會有非常明顯的增加。
MAE/MFE 分析
觀察 MAE/Return plot,停損設在差不多 10% 能避免虧損持續擴大,也能明顯看到勝手沒有超過 10% 的 MAE。
關於怎麼理解 MAE/MFE,可以參考這個部落格,裡面深入淺出的介紹了 MAE/MFE 的使用方法。
小結
最終策略
from pandas.core.indexing import convert_from_missing_indexer_tuple
from finlab import data
from finlab.backtest import sim
import pandas as pd
import numpy as np
import datetime
close = data.get("price:收盤價").fillna(method='ffill').fillna(method='bfill')
# Extend the dataset from monthly to daily with * (close >= 0)
rev_yy = data.get("monthly_revenue:去年同月增減(%)") * (close >= 0)
rev_mm = data.get("monthly_revenue:上月比較增減(%)") * (close >= 0)
rev_qq = data.get('fundamental_features:營收成長率') * (close >= 0)
no_grow = ((close - close.shift(-5)) / close < 1.07)
investor_conference = data.get('investors_conference').reset_index()
investor_conference = investor_conference.pivot(index='date', columns='stock_id')["公司名稱"].notna()
position = investor_conference * (close >= 0)
# Buy and Hold from last 10 days
position = position.shift(-10).fillna(False)
position = position & ((rev_yy > 0) | (rev_qq > 0) | (rev_mm > 0)) & no_grow
position = position.rolling(10).sum().fillna(0)
report = sim(position, trade_at_price="close", fee_ratio=1.425/1000/3, stop_loss=0.1)
可以觀察到,經過停損後,績效變差了,但是停損能作為一個防火牆,避免突如其來的虧損燒穿帳戶。
資料來源
在最糟的情況下,只要在前一天宣布召開法說會,隔天就能召開法說會,但我們的策略需要在法說會前十個交易日進行投資。
因此,我們應該特別注意這個時間範圍,以確保策略不會用到未來的資料。
風險評估
可以觀察到,這隻策略的 Draw Down 的行為跟大盤十分相似,但這隻策略在獲利時,能取得比大盤更好的績效。
總而言之,這隻策略是進可攻退可守的策略,再稍加修改就能取得更好的績效!
結論
我們從介紹法說會策略開始,這個策略基於「押寶法說會即將公布重大利多」的理念,選擇以撒網的方式尋找「具備某些特徵,可能會宣布重大利多消息的公司」。
在策略優化部分,我們加入了季營收增長率的概念,並探討了營收的年增率(QoQ)是否能夠增強策略表現。我們發現只要在YoY、QoQ、MoM三者中至少有一個大於零,就能提高夏普比率。
我們也分析了最大不利移動/最大有利移動(MAE/MFE),發現停損設在約10%能夠有效避免虧損擴大。
總體來說,這個策略是進可攻退可守的,且在獲利時表現優於大盤。我們相信稍加修改,可以取得更好的績效!