練習版程式碼連結:https://colab.research.google.com/drive/1IY81k4kMQtpdYWOVTa_esgIQ4zOCKN9y?usp=sharing
(請參考第一章第一節來啟動該筆記本)
上一節,我們成功對策略進行驗證。
這一節,我們來對策略添加濾網,以求達到更高的獲利。
1. 什麼是濾網
濾網顧名思義,就是在策略中放置一個指標,把無法獲利的交易給取消掉,藉由減少虧損的方式來增大獲利。
假設有一段時間的價格,取這個價格的中位數 median,如圖所示,圓圈代表價格,兩圓連成一點表示前一筆價格與後一筆價格的連線,通常會有許多價格穿過中位數。
但是假如有兩個價格連起來且都在中位數上方,則表示市場當時確實有向上的趨勢產生。
我們可以藉由這種方式,過濾掉不滿足上述條件的交易,在上圖中,只有一條線滿足此條件,就是圖中被圈起來的那條線。
2. 撰寫策略濾網
先開啟練習版筆記本,掛接雲端硬碟,把該跑的程式跑完,從 MMI Filter 開始撰寫中位數:
median = ohlcv.close.rolling(20).median()
可以把 2021 年 11 月的中位數價格和整體價格走勢畫出來看看:
ohlcv.close['2021-11'].plot()
median['2021-11'].plot()
現在來開始製作濾網。
於 median 這個變數下方撰寫兩個辨識價格是否大於中位數的一個布林訊號,一個辨識今天價格,一個辨識昨天的:
median = ohlcv.close.rolling(20).median()
p1 = ohlcv.close > median
p2 = ohlcv.close.shift() > median
ohlcv.close['2021-11'].plot()
median['2021-11'].plot()
然後在於 p2 下方撰寫濾網的程式碼,把最近 20 天, p1 和 p2 的結果都為 True(雙方的價格都大於中位數)的次數總和平均的布林訊號轉成整數,(True 為 1,False 為 0),並傳給 mmi 這個變數。
把 mmi 連同另外兩個價格走勢一併畫出來,並添加 y 軸。
程式碼最後會長這樣:
median = ohlcv.close.rolling(20).median()
p1 = ohlcv.close > median
p2 = ohlcv.close.shift() > median
mmi = (p1 & p2).astype(int).rolling(20).mean()
ohlcv.close['2021-11'].plot()
median['2021-11'].plot()
mmi['2021-11'].plot(secondary_y = True)
於是,我們就完成了濾網。
現在該是把濾網添加到策略裡面運行的時候了,先把後面有 plot 的程式碼複製貼上到 「plot」 下方的儲存格,也就是下一個儲存格,並重新運行。
再來把「Simple Moving Average」下方儲存格的程式碼複製貼上到「Modify SMA strategy」下方的儲存格。
然後把「MMI Filter」下方儲存格的程式碼貼上到 return 上方並按 tab 縮進,使其能夠被函式包住。
再來修改一下進場點,於 mmi 這個變數下方撰寫如下的程式碼:
entries = entries & (mmi > 0.5)
這行程式碼的意思為:「每當滿足進場點條件時,還須符合 mmi > 0.5 的條件才能進場」,這讓我們過濾掉許多無法獲利的交易。
於是,整個策略已經被修改完畢。
由於這與「Simple Moving Average」的策略有所不同,所以必須修改一下策略名稱:
import numpy as np
from finlab_crypto import Strategy
@Strategy(sma1 = 20, sma2 = 60)
def mmi_sma_strategy(ohlcv):
close = ohlcv.close
sma20 = close.rolling(mmi_sma_strategy.sma1).mean()
sma60 = close.rolling(mmi_sma_strategy.sma2).mean()
entries = (sma20 > sma60) & (sma20.shift() < sma60.shift())
exits = (sma20 < sma60) & (sma20.shift() > sma60.shift())
figures = {
'overlaps': {
'sma20': sma20,
'sma60': sma60
}
}
median = ohlcv.close.rolling(20).median()
p1 = ohlcv.close > median
p2 = ohlcv.close.shift() > median
mmi = (p1 & p2).astype(int).rolling(20).mean()
entries = entries & (mmi > 0.5)
return entries, exits, figures
variables = {'sma1': np.arange(20, 100, 5), 'sma2': np.arange(20, 100, 5)}
portfolio = mmi_sma_strategy.backtest(ohlcv, variables=variables, freq='1h', plot=True)
總共更改了四處。
最後來執行程式:
這一節,我們成功製作了策略濾網。
下一節,我們來試著將 filters 進行打包。