지표 조합 전략¶
여러 기술 지표를 조합하여 시그널의 신뢰도를 높이는 전략 예제입니다.
1. RSI + MACD 이중 확인¶
RSI와 MACD의 시그널이 동시에 발생할 때만 매매합니다.
version("1.0")
description("RSI + MACD 이중 확인 전략")
param("rsi_period", "rsi period", 14)
c = chart("1D")
# 지표 계산
rsi = ta.rsi(c.close, script_params["rsi_period"])
macd_line, signal, hist = ta.macd(c.close, 12, 26, 9)
# 차트 표시
c.line("RSI", rsi, color="purple")
c.histogram("MACD Hist", hist, color="gray")
c.hline("RSI OB", 70, color="red")
c.hline("RSI OS", 30, color="green")
# RSI 과매도 + MACD 히스토그램 양전환
rsi_oversold = rsi[0] < 35
macd_bullish = hist[1] < 0 and hist[0] > 0
# RSI 과매수 + MACD 히스토그램 음전환
rsi_overbought = rsi[0] > 65
macd_bearish = hist[1] > 0 and hist[0] < 0
if rsi_oversold and macd_bullish:
buy(tag=f"RSI({rsi[0]:.0f}) 과매도 + MACD 양전환")
elif rsi_overbought and macd_bearish:
sell(tag=f"RSI({rsi[0]:.0f}) 과매수 + MACD 음전환")
else:
hold()
2. 볼린저밴드 + RSI + 거래량¶
세 가지 지표가 모두 같은 방향일 때만 진입합니다.
version("1.0")
description("볼린저밴드 + RSI + 거래량 삼중 필터")
c = chart("1D")
# 볼린저밴드
upper, mid, lower = ta.bbands(c.close, 20, 2.0)
c.line("BB Upper", upper, color="red")
c.line("BB Mid", mid, color="gray")
c.line("BB Lower", lower, color="green")
# RSI
rsi = ta.rsi(c.close, 14)
# 거래량
vol_sma = ta.sma(c.volume, 20)
# 매수 조건: 하단밴드 + RSI 과매도 + 거래량 증가
bb_buy = c.close[0] < lower[0]
rsi_buy = rsi[0] < 30
vol_up = c.volume[0] > vol_sma[0] * 1.2
# 매도 조건: 상단밴드 + RSI 과매수
bb_sell = c.close[0] > upper[0]
rsi_sell = rsi[0] > 70
if bb_buy and rsi_buy and vol_up:
buy(tag=f"BB하단+RSI({rsi[0]:.0f})+거래량({c.volume[0]/vol_sma[0]:.1f}배)")
elif bb_sell and rsi_sell:
sell(tag=f"BB상단+RSI({rsi[0]:.0f}) 과매수")
else:
hold()
3. ADX 기반 전략 전환기¶
ADX로 추세/횡보를 판단하고, 상황에 맞는 전략을 자동 전환합니다.
version("1.0")
description("ADX 기반 전략 전환기 — 추세/횡보 적응형")
param("adx_threshold", "adx threshold", 25)
c = chart("1D")
# 추세 강도
adx = ta.adx(c.high, c.low, c.close, 14)
# 추세 방향
ema20 = ta.ema(c.close, 20)
ema50 = ta.ema(c.close, 50)
# 오실레이터
rsi = ta.rsi(c.close, 14)
k, d = ta.stoch(c.high, c.low, c.close, 14, 3, 3)
c.line("EMA 20", ema20, color="orange")
c.line("EMA 50", ema50, color="blue")
threshold = script_params["adx_threshold"]
if adx[0] > threshold:
# === 추세 모드: 추세 추종 ===
log(f"[추세 모드] ADX={adx[0]:.0f}")
if ema20 > ema50 and c.close > ema20:
buy(tag=f"추세 추종 매수 (ADX={adx[0]:.0f})")
elif ema20 < ema50:
sell(tag=f"추세 추종 매도 (ADX={adx[0]:.0f})")
else:
hold()
else:
# === 횡보 모드: 역추세 (오실레이터) ===
log(f"[횡보 모드] ADX={adx[0]:.0f}")
if rsi[0] < 30 and k[0] < 20:
buy(tag=f"횡보 반등 — RSI={rsi[0]:.0f}, K={k[0]:.0f}")
elif rsi[0] > 70 and k[0] > 80:
sell(tag=f"횡보 반락 — RSI={rsi[0]:.0f}, K={k[0]:.0f}")
else:
hold()
4. 멀티 타임프레임 모멘텀¶
일봉 추세 + 1시간봉 모멘텀 + 5분봉 진입 타이밍을 조합합니다.
version("1.0")
description("멀티 타임프레임 모멘텀 전략")
# 일봉: 추세 방향
d1 = chart("1D")
sma20_d = ta.sma(d1.close, 20)
sma60_d = ta.sma(d1.close, 60)
trend_up = sma20_d > sma60_d
trend_down = sma20_d < sma60_d
# 1시간봉: 모멘텀
h1 = chart("1H")
rsi_h = ta.rsi(h1.close, 14)
mom_h = ta.mom(h1.close, 5)
# 5분봉: 진입 타이밍
m5 = chart("5T")
ema5_m = ta.ema(m5.close, 5)
ema20_m = ta.ema(m5.close, 20)
m5.line("EMA 5", ema5_m, color="orange")
m5.line("EMA 20", ema20_m, color="blue")
# 3단계 조건
if trend_up and rsi_h[0] < 50 and mom_h[0] > 0 and ema5_m.cross_up(ema20_m):
buy(tag="일봉 상승 + 시간봉 모멘텀 + 5분봉 크로스")
elif trend_down and rsi_h[0] > 50 and mom_h[0] < 0 and ema5_m.cross_down(ema20_m):
sell(tag="일봉 하락 + 시간봉 약세 + 5분봉 크로스")
else:
hold()
5. 변동성 수축 → 돌파 전략¶
볼린저밴드 수축 후 방향 감지하여 돌파를 포착합니다.
version("1.0")
description("변동성 수축 후 돌파 전략")
c = chart("1D")
# 볼린저밴드
upper, mid, lower = ta.bbands(c.close, 20, 2.0)
band_width = (upper[0] - lower[0]) / mid[0]
# 밴드 폭 이동평균 (수축 감지)
bw_series = upper - lower
bw_sma = ta.sma(bw_series, 50)
# ATR
atr = ta.atr(c.high, c.low, c.close, 14)
atr_sma = ta.sma(atr, 50)
# 수축 상태 감지
squeeze = bw_series[0] < bw_sma[0] * 0.6 and atr[0] < atr_sma[0] * 0.7
c.line("BB Upper", upper, color="red")
c.line("BB Lower", lower, color="green")
if squeeze:
log("변동성 수축 감지!")
if c.close[0] > upper[0]:
c.marker("BREAKOUT", color="green", position="below", shape="arrow")
buy(tag="스퀴즈 후 상방 돌파")
elif c.close[0] < lower[0]:
c.marker("BREAKDOWN", color="red", position="above", shape="arrow")
sell(tag="스퀴즈 후 하방 이탈")
else:
hold(tag="스퀴즈 중 — 돌파 대기")
else:
hold(tag="수축 없음")