逆張り戦略の王道といえばRSI。さらにトレンド転換のシグナルとしてMACDを組み合わせると、ダマシを減らした精度の高いエントリーが狙えます。本記事では、yfinanceで取得した日足データを使い、RSI×MACDの逆張り戦略をPythonでバックテストする方法を、そのまま動くコードと一緒に紹介します。
戦略の設計
使用するインジケーターはRSI(14)とMACD(12,26,9)の2つ。シンプルなロジックは次の通りです。
- エントリー(買い):RSIが30を下回り、かつMACDヒストグラムが前日比で上昇に転じたとき
- エグジット(売り):RSIが70を上回ったとき、または保有5営業日経過
なぜMACDを組み合わせるのか
RSI単独だと「売られすぎ」シグナルが連発し、下落トレンド中に何度もエントリーしてしまいます。MACDヒストグラムの転換を加えることで、勢いが反転したタイミングだけにエントリーを絞れる、というのがこの組み合わせの肝です。
Pythonコード
import yfinance as yf
import pandas as pd
import numpy as np
def rsi(series, period=14):
delta = series.diff()
gain = delta.where(delta > 0, 0).rolling(period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(period).mean()
rs = gain / loss
return 100 - (100 / (1 + rs))
def macd_hist(series, fast=12, slow=26, signal=9):
ema_f = series.ewm(span=fast).mean()
ema_s = series.ewm(span=slow).mean()
macd_line = ema_f - ema_s
sig_line = macd_line.ewm(span=signal).mean()
return macd_line - sig_line
df = yf.download("^N225", period="2y", interval="1d", progress=False)
df["RSI"] = rsi(df["Close"])
df["HIST"] = macd_hist(df["Close"])
df["entry"] = (df["RSI"] < 30) & (df["HIST"] > df["HIST"].shift(1))
position, entry_price, hold = 0, 0, 0
returns = []
for i, row in df.iterrows():
if position == 0 and row["entry"]:
position, entry_price, hold = 1, row["Close"], 0
elif position == 1:
hold += 1
if row["RSI"] > 70 or hold >= 5:
returns.append((row["Close"] - entry_price) / entry_price)
position = 0
n = max(len(returns), 1)
print(f"トレード回数: {len(returns)}")
print(f"勝率: {sum(1 for r in returns if r>0)/n:.1%}")
print(f"平均リターン: {np.mean(returns):.2%}")
結果の見方
このコードを日経平均(^N225)の過去2年で実行すると、勝率が高いものの平均リターンが小さい「コツコツ型」の結果になりがちです。さらにstop-loss(損切り)や保有日数の最適化を加えることで、パラメータをチューニングできます。実運用に向けては手数料・スリッページの考慮も忘れずに。
応用のヒント
個別株に応用するなら、業種ごとにパラメータを変えるのが定番。たとえば値動きの荒い小型株はperiod=10、安定したディフェンシブ銘柄はperiod=21といった具合に、銘柄特性に合わせたチューニングが効果的です。
まとめ
RSIとMACDの組み合わせは、逆張り戦略のダマシを減らす定番テクニック。本記事のコードはそのまま貼り付けて動作確認できる構成にしてあるので、銘柄やパラメータを変えながら、自分なりの逆張りロジックを育ててみてください。バックテスト結果は実運用を保証するものではないので、必ず少額・デモ口座での検証から始めましょう。

