好啦!之前介紹過了如何用Backtesting套件來實做均線的策略,
前面也介紹過了如何安裝Ta-lib套件,
相信大家一定很想知道如果使用Ta-lib內的套件要如何寫策略,
今天就來和大家介紹RSI低買高賣策略囉!
def rsi_buy(s1,thres):
    return s1[-1] < thres #收盤 RSI 值低於買進門檻,rsi_buy為 True
def rsi_sell(s1,thres):
    return s1[-1] > thres #收盤 RSI 值高於賣出門檻,rsi_sell為 True
class RSI_(Strategy):
    
    # 定義參數
    n1 = 14 # rsi 要算幾天的 RSI 值
    n2 = 30 # rsi 低於多少買進
    n3 = 50 # rsi 高於多少賣出
    
    # 先算好技術指標價格
    def init(self):
        self.rsi = self.I(talib.RSI, self.data.Close, self.n1)
        
    # 一次推進一根 K 棒    
    def next(self):
        
        # 收盤 rsi低於 30 ,隔日開盤價買進
        if rsi_buy(self.rsi, self.n2) and not (self.position.is_long):
            self.buy()
        # 收盤 rsi高於 50 ,隔日開盤價賣出
        if rsi_sell(self.rsi, self.n3) and not (self.position.is_short):
            self.position.close()
策略搞定之後就要來用Backtest回測囉!
#輸入回測條件:df(台積電的資料)跑回測,策略是 RSI_,起始資金 10000元,交易成本 0.2%。            
bt = Backtest(df, RSI_, cash=10000, commission=0.002)
#把回測完得到的數據存到stats
stats = bt.run()
#畫圖(如果不加 superimpose = False,會看到他把每五根日 K 棒合成一根週 K 棒 )
bt.plot(superimpose = False)
stats
資料:台積電2020-2021/9/22
策略:「RSI低於30做多,高於50出場」
績效僅16%,雖然Sharpe Ratio高達2.2,但真的太早出場,超大魚尾都沒吃到!
Out:
---------------------------------------------
Start                     2020-01-02 00:00:00
End                       2021-09-22 00:00:00
Duration                    629 days 00:00:00
Exposure [%]                         7.790143
Equity Final [$]                 11590.450906
Equity Peak [$]                  11590.450906
Return [%]                          15.904509
Buy & Hold Return [%]               72.861357
Max. Drawdown [%]                  -14.482759
Avg. Drawdown [%]                   -5.409828
Max. Drawdown Duration      431 days 00:00:00
Avg. Drawdown Duration      146 days 00:00:00
# Trades                                    3
Win Rate [%]                            100.0
Best Trade [%]                       7.045936
Worst Trade [%]                      2.568966
Avg. Trade [%]                       4.993597
Max. Trade Duration          34 days 00:00:00
Avg. Trade Duration          17 days 00:00:00
Expectancy [%]                            NaN
SQN                                  3.672751
Sharpe Ratio                         2.208007
Sortino Ratio                             NaN
Calmar Ratio                         0.344796
_strategy                                RSI_
接著我們用下面這行code就能把圖畫出來囉!
bt.plot(superimpose = False)

#這邊會將rsi買進門檻和賣出門檻的參數從10~90去跑跑看哪組參數搭配能讓最後帳戶總淨值最高
#至於constraint那一行,是指rsi買進門檻要低於賣出門檻,這樣比較合理,也可以加速最佳化。
stats = bt.optimize(n2=range(10, 90, 1),
                    n3=range(10, 90, 1),
                    maximize='Equity Final [$]',
                    constraint=lambda p: p.n2 < p.n3)
stats
Out:
---------------------------------------------
Start                     2020-01-02 00:00:00
End                       2021-09-22 00:00:00
Duration                    629 days 00:00:00
Exposure [%]                         39.26868
Equity Final [$]                 20354.235241
Equity Peak [$]                  21917.273783
Return [%]                         103.542352
Buy & Hold Return [%]               72.861357
Max. Drawdown [%]                  -25.970149
Avg. Drawdown [%]                   -4.714841
Max. Drawdown Duration      143 days 00:00:00
Avg. Drawdown Duration       29 days 00:00:00
# Trades                                    2
Win Rate [%]                            100.0
Best Trade [%]                      44.419077
Worst Trade [%]                      36.99977
Avg. Trade [%]                      40.709424
Max. Trade Duration         175 days 00:00:00
Avg. Trade Duration         124 days 00:00:00
Expectancy [%]                            NaN
SQN                                  11.32503
Sharpe Ratio                          7.75973
Sortino Ratio                             NaN
Calmar Ratio                         1.567547
_strategy                   RSI_(n2=40,n3=86)
#畫圖(如果不加 superimpose = False,會看到他把每五根日 K 棒合成一根週 K 棒 )
bt.plot(superimpose = False)

**不過這邊還是要提醒讀者:像這樣過度最佳化後的參數並不適合實際拿來使用,
過去績效不代表更不能保證未來走勢,
所以大家還是多想想交易策略的邏輯,開發實用的策略比較實在喔!