전략 예제 6가지
트레이딩뷰에서 바로 백테스트하고 자동매매에 쓸 수 있는 파인스크립트 전략 예제 6가지(RSI 역추세, 볼린저밴드 돌파, 이동평균 교차, 돈치안 채널 돌파, MACD+200 EMA, 분할 매수 DCA)를 전체 코드(Pine Script v6)와 함께 설명합니다.
많이 쓰이는 지표와 매매 방식으로 만든 파인스크립트 전략 예제 6가지입니다.
모두 복사해서 바로 백테스트할 수 있고, 설정 화면에 TVExtBot 주문메시지를 붙여넣으면 그대로 자동매매에 쓸 수 있습니다.
먼저 읽어 주세요
- 예제는 구조를 배우기 위한 코드입니다. 수익을 보장하지 않으며, 종목·시간봉·기간에 따라 결과가 크게 다릅니다.
- 실전에 쓰기 전에 반드시 백테스트로 검증하고, 테스트넷이나 소액으로 먼저 확인해 주세요.
- 매매 결과에 대한 책임은 사용자에게 있습니다.
전략 비교
| 전략 | 유형 | 잘 맞는 시장 | 약한 시장 |
|---|---|---|---|
| RSI 역추세 | 과매도에서 매수 | 박스권·횡보 | 강한 하락 추세 |
| 볼린저밴드 돌파 | 상단 돌파 시 매수 | 변동성이 커지는 추세 초입 | 가짜 돌파가 잦은 횡보 |
| 이동평균 교차 | 골든크로스 매수 | 길게 이어지는 추세 | 횡보 (잦은 손절) |
| 돈치안 채널 돌파 | N봉 최고가 돌파 시 매수 | 크게 이어지는 추세 | 횡보 (가짜 돌파) |
| MACD + 200 EMA | 상승 추세 속 눌림목 매수 | 완만한 상승 추세 | 하락 추세 (진입 없음)·급변동 |
| 분할 매수(DCA) | 일정 간격으로 나눠 매수 | 장기 우상향 현물 | 길게 이어지는 하락 |
모든 코드는 같은 구조입니다: 설정 → 지표 계산 → 신호 → 주문(alert_message 포함). 모두 롱 전용이고, 분할 매수를 뺀 다섯 전략에는 손절(%)을 넣었습니다.
1. RSI 역추세 전략
RSI가 과매도(30) 아래로 내려갔다가 다시 올라올 때 매수하고, 과매수(70)에 닿으면 청산합니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("RSI 역추세 전략", overlay = false,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10,
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
rsiLen = input.int(14, "RSI 기간", minval = 2)
oversold = input.int(30, "과매도", minval = 1, maxval = 50)
overbought = input.int(70, "과매수", minval = 50, maxval = 99)
slPct = input.float(3.0, "손절 (%)", minval = 0.1, step = 0.1)
entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
exitMsg = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
rsi = ta.rsi(close, rsiLen)
plot(rsi, "RSI", color.purple)
hline(oversold, "과매도", color.green)
hline(overbought, "과매수", color.red)
longSignal = ta.crossover(rsi, oversold)
exitSignal = ta.crossover(rsi, overbought)
if longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long, alert_message = entryMsg)
if strategy.position_size > 0
strategy.exit("SL", "Long", stop = strategy.position_avg_price * (1 - slPct / 100), alert_message = exitMsg)
if exitSignal
strategy.close("Long", alert_message = exitMsg)RSI는 가격과 범위가 달라 overlay = false 로 차트 아래 별도 창에 표시합니다.
2. 볼린저밴드 돌파 전략
종가가 볼린저밴드 상단을 돌파하면 매수하고, 중심선(이동평균) 아래로 내려오면 청산합니다. 변동성이 커지며 추세가 시작되는 구간을 노립니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("볼린저밴드 돌파 전략", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10,
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
bbLen = input.int(20, "기간", minval = 2)
bbMult = input.float(2.0, "표준편차 배수", minval = 0.5, step = 0.1)
slPct = input.float(3.0, "손절 (%)", minval = 0.1, step = 0.1)
entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
exitMsg = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
[basis, upper, lower] = ta.bb(close, bbLen, bbMult)
plot(basis, "중심선", color.orange)
p1 = plot(upper, "상단", color.blue)
p2 = plot(lower, "하단", color.blue)
fill(p1, p2, color.new(color.blue, 92))
longSignal = ta.crossover(close, upper)
exitSignal = ta.crossunder(close, basis)
if longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long, alert_message = entryMsg)
if strategy.position_size > 0
strategy.exit("SL", "Long", stop = strategy.position_avg_price * (1 - slPct / 100), alert_message = exitMsg)
if exitSignal
strategy.close("Long", alert_message = exitMsg)3. 이동평균 교차 전략
빠른 이동평균이 느린 이동평균을 위로 교차(골든크로스)하면 매수, 아래로 교차(데드크로스)하면 청산합니다. 이동평균 종류(SMA/EMA)를 설정에서 고를 수 있습니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("이동평균 교차 전략", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10,
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
maType = input.string("EMA", "이동평균 종류", options = ["SMA", "EMA"])
fastLen = input.int(20, "빠른 이동평균", minval = 1)
slowLen = input.int(60, "느린 이동평균", minval = 2)
slPct = input.float(3.0, "손절 (%)", minval = 0.1, step = 0.1)
entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
exitMsg = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
ma(src, len) => maType == "SMA" ? ta.sma(src, len) : ta.ema(src, len)
fast = ma(close, fastLen)
slow = ma(close, slowLen)
plot(fast, "빠른 이동평균", color.orange)
plot(slow, "느린 이동평균", color.blue)
longSignal = ta.crossover(fast, slow)
exitSignal = ta.crossunder(fast, slow)
if longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long, alert_message = entryMsg)
if strategy.position_size > 0
strategy.exit("SL", "Long", stop = strategy.position_avg_price * (1 - slPct / 100), alert_message = exitMsg)
if exitSignal
strategy.close("Long", alert_message = exitMsg)4. 돈치안 채널 돌파 전략 (터틀 트레이딩)
최근 20봉의 최고가를 넘으면 매수하고, 최근 10봉의 최저가 아래로 내려가면 청산합니다. 1980년대 「터틀 트레이딩」으로 유명해진 추세 추종 규칙을 단순하게 옮긴 예제입니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("돈치안 채널 돌파 전략", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10,
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
entryLen = input.int(20, "진입 채널 기간", minval = 2)
exitLen = input.int(10, "청산 채널 기간", minval = 2)
slPct = input.float(5.0, "손절 (%)", minval = 0.1, step = 0.1)
entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
exitMsg = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
// [1]: 지금 봉을 빼고 직전 봉까지의 최고가·최저가
upper = ta.highest(high, entryLen)[1]
lower = ta.lowest(low, exitLen)[1]
plot(upper, "진입 채널 (최고가)", color.green)
plot(lower, "청산 채널 (최저가)", color.red)
longSignal = close > upper
exitSignal = close < lower
if longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long, alert_message = entryMsg)
if strategy.position_size > 0
strategy.exit("SL", "Long", stop = strategy.position_avg_price * (1 - slPct / 100), alert_message = exitMsg)
if exitSignal
strategy.close("Long", alert_message = exitMsg)채널을 계산할 때 [1]로 지금 봉을 뺍니다. 빼지 않으면 지금 봉의 고가가 채널에 들어가 종가가 채널을 넘을 수 없습니다.
5. MACD 교차 + 200 EMA 필터 전략
가격이 200 EMA 위(상승 추세)에 있을 때만, MACD선이 0선 아래에서 시그널선을 위로 교차하면 매수합니다. MACD선이 시그널선을 아래로 교차하면 청산합니다. 추세 방향으로 눌림목에서 들어가는, 많이 쓰이는 조합입니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("MACD + 200 EMA 전략", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10,
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
fastLen = input.int(12, "MACD 빠른 기간", minval = 1)
slowLen = input.int(26, "MACD 느린 기간", minval = 2)
sigLen = input.int(9, "시그널 기간", minval = 1)
trendLen = input.int(200, "추세 EMA 기간", minval = 2)
slPct = input.float(3.0, "손절 (%)", minval = 0.1, step = 0.1)
entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
exitMsg = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
[macdLine, signalLine, hist] = ta.macd(close, fastLen, slowLen, sigLen)
trend = ta.ema(close, trendLen)
plot(trend, "추세 EMA", color.orange, 2)
longSignal = ta.crossover(macdLine, signalLine) and macdLine < 0 and close > trend
exitSignal = ta.crossunder(macdLine, signalLine)
if longSignal and strategy.position_size == 0
strategy.entry("Long", strategy.long, alert_message = entryMsg)
if strategy.position_size > 0
strategy.exit("SL", "Long", stop = strategy.position_avg_price * (1 - slPct / 100), alert_message = exitMsg)
if exitSignal
strategy.close("Long", alert_message = exitMsg)차트에는 200 EMA만 그립니다. MACD는 가격과 범위가 달라서, 확인하려면 트레이딩뷰 기본 지표 MACD를 따로 추가하세요. 200 EMA는 계산에 봉 200개가 필요하므로, 백테스트 기간이 너무 짧으면 거래가 거의 나오지 않습니다.
6. 분할 매수(DCA) 전략
정해진 간격(기본 1주)마다 같은 금액씩 나눠 사고, 평균 매수가보다 정한 비율(기본 20%) 오르면 전량 매도합니다. 업비트·빗썸 같은 현물에서 장기로 모아 가는 용도입니다.
전략 스크립트 (Pine Script v6)
//@version=6
strategy("분할 매수(DCA) 전략", overlay = true,
initial_capital = 10000,
default_qty_type = strategy.cash, // 한 번에 정한 금액만큼 매수
default_qty_value = 500,
pyramiding = 20, // 같은 방향으로 최대 20번까지 추가 매수
commission_type = strategy.commission.percent,
commission_value = 0.05,
slippage = 1)
period = input.timeframe("1W", "매수 간격")
maxBuys = input.int(20, "최대 매수 횟수", minval = 1, maxval = 20)
dipPct = input.float(0.0, "추가 조건: 직전 매수가보다 하락 (%)", minval = 0, step = 0.5, tooltip = "0이면 간격마다 무조건 매수")
tpPct = input.float(20.0, "익절: 평균 매수가 대비 (%)", minval = 0.5, step = 0.5)
buyMsg = input.text_area("", "매수 주문메시지", group = "TVExtBot")
sellMsg = input.text_area("", "전량 매도 주문메시지", group = "TVExtBot")
var float lastBuy = na
newPeriod = timeframe.change(period)
dipOk = na(lastBuy) or dipPct == 0 or close <= lastBuy * (1 - dipPct / 100)
if newPeriod and strategy.opentrades < maxBuys and dipOk
strategy.entry("DCA", strategy.long, alert_message = buyMsg)
lastBuy := close
if strategy.position_size > 0 and close >= strategy.position_avg_price * (1 + tpPct / 100)
strategy.close("DCA", alert_message = sellMsg)
lastBuy := na
plot(strategy.position_size > 0 ? strategy.position_avg_price : na, "평균 매수가", color.orange, style = plot.style_linebr)- 차트는 매수 간격보다 짧은 시간봉(예: 1주 간격이면 일봉·4시간봉)에서 쓰세요.
- 백테스트는 1회 500(통화 단위)으로 계산합니다. 실제 주문 금액은 매수 주문메시지의 금액을 따릅니다. 둘을 같게 맞춰야 백테스트와 실제가 비슷해집니다.
- 매수 메시지는 고정 금액 시장가 매수, 매도 메시지는 보유 수량 100% 매도로 만드세요.
분할 매수는 손절이 없습니다
하락이 길어지면 최대 매수 횟수까지 계속 삽니다. 최대 매수 횟수 × 1회 금액이 감당할 수 있는 금액인지 먼저 확인하세요.
7. 전략을 발전시키는 방법
예제를 그대로 쓰기보다 아래처럼 하나씩 더해 가며 백테스트 결과를 비교해 보세요.
- 추세 필터 추가: 일봉 추세 방향으로만 진입 → 멀티 타임프레임 사용법
- 익절·트레일링 스탑 추가 → 손절·익절·트레일링 스탑
- 설정값 최적화: 기간·배수·손절 폭을 옵티마이저로 비교 → 옵티마이저에 맞는 input 설계법
- 리페인팅·비용 점검 → 백테스트와 실전이 다른 이유
8. TVExtBot으로 자동매매하기
- TVExtBot 확장프로그램에서 롱 진입·청산 주문메시지를 만듭니다.
- 전략 설정의 TVExtBot 항목에 붙여넣습니다.
- 트레이딩뷰에서 얼러트를 추가하고 조건에서 전략을 고른 뒤, 메시지 칸에
{{strategy.order.alert_message}}를 입력합니다. - 알림 탭의 웹훅 URL 에 본인의 웹훅 URL을 입력합니다. → 웹훅URL에 의한 자동매매
예제에서는 손절과 조건 청산에 같은 청산 메시지를 쓰므로, 어느 쪽으로 청산되어도 같은 주문이 나갑니다. 분할 매수(DCA)는 매수·전량 매도 메시지 두 개를 넣습니다.
TVExtBot이 처음이라면 코인 주식 자동매매 시작하기부터 따라 해 보세요.
자주 나는 오류
파인스크립트에서 자주 나는 오류(Mismatched input, Undeclared identifier, Cannot call with argument, Cannot use plot in local scope, max_bars_back, Loop takes too long 등)의 원인과 해결 방법을 예제 코드로 정리합니다.
최적화하기 좋은 input 설계
트레이딩뷰 전략의 설정값을 자동 백테스트(최적화)하기 좋게 파인스크립트 input을 설계하는 방법. input.int와 input.float의 범위와 단계, 파라미터 수와 조합 수, 잘못된 조합 걸러내기, 과최적화를 피하는 방법을 정리합니다.