用Python回測總經指標(2)|美國失業率 vs S&P 500指數

  • Post author:
  • Reading time:4 mins read
thumbnail

FED 打通膨不擇手段地升息,開始影響到實體經濟,除了一連串財爆,10-11月許多著名科技業如 Twitter、Meta都開始為了蹲節而裁員滾滾,從 裁員統整網站 資料可以見到一串觸目驚心的數字,10月的美國失業率是3.7%,還不是特別高,這個月失業率會不會噴出要等12月初才知道。究竟美國失業率要如何應用到策略上?FinLab量化平台能否支援 S&P 500指數 的回測?本篇文章帶給你相關洞見與程式撰寫方法。

截圖 2022 11 10 下午3.55.42

資料取得

透過FinLab資料庫即可一行取得失業率資料
data.get('us_unemployment_rate_seasonally_adjusted:value)'
如果你對抓取美國就業相關總經數據有興趣,可以參考此篇爬蟲教學

圖表觀測

美國數據比台灣數據好的地方在資料很早就有統計,可以做長時間回測,圖中可以發現失業率指標大致在3~10%擺盪,歷史失業率接近10%時,往往是股市低點,有人說目前的通盤環境類似1983年,但目前的失業率還在低檔,離10%高檔還很遠,是不是還沒末跌段?
失業率循環的週期普遍在5年以上,是蠻長線的指標,2000年以後,失業率與股市表現有明顯負相關,2000年以前股市和失業率關聯不大,S&P 500幾乎一路往上衝。。

newplot 24


為了方便長短期失業率趨勢,我們可將失業率化成均線,看MA6與MA2的差額,讓我們更能方便觀測短期失業率是否變嚴重,負值越高代表短期失業率越嚴重,可以發現指標由正轉負時,會領先預告股價崩跌,但由於訊號週期長,由負轉正也往往會錯過V轉反彈,2022由於就業市場太好,死叉訊號落後股市崩跌很多。

newplot 25

總經指標回測

程式範例

若我們想要用失業率回測 S&P 500 指數,第一個面臨到的問題是 FinLab 量化平台可否回測台股以外的交易資料?
答案是可以的,只要繼承MarketInfo類別,客製化回測市場的資料,修改一下市場類別回傳的方法,最後將新類別傳入sim的market參數即可。範例將台股的資料換成世界指數的資料。
訊號條件只有一個失業率 MA2 小於 MA6 時持有 S&P 500 指數

from finlab import data
from finlab.market_info import MarketInfo
from finlab.backtest import sim
import pandas as pd

class WorldIndexMarketInfo(MarketInfo):

    @staticmethod
    def get_benchmark():
        world_index = data.get('world_index:close')
        sp500 = world_index['^GSPC'].ffill()
        return sp500

    @staticmethod
    def get_asset_id_to_name():
        return {}

    @staticmethod
    def get_price(trade_at_price, adj=True):
        if isinstance(trade_at_price, pd.Series):
            return trade_at_price.to_frame()

        if isinstance(trade_at_price, pd.DataFrame):
            return trade_at_price

        if isinstance(trade_at_price, str):
            if trade_at_price == 'volume':
                return data.get('world_index:vol')

            if adj:
                table_name = 'world_index:adj_'
                price_name = trade_at_price
            else:
                table_name = 'world_index:'
                price_name = trade_at_price

            price = data.get(f'{table_name}{price_name}')
            return price

        raise Exception(f'**ERROR: trade_at_price is not allowed (accepted types: pd.DataFrame, pd.Series, str).')


from finlab import data

unemployment_rate = data.get('us_unemployment_rate_seasonally_adjusted:value')
close = data.get('world_index:close')
cond1 = (close.ffill() > 0)[['^GSPC']]
cond2 = (unemployment_rate.average(2) < unemployment_rate.average(6))['美國失業率(季調)'].reindex(cond1.index,method='ffill')

position = cond1 & cond2

report = sim(position,resample='D', market=WorldIndexMarketInfo, name='us_unemplyment_rate', tax_ratio=0, fee_ratio=0, upload=False)
report.benchmark = close['^GSPC'].ffill()
report.display()

回測結果

全歷史

使用失業率指標來擇時,沒有比一直持有好,但橘線的回檔曲線明顯優於一直持有,閃崩要閃V轉,報酬率與穩定度你選哪一個?

newplot 26

2000年至今

2000年以後的回測,失業率指標就明顯有效果,報酬率和回檔曲線都比一直持有好。

newplot 27

結論

colab 範例檔
world_index 資歷集內還有其他指數資料,趕快來探索更廣的應用!如果你對總經指標回測有興趣,可以參考參考之前類似的文章「用Python回測總經指標(1)|M1B & M2 年增率」,如果有想要的總經指標,卻在 FinLab資料庫找不到,也歡迎到 Discord 與我們討論與許願喔。
失業率指標何時噴上來?會是末跌段一個重要指標,讓我們繼續看下去。

Ben

Python 軟體工程師與量化策略研究員。 鑽研資料工程、網頁後端、資料視覺化、量化交易策略開發。 投資主力在台股市場,量化策略為主、質化分析為輔,追求人機攜做最佳化。逐步將觸角延伸到總經、美股、加密貨幣,朝更全方位的交易人邁進。