기본 전략 예제¶
QuantiqDSL의 기본 기능을 활용한 간단한 전략 예제 모음입니다.
실제 runtime 예제 라이브러리는 단순히 같은 지표의 기간만 바꾼 복제본보다, 다음처럼 구조적으로 다른 전략 축을 우선합니다.
- 스타터 템플릿: 바로 수정해 쓰는 기본 골격
- 커뮤니티 전략: 추세, 모멘텀, 변동성, 거래량, 가격행동, 멀티 타임프레임
- 확장 예제: 평균회귀, 패턴, 복합 전략, 수동 계산 지표
즉 RSI/MACD를 여러 번 반복해 늘리는 것보다, 진입/청산 논리와 차트 해석이 다른 예제를 더 중요하게 봅니다.
1. 골든크로스 / 데드크로스¶
가장 기본적인 이동평균 크로스오버 전략입니다.
version("1.0")
description("SMA 골든크로스/데드크로스 전략")
param("fast", "fast", 5)
param("slow", "slow", 20)
c = chart("1D")
fast_ma = ta.sma(c.close, script_params["fast"])
slow_ma = ta.sma(c.close, script_params["slow"])
c.line("Fast", fast_ma, color="orange")
c.line("Slow", slow_ma, color="blue")
if fast_ma.cross_up(slow_ma):
c.marker("BUY", color="green", position="below", shape="triangle")
buy(tag=f"골든크로스: {script_params['fast']}일선 > {script_params['slow']}일선")
elif fast_ma.cross_down(slow_ma):
c.marker("SELL", color="red", position="above", shape="triangle")
sell(tag=f"데드크로스: {script_params['fast']}일선 < {script_params['slow']}일선")
else:
hold()
2. RSI 과매수/과매도 전략¶
RSI가 극단 구간에 진입했다가 빠져나올 때 매매합니다.
version("1.0")
description("RSI 과매수/과매도 반전 전략")
param("period", "period", 14)
param("overbought", "overbought", 70)
param("oversold", "oversold", 30)
c = chart("1D")
rsi = ta.rsi(c.close, script_params["period"])
c.line("RSI", rsi, color="purple")
c.hline("과매수", script_params["overbought"], color="red")
c.hline("과매도", script_params["oversold"], color="green")
c.hline("중심", 50, color="gray")
ob = script_params["overbought"]
os_level = script_params["oversold"]
# 과매도 구간에서 탈출할 때 매수
if rsi[1] < os_level and rsi[0] >= os_level:
buy(tag=f"RSI 과매도 탈출: {rsi[0]:.1f}")
# 과매수 구간에서 탈출할 때 매도
elif rsi[1] > ob and rsi[0] <= ob:
sell(tag=f"RSI 과매수 탈출: {rsi[0]:.1f}")
else:
hold()
3. 볼린저밴드 반전 전략¶
볼린저밴드의 상하단을 지지/저항으로 활용합니다.
version("1.0")
description("볼린저밴드 평균회귀 전략")
param("bb_period", "bb period", 20)
param("bb_std", "bb std", 2.0)
c = chart("1D")
upper, mid, lower = ta.bbands(c.close, script_params["bb_period"], script_params["bb_std"])
c.line("BB Upper", upper, color="red")
c.line("BB Mid", mid, color="gray")
c.line("BB Lower", lower, color="green")
# 하단밴드 이탈 후 반등 → 매수
if c.close[1] < lower[1] and c.close[0] > lower[0]:
buy(tag="볼린저밴드 하단 반등")
# 상단밴드 이탈 후 반락 → 매도
elif c.close[1] > upper[1] and c.close[0] < upper[0]:
sell(tag="볼린저밴드 상단 반락")
else:
hold()
4. 이동평균 정배열 전략¶
3개의 이동평균이 정배열(단기 > 중기 > 장기)일 때 매수합니다.
version("1.0")
description("이동평균 정배열 전략")
c = chart("1D")
sma5 = ta.sma(c.close, 5)
sma20 = ta.sma(c.close, 20)
sma60 = ta.sma(c.close, 60)
c.line("SMA 5", sma5, color="red")
c.line("SMA 20", sma20, color="blue")
c.line("SMA 60", sma60, color="green")
# 정배열: 5일 > 20일 > 60일
bullish_align = sma5 > sma20 and sma20 > sma60
# 역배열: 5일 < 20일 < 60일
bearish_align = sma5 < sma20 and sma20 < sma60
if bullish_align and c.close > sma5:
buy(tag="이동평균 정배열 + 가격 > 5일선")
elif bearish_align:
sell(tag="이동평균 역배열")
else:
hold(tag="혼조세")
5. 거래량 돌파 전략¶
평균 거래량의 2배 이상 거래량과 함께 가격이 상승하면 매수합니다.
version("1.0")
description("거래량 돌파 전략")
param("vol_mult", "vol mult", 2.0)
c = chart("1D")
vol_sma = ta.sma(c.volume, 20)
sma20 = ta.sma(c.close, 20)
c.line("SMA 20", sma20, color="blue")
# 거래량 폭증 + 양봉 + 이평선 위
vol_surge = c.volume[0] > vol_sma[0] * script_params["vol_mult"]
bullish_candle = c.close[0] > c.open[0]
above_ma = c.close > sma20
if vol_surge and bullish_candle and above_ma:
c.marker("VOL!", color="green", position="below", shape="circle")
buy(tag=f"거래량 {c.volume[0]/vol_sma[0]:.1f}배 폭증 + 양봉")
elif c.close < sma20:
sell(tag="이평선 이탈")
else:
hold()
6. ATR 기반 추세 추종¶
ATR을 활용한 트레일링 스탑 기반 전략입니다.
version("1.0")
description("ATR 트레일링 스탑 전략")
param("atr_mult", "atr mult", 2.0)
param("atr_period", "atr period", 14)
c = chart("1D")
atr = ta.atr(c.high, c.low, c.close, script_params["atr_period"])
sma20 = ta.sma(c.close, 20)
# ATR 기반 채널
upper_band = sma20[0] + atr[0] * script_params["atr_mult"]
lower_band = sma20[0] - atr[0] * script_params["atr_mult"]
c.line("SMA 20", sma20, color="blue")
c.hline("Upper", upper_band, color="red")
c.hline("Lower", lower_band, color="green")
if c.close[0] > upper_band:
buy(tag="ATR 상단 채널 돌파")
elif c.close[0] < lower_band:
sell(tag="ATR 하단 채널 이탈")
else:
hold()