짧은 시간봉 전략은 신호가 많은 대신 추세를 거스르는 거짓 신호도 많습니다.
이 글에서는 request.security() 로 일봉·4시간봉 같은 상위 시간봉 데이터를 가져와, “큰 추세 방향으로만 진입"하는 필터를 만드는 방법을 설명합니다.

이 글에서 배우는 것
  • request.security() 기본 사용법
  • 리페인팅 없이 상위 시간봉 값을 가져오는 방법
  • 일봉 추세 필터 + 1시간봉 진입 전략 전체 코드

※ 예제 코드는 파인스크립트 v6 기준입니다.

1. request.security() 기본

request.security(symbol, timeframe, expression, gaps, lookahead)
인수의미예
symbol심볼. 현재 차트는 syminfo.tickerid"BINANCE:BTCUSDT"
timeframe시간봉"60"(1시간), "240"(4시간), "D", "W"
expression그 시간봉에서 계산할 값close, ta.ema(close, 50)
lookahead미래 값 참조 여부barmerge.lookahead_on / _off

expression 에 넣은 계산은 요청한 시간봉 기준으로 실행됩니다. 즉 ta.ema(close, 50) 을 "D" 로 요청하면 일봉 50일 EMA 가 됩니다.

2. 리페인팅 없이 가져오기

상위 시간봉의 현재 봉은 아직 마감되지 않았으므로 값이 계속 바뀝니다. 과거 봉에서는 마감된 값으로 계산되므로 백테스트와 실시간이 달라집니다. 확정된 직전 봉 값을 쓰면 해결됩니다.

// 리페인팅 없는 상위 시간봉 값 가져오기 (일봉 종가와 일봉 50 EMA)
dailyClose = request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_on)
dailyEma   = request.security(syminfo.tickerid, "D", ta.ema(close, 50)[1], lookahead = barmerge.lookahead_on)
  • close[1], ta.ema(...)[1] : 상위 시간봉의 직전(마감된) 봉 값
  • lookahead_on : 그 값을 상위 봉이 시작하는 시점부터 사용

※ [1] 없이 lookahead_on 만 쓰면 미래 데이터를 보게 되어 백테스트가 비현실적으로 좋아집니다. 원인과 확인 방법은 백테스트와 실전이 다른 이유에서 설명합니다.

3. 전략 예제: 일봉 추세 필터 + 1시간봉 진입

  • 일봉 필터: 전일 종가가 일봉 50 EMA 위면 상승 추세 → 롱만 허용
  • 진입 신호: 차트 시간봉(예: 1시간봉)의 EMA 20/50 골든크로스
  • 청산: 데드크로스 또는 일봉 추세가 하락으로 바뀔 때

전략 스크립트 (Pine Script v6)

 1//@version=6
 2strategy("일봉 추세 필터 EMA 전략", overlay = true,
 3     initial_capital   = 10000,
 4     default_qty_type  = strategy.percent_of_equity,
 5     default_qty_value = 10,
 6     commission_type   = strategy.commission.percent,
 7     commission_value  = 0.05,
 8     slippage          = 1)
 9
10// ── 설정 ─────────────────────────────
11htf       = input.timeframe("D", "필터 시간봉", group = "추세 필터")
12htfLen    = input.int(50, "필터 EMA 길이", minval = 1, group = "추세 필터")
13useFilter = input.bool(true, "추세 필터 사용", group = "추세 필터")
14fastLen   = input.int(20, "빠른 EMA", minval = 1, group = "진입")
15slowLen   = input.int(50, "느린 EMA", minval = 1, group = "진입")
16
17entryMsg = input.text_area("", "롱 진입 주문메시지", group = "TVExtBot")
18exitMsg  = input.text_area("", "롱 청산 주문메시지", group = "TVExtBot")
19
20// ── 상위 시간봉 (리페인팅 없음) ─────────────
21[htfClose, htfEma] = request.security(syminfo.tickerid, htf,
22     [close[1], ta.ema(close, htfLen)[1]], lookahead = barmerge.lookahead_on)
23upTrend  = not useFilter or htfClose > htfEma
24
25// ── 차트 시간봉 신호 ─────────────────────
26fast = ta.ema(close, fastLen)
27slow = ta.ema(close, slowLen)
28plot(fast, "빠른 EMA", color.orange)
29plot(slow, "느린 EMA", color.blue)
30plot(htfEma, "필터 EMA (상위 시간봉)", color.gray, 2, plot.style_stepline)
31
32bgcolor(useFilter ? (upTrend ? color.new(color.green, 92) : color.new(color.red, 92)) : na)
33
34longSignal = ta.crossover(fast, slow)
35exitSignal = ta.crossunder(fast, slow) or not upTrend
36
37// ── 주문 ─────────────────────────────
38if longSignal and upTrend and strategy.position_size == 0
39    strategy.entry("Long", strategy.long, alert_message = entryMsg)
40
41if exitSignal and strategy.position_size > 0
42    strategy.close("Long", alert_message = exitMsg)

결과 비교해 보기: 설정에서 추세 필터 사용을 끄고 켜며 전략 테스터의 거래 횟수, 승률, 최대 낙폭을 비교해 보세요. 일반적으로 필터를 켜면 거래 횟수는 줄고, 추세를 거스르는 손실 거래가 줄어듭니다. (결과는 종목과 기간에 따라 다릅니다.)

4. 알아 두면 좋은 점

  • 차트보다 낮은 시간봉은 가져올 수 없습니다. 1시간봉 차트에서 5분봉 값을 쓰려면 request.security_lower_tf() 를 사용합니다. (봉 안의 값이 배열로 돌아옵니다)
  • 다른 심볼도 가져올 수 있습니다. 예: 알트코인 전략에서 비트코인 추세로 필터링
    btcUp = request.security("BINANCE:BTCUSDT", "D", close[1] > ta.ema(close, 50)[1], lookahead = barmerge.lookahead_on)
  • 호출 개수에 제한이 있습니다. 한 스크립트에서 request.*() 호출은 최대 40개(요금제에 따라 다름)입니다. 같은 심볼·시간봉은 튜플로 한 번에 가져오면 좋습니다.
    [dClose, dEma] = request.security(syminfo.tickerid, "D", [close[1], ta.ema(close, 50)[1]], lookahead = barmerge.lookahead_on)
  • 자동매매 얼러트는 차트 시간봉 기준으로 전송됩니다. 얼러트를 만들 때 차트 시간봉이 백테스트한 시간봉과 같은지 확인해 주세요.

만든 전략을 자동매매로 연결하는 방법은 얼러트 메시지 정리와 웹훅URL에 의한 자동매매를 참고해 주세요.