**MACDとStochRSIの逆行(ダイバージェンス)**を組み合わせると、反発ポイントをかなり精度高く狙えます。整理してみましょう。
🔎 基本の考え方
- MACD:トレンドの強弱や方向性を示す(移動平均ベース)。
- StochRSI:RSIをさらにストキャスティクス化したもので、過熱感を敏感に捉える。
両者が「価格と逆行」したときは、トレンドの勢いが鈍化しているサイン。特に両方が同時に逆行しているときは、反発の信頼度が高まります。
📈 典型的なシナリオ
1. ブル・ダイバージェンス(反発上昇狙い)
- 価格:安値更新
- MACD:安値を切り上げ
- StochRSI:売られすぎゾーン(0.2以下)から上昇
➡ 買いエントリー候補:StochRSIが0.2を上抜け、かつMACDがシグナルに近づくタイミング。
2. ベア・ダイバージェンス(反落下落狙い)
- 価格:高値更新
- MACD:高値を切り下げ
- StochRSI:買われすぎゾーン(0.8以上)から下落
➡ 売りエントリー候補:StochRSIが0.8を下抜け、かつMACDがデッドクロスに近づくタイミング。
🛠 実務的なエントリー条件(例)
- 買いシグナル
- 価格が直近安値を更新
- MACDラインが前回安値より高い位置(ブル・ダイバージェンス)
- StochRSIが0.2以下から反発上昇
→ エントリー:StochRSIが0.2を上抜けた足で買い
- 売りシグナル
- 価格が直近高値を更新
- MACDラインが前回高値より低い位置(ベア・ダイバージェンス)
- StochRSIが0.8以上から反落
→ エントリー:StochRSIが0.8を下抜けた足で売り
🎯 利確・損切りの目安
- 利確:MACDがゼロラインに到達 or StochRSIが反対ゾーンにタッチ
- 損切り:直近高値/安値を明確にブレイクしたら撤退
✅ まとめ
- MACDの逆行現象=トレンドの勢い鈍化
- StochRSIの極端ゾーンからの反転=タイミングのトリガー
- 両者を組み合わせることで「反発の精度」を高められる
ここでは MACDとStochRSIの逆行(ダイバージェンス) を利用した、実際のトレードシナリオを「買い」「売り」両方のケースで詳しく整理します。
📈 シナリオ1:ブル・ダイバージェンス(反発上昇狙い)
条件
- 価格:安値を更新している
- MACD:安値を切り上げ(モメンタムの下落鈍化)
- StochRSI:売られすぎゾーン(0.2以下)から反発
エントリー
- StochRSIが0.2を上抜けたタイミングでロング
- MACDヒストグラムが縮小し始めたら強気度アップ
利確・損切り
- 利確:MACDがゼロラインに到達、またはStochRSIが0.8以上に到達
- 損切り:直近安値を明確に割り込んだら撤退
実例イメージ
BTCが下落トレンドで3万ドルを割り込むが、MACDは安値を切り上げ、StochRSIが0.1から反発 → 3.2万ドルまでのリバウンドを狙う。
📉 シナリオ2:ベア・ダイバージェンス(反落下落狙い)
条件
- 価格:高値を更新している
- MACD:高値を切り下げ(上昇モメンタムの鈍化)
- StochRSI:買われすぎゾーン(0.8以上)から反落
エントリー
- StochRSIが0.8を下抜けたタイミングでショート
- MACDがデッドクロスに近づいていれば信頼度アップ
利確・損切り
- 利確:MACDがゼロラインに到達、またはStochRSIが0.2以下に到達
- 損切り:直近高値を明確に突破したら撤退
実例イメージ
NASDAQがAI関連株で高値更新するが、MACDはピークを切り下げ、StochRSIが0.9から反落 → 調整下落をショートで狙う。
⚖️ シナリオ3:複合フィルター型(精度強化)
- 条件追加:サポート・レジスタンスや出来高を組み合わせる
- 例:ブル・ダイバージェンスが出たが、同時に出来高が増加 → 反発の信頼度が高い
- 逆に、ベア・ダイバージェンスが出ても出来高が伴わなければ見送り
🛠 実務オペレーション(システム化)
- 検知:TradingViewでMACDとStochRSIのダイバージェンスをスクリプト化
- 条件:
- 価格とMACDが逆行
- StochRSIが閾値(0.2 / 0.8)をクロス
- アラート:条件成立時に通知 → Power AutomateでOneDriveに保存
- 執行:API経由で自動発注 or 半自動で確認後エントリー
✅ まとめると:
- ブル・ダイバージェンス=反発上昇狙い(ロング)
- ベア・ダイバージェンス=反落下落狙い(ショート)
- 出来高やサポレジでフィルタリングすると精度がさらに上がる
MACDとStochRSIダイバージェンス検出
MACDとStochRSIの両方のダイバージェンスを見つけることで、信頼度を上げるために、両方の一致を要求するか、どちらかを許可するか選べるように設定したい。重要なポイントは、StochRSIのしきい値交差をエントリートリガーとして要求するかどうか。コードは、価格とインジケーターのピボットを検出し、ダイバージェンスに基づいて信号を出します。最終的に、設定に応じてエントリートリガーをオプションで追加する予定です。
Pine Script sample for MACD and StochRSI divergence detector
価格とオシレーターの逆行(ダイバージェンス)を、MACDとStochRSIの両方で検知し、ライン描画・シグナル・アラートまでを1本でカバーします。相場の反発/反落の初動検知に使いやすい構成です。
Features
- 検知対象: 価格×MACD、価格×StochRSI のブル/ベア・ダイバージェンス
- 同期許容: ピボット発生タイミングのズレを数バーまで許容(同期ウィンドウ)
- 厳格度: MACDかStochRSIのどちらかで発生、または両方同時発生のみで通知を選択
- トリガー: オプションでStochRSI閾値クロスを発火条件に追加
- 可視化: ピボット間のライン描画、チャート上のシグナル、サブウィンドウにMACD/ストキャスRSI表示
- アラート: ブル/ベア発生時のアラート条件あり
Parameters and logic
- ピボット方式: ta.pivotlow / ta.pivothigh(左右幅は調整可)
- ブル(反発)条件: 価格が安値更新、オシレーターは安値切り上げ(higher low)
- ベア(反落)条件: 価格が高値更新、オシレーターは高値切り下げ(lower high)
- StochRSI: RSI(14)に対しストキャス化(14)→ %K(3) 平滑、%D(3)は参考
- エントリーフィルタ(任意): ブル時はStochRSIが0.2上抜け、ベア時は0.8下抜け
Code
// © Yuki — MACD + StochRSI Divergence Detector
// This source code is subject to the Mozilla Public License 2.0: https://mozilla.org/MPL/2.0/
//@version=5
indicator("MACD + StochRSI Divergence Detector", overlay=true, max_lines_count=500, max_labels_count=500)
//======================
// Inputs
//======================
group_len = "Lengths"
fastMA = input.int(12, "MACD fast", minval=1, group=group_len)
slowMA = input.int(26, "MACD slow", minval=1, group=group_len)
sigMA = input.int(9, "MACD signal",minval=1, group=group_len)
rsiLen = input.int(14, "RSI length", minval=2, group=group_len)
stochLen = input.int(14, "Stoch RSI length", minval=2, group=group_len)
kLen = input.int(3, "%K smoothing", minval=1, group=group_len)
dLen = input.int(3, "%D smoothing", minval=1, group=group_len)
group_piv = "Pivot detection"
left = input.int(5, "Pivot left bars", minval=1, group=group_piv)
right = input.int(5, "Pivot right bars", minval=1, group=group_piv)
syncWindow = input.int(3, "Pivot sync window (bars)", minval=0, group=group_piv)
group_logic = "Signal logic"
requireBoth = input.bool(false, "Require BOTH MACD & StochRSI divergence", group=group_logic)
useStochTrigger = input.bool(true, "Require StochRSI trigger (0.2/0.8 cross)", group=group_logic)
group_vis = "Visualization"
showLines = input.bool(true, "Draw divergence lines", group=group_vis)
showMACD = input.bool(false, "Show MACD sub-panel", group=group_vis)
showStoch = input.bool(false, "Show StochRSI sub-panel", group=group_vis)
//======================
// Calculations
//======================
// MACD
[macdLine, signalLine, hist] = ta.macd(close, fastMA, slowMA, sigMA)
// StochRSI (%K, %D)
rsi = ta.rsi(close, rsiLen)
rsiLow = ta.lowest(rsi, stochLen)
rsiHigh = ta.highest(rsi, stochLen)
stochRaw = (rsiHigh - rsiLow != 0) ? (rsi - rsiLow) / (rsiHigh - rsiLow) : 0.0
k = ta.sma(stochRaw, kLen)
d = ta.sma(k, dLen)
//======================
// Pivots (price & oscillators)
//======================
// price pivots
pLow = ta.pivotlow(low, left, right)
pHigh = ta.pivothigh(high, left, right)
pLowBar = na(pLow) ? na : bar_index - right
pHighBar = na(pHigh) ? na : bar_index - right
// oscillator pivots (MACD & StochRSI use same pivot widths)
mLow = ta.pivotlow(macdLine, left, right)
mHigh = ta.pivothigh(macdLine, left, right)
mLowBar = na(mLow) ? na : bar_index - right
mHighBar = na(mHigh) ? na : bar_index - right
sLow = ta.pivotlow(k, left, right)
sHigh = ta.pivothigh(k, left, right)
sLowBar = na(sLow) ? na : bar_index - right
sHighBar = na(sHigh) ? na : bar_index - right
//======================
// State to keep last two pivots for comparisons
//======================
var float lastPriceLow = na
var float prevPriceLow = na
var int lastPriceLowBar = na
var int prevPriceLowBar = na
var float lastMacdLow = na
var float prevMacdLow = na
var int lastMacdLowBar = na
var int prevMacdLowBar = na
var float lastStochLow = na
var float prevStochLow = na
var int lastStochLowBar = na
var int prevStochLowBar = na
var float lastPriceHigh = na
var float prevPriceHigh = na
var int lastPriceHighBar = na
var int prevPriceHighBar = na
var float lastMacdHigh = na
var float prevMacdHigh = na
var int lastMacdHighBar = na
var int prevMacdHighBar = na
var float lastStochHigh = na
var float prevStochHigh = na
var int lastStochHighBar = na
var int prevStochHighBar = na
//---- update on new pivots
if not na(pLow)
prevPriceLow := lastPriceLow
prevPriceLowBar:= lastPriceLowBar
lastPriceLow := pLow
lastPriceLowBar:= pLowBar
if not na(mLow)
prevMacdLow := lastMacdLow
prevMacdLowBar:= lastMacdLowBar
lastMacdLow := mLow
lastMacdLowBar:= mLowBar
if not na(sLow)
prevStochLow := lastStochLow
prevStochLowBar:= lastStochLowBar
lastStochLow := sLow
lastStochLowBar:= sLowBar
if not na(pHigh)
prevPriceHigh := lastPriceHigh
prevPriceHighBar:= lastPriceHighBar
lastPriceHigh := pHigh
lastPriceHighBar:= pHighBar
if not na(mHigh)
prevMacdHigh := lastMacdHigh
prevMacdHighBar:= lastMacdHighBar
lastMacdHigh := mHigh
lastMacdHighBar:= mHighBar
if not na(sHigh)
prevStochHigh := lastStochHigh
prevStochHighBar:= lastStochHighBar
lastStochHigh := sHigh
lastStochHighBar:= sHighBar
//======================
// Divergence conditions
//======================
// helper: are two pivots close in time?
inSync(a, b) =>
not na(a) and not na(b) and math.abs(a - b) <= syncWindow
// Bullish: price lower low AND oscillator higher low
bullMacd = not na(lastPriceLow) and not na(prevPriceLow) and not na(lastMacdLow) and not na(prevMacdLow) and
lastPriceLow < prevPriceLow and lastMacdLow > prevMacdLow and
inSync(lastPriceLowBar, lastMacdLowBar)
bullStoch = not na(lastPriceLow) and not na(prevPriceLow) and not na(lastStochLow) and not na(prevStochLow) and
lastPriceLow < prevPriceLow and lastStochLow > prevStochLow and
inSync(lastPriceLowBar, lastStochLowBar)
// Bearish: price higher high AND oscillator lower high
bearMacd = not na(lastPriceHigh) and not na(prevPriceHigh) and not na(lastMacdHigh) and not na(prevMacdHigh) and
lastPriceHigh > prevPriceHigh and lastMacdHigh < prevMacdHigh and
inSync(lastPriceHighBar, lastMacdHighBar)
bearStoch = not na(lastPriceHigh) and not na(prevPriceHigh) and not na(lastStochHigh) and not na(prevStochHigh) and
lastPriceHigh > prevPriceHigh and lastStochHigh < prevStochHigh and
inSync(lastPriceHighBar, lastStochHighBar)
// Logic: either-or vs both
bullRaw = requireBoth ? (bullMacd and bullStoch) : (bullMacd or bullStoch)
bearRaw = requireBoth ? (bearMacd and bearStoch) : (bearMacd or bearStoch)
// Optional stoch trigger
bullTrig = not useStochTrigger or ta.crossover(k, 0.2)
bearTrig = not useStochTrigger or ta.crossunder(k, 0.8)
bullSignal = bullRaw and bullTrig
bearSignal = bearRaw and bearTrig
//======================
// Visuals on price chart
//======================
plotshape(bullSignal, title="Bullish divergence", style=shape.triangleup, location=location.belowbar, color=color.new(color.lime, 0), size=size.tiny, text="Bull Div")
plotshape(bearSignal, title="Bearish divergence", style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny, text="Bear Div")
// Draw divergence lines (price and oscillator)
if showLines
// Bullish lines
if bullMacd
line.new(prevPriceLowBar, prevPriceLow, lastPriceLowBar, lastPriceLow, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.lime, 0))
line.new(prevMacdLowBar, prevMacdLow, lastMacdLowBar, lastMacdLow, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.teal, 0))
if bullStoch
line.new(prevPriceLowBar, prevPriceLow, lastPriceLowBar, lastPriceLow, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.lime, 0))
line.new(prevStochLowBar, prevStochLow, lastStochLowBar, lastStochLow, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.blue, 0))
// Bearish lines
if bearMacd
line.new(prevPriceHighBar, prevPriceHigh, lastPriceHighBar, lastPriceHigh, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.red, 0))
line.new(prevMacdHighBar, prevMacdHigh, lastMacdHighBar, lastMacdHigh, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.orange, 0))
if bearStoch
line.new(prevPriceHighBar, prevPriceHigh, lastPriceHighBar, lastPriceHigh, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.red, 0))
line.new(prevStochHighBar, prevStochHigh, lastStochHighBar, lastStochHigh, xloc=xloc.bar_index, extend=extend.none, color=color.new(color.purple, 0))
//======================
// Sub-panels (optional)
//======================
macdColor = hist >= 0 ? color.new(color.green, 0) : color.new(color.red, 0)
plot(showMACD ? macdLine : na, title="MACD", color=color.new(color.aqua, 0))
plot(showMACD ? signalLine : na, title="Signal", color=color.new(color.fuchsia, 0))
plot(showMACD ? hist : na, title="Histogram", style=plot.style_columns, color=macdColor)
plot(showStoch ? k : na, title="%K (StochRSI)", color=color.new(color.blue, 0))
plot(showStoch ? d : na, title="%D (StochRSI)", color=color.new(color.gray, 0))
hline(showStoch ? 0.8 : na, "K 0.8", color=color.new(color.red, 70))
hline(showStoch ? 0.2 : na, "K 0.2", color=color.new(color.lime, 70))
//======================
// Alerts
//======================
alertcondition(bullSignal, title="Bullish divergence (confirmed)", message="Bullish divergence detected (MACD/StochRSI) with trigger")
alertcondition(bearSignal, title="Bearish divergence (confirmed)", message="Bearish divergence detected (MACD/StochRSI) with trigger")
alertcondition(bullRaw, title="Bullish divergence (raw)", message="Bullish divergence detected (raw)")
alertcondition(bearRaw, title="Bearish divergence (raw)", message="Bearish divergence detected (raw)")
How to use
- 時間軸: 4H・1Dでのノイズ低減がおすすめ。短期はpivot幅を広げる(left/right↑)。
- 厳格度: 精度優先なら「Require BOTH」をON。回転重視ならOFF。
- トリガー: 値動きの初動を狙うならStochRSIトリガーをONに。早めに入るならOFF。
- 同期ウィンドウ: 0~3で調整。値を大きくすると偽陽性が増えやすい。
Notes and customization
- フィルタ追加: 200EMAの位置や出来高増減、サポレジ接触で条件をさらに絞れます。
- 利確/損切りの目安: ブルはMACDゼロライン接近・前戻り高値、ベアはゼロライン割れ・直近押し安値。損切りは直近ピボット反対側超え。
- 描画負荷: ラインが多くなる場合は「Draw divergence lines」をOFFに。max_lines_countは必要に応じ増加。