PROTECTED SOURCE SCRIPT

Regime Change Strategy - Overlay

37
// =====================================================================
// 📊 레짐 체인지 전략 - RSI + MACD 복합 오실레이터
// =====================================================================
// RSI, MACD, 다이버전스, 거래량 분석을 하나의 패널에 통합
// TradingView → Pine Editor에 붙여넣기 → Add to Chart
// =====================================================================

//version=5
indicator("레짐 체인지 - RSI·MACD 복합 패널", overlay=false, max_lines_count=500, max_labels_count=200)

// ─────────────────────────────────────────────
// 📌 설정값
// ─────────────────────────────────────────────
grp_rsi = "━━ RSI 설정 ━━"
rsi_src = input.source(close, "RSI 소스", group=grp_rsi)
rsi_len = input.int(14, "RSI 길이", minval=5, group=grp_rsi)
rsi_ob = input.int(70, "과매수 기준", minval=60, group=grp_rsi)
rsi_os = input.int(30, "과매도 기준", minval=10, group=grp_rsi)
show_rsi = input.bool(true, "RSI 표시", group=grp_rsi)

grp_macd = "━━ MACD 설정 ━━"
macd_fast = input.int(12, "MACD Fast", minval=5, group=grp_macd)
macd_slow = input.int(26, "MACD Slow", minval=10, group=grp_macd)
macd_sig = input.int(9, "MACD Signal",minval=3, group=grp_macd)
show_macd = input.bool(true, "MACD 히스토그램 표시", group=grp_macd)

grp_div = "━━ 다이버전스 설정 ━━"
show_div = input.bool(true, "다이버전스 표시", group=grp_div)
div_lookback = input.int(5, "피봇 룩백", minval=2, group=grp_div)

grp_vol = "━━ 거래량 설정 ━━"
show_vol = input.bool(true, "거래량 바 표시", group=grp_vol)
vol_ma_len = input.int(20, "거래량 MA 길이", group=grp_vol)
vol_thresh = input.float(1.5, "거래량 급증 배수", group=grp_vol)

// ─────────────────────────────────────────────
// 📐 RSI 계산
// ─────────────────────────────────────────────
rsi_val = ta.rsi(rsi_src, rsi_len)
rsi_ma = ta.sma(rsi_val, 9) // RSI 시그널선

