投資のためのデータサイエンス

個人の投資活動に役立つデータ分析にまつわる話題を綴ります。

Sofien Kaabar氏の逆張り指標

(2024/8/7) 新しいバージョンのyfinanceライブラリに対応してデータ獲得部分のコードを修正しました

Sofien Kaabar氏は近年、市場価格のテクニカル分析に関してMediumをはじめとして数多くの投稿をしています。
特に、氏の開発した"K's Reversal Indicator"がよく知られているようです。
上記逆張り指標はI, II, IIIがありますが、ここではMedium記事をもとに、K's Reversal Indicator Iの実装を試みました。この指標は、MACDボリンジャーバンドを組み合わせたものになっています。シグナル判定基準は以下の通りです。

買いシグナル:価格が100期間ボリンジャーバンドの下バンドよりも低く、かつMACDMACDシグナルでゴールデンクロスが起きたとき
売りシグナル:価格が100期間ボリンジャーバンドの上バンドよりも高く、かつMACDMACDシグナルでデッドクロスが起きたとき

まず、必要なライブラリをインポートします。

import matplotlib.pyplot as plt
import pandas as pd
import yfinance as yf
import talib as ta
import matplotlib.dates as mdates
from datetime import date, datetime, timedelta
import numpy as np
import mplfinance as mpf
plt.style.use('fivethirtyeight')

次に、市場価格データを読み込みます。ここではFXのデータを用いています。

symbol = 'AUDUSD=X'
end_date = datetime.today()
start_date = end_date - timedelta(days=1095)
# yahooサイトからデータをダウンロード
data = yf.download(symbol, start_date, end_date)

以下では、K's Reversal Indicator Iの戦略を実装します。

def kr_1_strategy(df):
    kr_Buy = []
    kr_Sell = []
    df['bbub'],df['bbmb'],df['bblb'] = ta.BBANDS(df['Adj Close'], timeperiod=100, nbdevup=1.5, nbdevdn=1.5)
    df['macd'], df['macdsignal'], df['macdhist'] = ta.MACD(df['Adj Close'], fastperiod=12, slowperiod=26, signalperiod=9)

    for i in range(0, len(df)):
        if df['Adj Close'][i] <= df['bblb'][i] and df['macd'][i-1] <= df['macdsignal'][i-1] \
           and df['macd'][i] > df['macdsignal'][i]:
            kr_Sell.append(np.nan)
            kr_Buy.append(df['Adj Close'][i])
        elif df['Adj Close'][i] >= df['bbub'][i] and df['macd'][i-1] >= df['macdsignal'][i-1] \
           and df['macd'][i] < df['macdsignal'][i]:
            kr_Buy.append(np.nan)
            kr_Sell.append(df['Adj Close'][i])        
        else:
            kr_Buy.append(np.nan)
            kr_Sell.append(np.nan)

    df['kr_Buy_Signal_price'] = kr_Buy
    df['kr_Sell_Signal_price'] = kr_Sell
    return df

df1 = data.copy()
df1 = kr_1_strategy(df1)

さらに以下では、この戦略の適用結果を描画しています。

fig, ax1 = plt.subplots(figsize=(14,8))
fig.suptitle(symbol, fontsize=10, backgroundcolor='blue', color='white')
ax1 = plt.subplot2grid((14, 8), (0, 0), rowspan=8, colspan=14)
ax2 = plt.subplot2grid((14, 12), (10, 0), rowspan=6, colspan=14)
ax1.set_ylabel('Price')
ax1.plot(df1['Adj Close'],label='Close Price', linewidth=0.5, color='blue')
ax1.scatter(df1.index, df1['kr_Buy_Signal_price'], color='green', marker='^', alpha=1)
ax1.scatter(df1.index, df1['kr_Sell_Signal_price'], color='red', marker='v', alpha=1)
ax1.legend()
ax1.grid()
ax1.set_xlabel('Date', fontsize=8)

ax2.plot(df1['Adj Close'], label='Close', color='blue', alpha=0.35) #middle band
ax2.plot(df1['bbub'], label='Upper', color='green', alpha=0.35) #Upper band
ax2.plot(df1['bblb'], label='Lower', color='red', alpha=0.35) #lower band
ax2.fill_between(df1.index, df1['bbub'], df1['bblb'], alpha=0.1)
ax2.legend(loc='upper left')
ax2.grid()
plt.show()

上図の2段目はボリンジャーバンドです。Kaabar氏はMACDのパラメータ調整には言及していませんが、ボリンジャーバンド標準偏差に掛ける係数はユーザーの好みで調節してよいとしています。実際この係数が一般的な2.0ではなかなかシグナルが出ないため、ここでは1.5としています。またテクニカル指標計算ライブラリについては、pandas_taではこの係数を変えるたびに変数名を変える必要があるので、ここではtalibを用いています。