// RSI 색상 (구간별)
rsi_color = rsi_val >= rsi_ob ? color.new(#FF1744, 0) : // 과매수 = 빨강
rsi_val <= rsi_os ? color.new(#00C853, 0) : // 과매도 = 초록
color.new(#42A5F5, 0) // 중립 = 파랑

// RSI 플롯
plot(show_rsi ? rsi_val : na, "RSI", color=rsi_color, linewidth=2)
plot(show_rsi ? rsi_ma : na, "RSI Signal", color=color.new(#FFC107, 50), linewidth=1)

// RSI 구간 표시
h_ob = hline(rsi_ob, "과매수", color=color.new(#FF1744, 60), linestyle=hline.style_dashed)
h_os = hline(rsi_os, "과매도", color=color.new(#00C853, 60), linestyle=hline.style_dashed)
h_50 = hline(50, "중립", color=color.new(#9E9E9E, 80), linestyle=hline.style_dotted)
fill(h_ob, h_os, color=color.new(#42A5F5, 95), title="RSI 영역")

// RSI 과매수/과매도 배경
bgcolor(rsi_val >= rsi_ob ? color.new(#FF1744, 92) : na, title="과매수 배경")
bgcolor(rsi_val <= rsi_os ? color.new(#00C853, 92) : na, title="과매도 배경")

// ─────────────────────────────────────────────
// 📊 MACD 히스토그램 (스케일링하여 RSI 패널에 통합)
// ─────────────────────────────────────────────
[macd_line, signal_line, hist_val] = ta.macd(close, macd_fast, macd_slow, macd_sig)

// MACD 히스토그램을 RSI 스케일(0~100)에 맞춰 정규화
hist_max = ta.highest(math.abs(hist_val), 100)
hist_norm = hist_max != 0 ? (hist_val / hist_max) * 15 + 50 : 50 // 50 중심으로 ±15 범위

// 히스토그램 색상 (증가/감소 구분)
hist_color = hist_val >= 0 ?
(hist_val > hist_val[1] ? color.new(#00C853, 30) : color.new(#00C853, 60)) :
(hist_val < hist_val[1] ? color.new(#FF1744, 30) : color.new(#FF1744, 60))

plot(show_macd ? hist_norm : na, "MACD Hist (정규화)",
color=hist_color, style=plot.style_columns, linewidth=2)

// ─────────────────────────────────────────────
// 🔄 다이버전스 탐지 (Divergence Detection)
// ─────────────────────────────────────────────
// 피봇 하이/로우 탐지
pivot_lo = ta.pivotlow(rsi_val, div_lookback, div_lookback)
pivot_hi = ta.pivothigh(rsi_val, div_lookback, div_lookback)

// 가격의 피봇
price_pivot_lo = ta.pivotlow(low, div_lookback, div_lookback)
price_pivot_hi = ta.pivothigh(high, div_lookback, div_lookback)

// 이전 피봇 저장
var float prev_rsi_lo = na
var int prev_rsi_lo_x = na
var float prev_price_lo = na

var float prev_rsi_hi = na
var int prev_rsi_hi_x = na
var float prev_price_hi = na

// ── 강세 다이버전스 (Bullish Divergence) ──
// 가격은 저점을 낮추는데, RSI는 저점을 높이는 경우 → 매수 신호
if not na(pivot_lo) and show_div
if not na(prev_rsi_lo) and
low[div_lookback] < prev_price_lo and
pivot_lo > prev_rsi_lo
// 강세 다이버전스 발견!
line.new(prev_rsi_lo_x, prev_rsi_lo,
bar_index - div_lookback, pivot_lo,
color=color.new(#00C853, 0), width=2, style=line.style_solid)
label.new(bar_index - div_lookback, pivot_lo, "강세\nDiv",
color=color.new(#00C853, 0), textcolor=color.white,
style=label.style_label_up, size=size.tiny)

prev_rsi_lo := pivot_lo
prev_rsi_lo_x := bar_index - div_lookback
prev_price_lo := low[div_lookback]

// ── 약세 다이버전스 (Bearish Divergence) ──
// 가격은 고점을 높이는데, RSI는 고점을 낮추는 경우 → 매도 신호
if not na(pivot_hi) and show_div
if not na(prev_rsi_hi) and
high[div_lookback] > prev_price_hi and
pivot_hi < prev_rsi_hi
// 약세 다이버전스 발견!
line.new(prev_rsi_hi_x, prev_rsi_hi,
bar_index - div_lookback, pivot_hi,
color=color.new(#FF1744, 0), width=2, style=line.style_solid)
label.new(bar_index - div_lookback, pivot_hi, "약세\nDiv",
color=color.new(#FF1744, 0), textcolor=color.white,
style=label.style_label_down, size=size.tiny)

prev_rsi_hi := pivot_hi
prev_rsi_hi_x := bar_index - div_lookback
prev_price_hi := high[div_lookback]

// ─────────────────────────────────────────────
// 📊 거래량 분석 바 (하단)
// ─────────────────────────────────────────────
vol_avg = ta.sma(volume, vol_ma_len)
vol_ratio = volume / vol_avg

// 거래량을 RSI 스케일 하단(0~15)에 표시
vol_norm = math.min(vol_ratio / 3.0 * 15, 15)

vol_bar_color = vol_ratio >= vol_thresh ?
(close > open ? color.new(#00C853, 20) : color.new(#FF1744, 20)) :
(close > open ? color.new(#00C853, 70) : color.new(#FF1744, 70))

plot(show_vol ? vol_norm : na, "거래량 (정규화)",
color=vol_bar_color, style=plot.style_columns, linewidth=1)

// ─────────────────────────────────────────────
// 📋 상태 테이블
// ─────────────────────────────────────────────
var table info = table.new(position.bottom_right, 2, 5,
bgcolor=color.new(#1A1A2E, 10),
border_color=color.new(#333366, 0),
border_width=1)

if barstate.islast
// MACD 크로스 상태
macd_cross = macd_line > signal_line ? "🟢 골든" : "🔴 데드"
macd_cross_color = macd_line > signal_line ? color.new(#00C853, 0) : color.new(#FF1744, 0)

// RSI 추세
rsi_trend = rsi_val > rsi_ma ? "↗ 상승" : "↘ 하락"
rsi_trend_color = rsi_val > rsi_ma ? color.new(#00C853, 0) : color.new(#FF1744, 0)

// 거래량 상태
vol_status = vol_ratio >= vol_thresh ? "🔥 급증 " + str.tostring(vol_ratio, "#.1") + "x" :
"보통 " + str.tostring(vol_ratio, "#.1") + "x"

// 종합 신호
bull_count = (rsi_val < rsi_os ? 1 : 0) +
(macd_line > signal_line ? 1 : 0) +
(hist_val > hist_val[1] ? 1 : 0)

signal_text = bull_count >= 2 ? "🟢 매수 우세" :
bull_count <= 0 ? "🔴 매도 우세" : "🟡 중립"
signal_color = bull_count >= 2 ? color.new(#00C853, 0) :
bull_count <= 0 ? color.new(#FF1744, 0) : color.new(#FFC107, 0)

table.cell(info, 0, 0, "RSI", text_color=color.gray, text_size=size.tiny, bgcolor=color.new(#16213E, 0))
table.cell(info, 1, 0, str.tostring(rsi_val, "#.1") + " " + rsi_trend, text_color=rsi_trend_color, text_size=size.tiny, bgcolor=color.new(#16213E, 0))

table.cell(info, 0, 1, "MACD", text_color=color.gray, text_size=size.tiny, bgcolor=color.new(#1A1A2E, 0))
table.cell(info, 1, 1, macd_cross, text_color=macd_cross_color, text_size=size.tiny, bgcolor=color.new(#1A1A2E, 0))

table.cell(info, 0, 2, "거래량", text_color=color.gray, text_size=size.tiny, bgcolor=color.new(#16213E, 0))
table.cell(info, 1, 2, vol_status, text_color=color.white, text_size=size.tiny, bgcolor=color.new(#16213E, 0))

table.cell(info, 0, 3, "히스토그램", text_color=color.gray, text_size=size.tiny, bgcolor=color.new(#1A1A2E, 0))
table.cell(info, 1, 3, hist_val > hist_val[1] ? "↗ 확대" : "↘ 축소",
text_color=hist_val > hist_val[1] ? color.new(#00C853, 0) : color.new(#FF1744, 0), text_size=size.tiny, bgcolor=color.new(#1A1A2E, 0))

table.cell(info, 0, 4, "종합 신호", text_color=color.gray, text_size=size.tiny, bgcolor=color.new(#16213E, 0))
table.cell(info, 1, 4, signal_text, text_color=signal_color, text_size=size.tiny, bgcolor=color.new(#16213E, 0))

// ─────────────────────────────────────────────
// 🔔 알림 조건
// ─────────────────────────────────────────────
alertcondition(rsi_val <= rsi_os, "RSI 과매도 진입", "RSI가 " + str.tostring(rsi_os) + " 이하로 진입!")
alertcondition(rsi_val >= rsi_ob, "RSI 과매수 진입", "RSI가 " + str.tostring(rsi_ob) + " 이상으로 진입!")
alertcondition(ta.crossover(rsi_val, rsi_os), "RSI 과매도 탈출", "RSI가 과매도 구간에서 탈출! 반등 가능")
alertcondition(ta.crossover(macd_line, signal_line), "MACD 골든크로스", "MACD 골든크로스 발생!")
alertcondition(ta.crossunder(macd_line, signal_line),"MACD 데드크로스", "MACD 데드크로스 발생!")
alertcondition(vol_ratio >= vol_thresh, "거래량 급증", "거래량이 평균의 " + str.tostring(vol_thresh) + "배 돌파!")

Declinazione di responsabilità

Le informazioni e le pubblicazioni non sono intese come, e non costituiscono, consulenza o raccomandazioni finanziarie, di investimento, di trading o di altro tipo fornite o approvate da TradingView. Per ulteriori informazioni, consultare i Termini di utilizzo.