멀티 타임프레임 (Multi-Timeframe)¶
QuantiqDSL은 하나의 전략에서 여러 타임프레임의 데이터를 동시에 참조할 수 있습니다. 이를 통해 상위 타임프레임에서 추세를 확인하고 하위 타임프레임에서 진입 타이밍을 잡는 전략을 구현할 수 있습니다.
기본 사용법¶
chart()를 여러 번 호출하여 다른 타임프레임의 데이터를 가져옵니다.
각 ScaleChart 객체는 독립적인 OHLCV 시계열을 가지며, 개별적으로 지표를 계산할 수 있습니다.
d1 = chart("1D")
h1 = chart("1H")
m5 = chart("5T")
# 각 타임프레임에서 독립적으로 지표 계산
sma_d1 = ta.sma(d1.close, 20) # 일봉 20일 SMA
rsi_h1 = ta.rsi(h1.close, 14) # 1시간봉 14기간 RSI
ema_m5 = ta.ema(m5.close, 12) # 5분봉 12기간 EMA
탑다운 분석¶
멀티 타임프레임의 가장 일반적인 활용은 탑다운 분석입니다.
flowchart TD
A[일봉 - 추세 방향 확인] --> B[1시간봉 - 모멘텀 확인]
B --> C[5분봉 - 진입 타이밍]
C --> D[매매 결정]
예제: 3단계 확인 전략¶
version("1.0")
description("탑다운 멀티 타임프레임 전략")
# 1단계: 일봉 — 추세 확인
d1 = chart("1D")
sma20_d1 = ta.sma(d1.close, 20)
sma60_d1 = ta.sma(d1.close, 60)
daily_trend_up = sma20_d1 > sma60_d1
# 2단계: 1시간봉 — 모멘텀 확인
h1 = chart("1H")
rsi_h1 = ta.rsi(h1.close, 14)
macd_line, signal, hist = ta.macd(h1.close, 12, 26, 9)
momentum_ok = rsi_h1[0] < 60 and hist[0] > hist[1]
# 3단계: 5분봉 — 진입 타이밍
m5 = chart("5T")
ema5_m5 = ta.ema(m5.close, 5)
ema20_m5 = ta.ema(m5.close, 20)
# 차트 표시 (5분봉 기준)
m5.line("EMA 5", ema5_m5, color="orange")
m5.line("EMA 20", ema20_m5, color="blue")
# 매매 결정: 3단계 모두 충족 시
if daily_trend_up and momentum_ok and ema5_m5.cross_up(ema20_m5):
buy(tag="일봉 상승추세 + 시간봉 모멘텀 + 5분봉 크로스")
elif not daily_trend_up and rsi_h1[0] > 60 and ema5_m5.cross_down(ema20_m5):
sell(tag="일봉 하락추세 + 시간봉 약세 + 5분봉 크로스")
else:
hold()
지원 타임프레임 조합¶
| 조합 | 상위 TF | 중간 TF | 하위 TF | 용도 |
|---|---|---|---|---|
| 데이 트레이딩 | 1H/4H | 15T/30T | 1T/3T/5T | 일중 매매 |
| 스윙 트레이딩 | 1D/1W | 4H | 1H | 2~5일 보유 |
| 포지션 트레이딩 | 1W | 1D | 4H | 장기 보유 |
지원 스케일 전체: 1T, 3T, 5T, 10T, 15T, 30T, 60T, 1H, 4H, 1D, 1W, 1M.
타임프레임별 지표 비교¶
version("1.0")
description("RSI 멀티 타임프레임 비교")
m5 = chart("5T")
h1 = chart("1H")
d1 = chart("1D")
rsi_m5 = ta.rsi(m5.close, 14)
rsi_h1 = ta.rsi(h1.close, 14)
rsi_d1 = ta.rsi(d1.close, 14)
log(f"RSI — 5분: {rsi_m5[0]:.1f}, 1시간: {rsi_h1[0]:.1f}, 일봉: {rsi_d1[0]:.1f}")
# 모든 타임프레임에서 과매도일 때만 강한 매수
all_oversold = rsi_m5[0] < 30 and rsi_h1[0] < 35 and rsi_d1[0] < 40
if all_oversold:
buy(tag="전 타임프레임 과매도")
주의사항¶
평가 기준 봉은 항상 1T
Studio 테스트와 백테스트는 1T(1분봉)을 평가 기준 봉으로 사용합니다.
스크립트가 chart("5T")만 사용하더라도 1T 기준으로 봉이 처리되고,
상위 스케일(5T, 1H, 1D 등)은 1T로부터 증분 집계됩니다.
따라서 5T/1H/1D 같은 상위봉은 해당 봉이 실제로 닫힌 이후에만 최종값이 보이며,
닫히기 전 1T 시점에서 상위봉의 최종값을 미리 참조하는 lookahead 동작은 허용되지 않습니다.
스크립트 평가(주문 판단)는 정규장(09:00~15:19) 봉에서만 실행됩니다.
15:30 동시호가 캔들은 상위 타임프레임 집계에만 반영되고 스크립트 평가 대상에서 제외됩니다.
틱 모드에서 정규장 밖 시각을 지정하면 마지막 정규장 봉 기준으로 평가됩니다.
라이브 무체결 구간 봉 확정
라이브 런타임에서는 실시간 틱이 없는 구간에도 봉 마감 타이머가 봉을 확정합니다.
이 경우 상위 타임프레임 barstate(scale).is_confirmed도 정상적으로 진행됩니다.
무체결 확정 봉은 거래량 0이며 가격은 직전 종가와 동일합니다.
타임프레임 혼합 주의
- 하위 타임프레임 시계열을 상위 타임프레임 지표에 직접 넣지 마세요.
- 각 타임프레임의 데이터는 해당 타임프레임의 지표에만 사용하세요.
# (X) 잘못된 사용 — 5분봉 close를 일봉 SMA에 사용
m5 = chart("5T")
d1 = chart("1D")
wrong_sma = ta.sma(m5.close, 20) # 이것은 5분봉 20기간 SMA
# (O) 올바른 사용 — 각 타임프레임별로 계산
sma_m5 = ta.sma(m5.close, 20) # 5분봉 20기간 SMA
sma_d1 = ta.sma(d1.close, 20) # 일봉 20일 SMA
상위 타임프레임 히스토리 자동 로딩
Studio 테스트에서 상위 타임프레임(1D 등)의 과거 봉은 하위 타임프레임(5T 등)과 독립적으로 로딩됩니다.
예를 들어 5분봉 3일치 + 일봉 200일치를 동시에 사용할 수 있으며,
ta.sma(d1.close, 60) 같은 장기 지표도 일봉 데이터가 충분하면 정상 계산됩니다.
스크립트가 요구하는 최소 봉 수(예: sma(close, 60) → 최소 60봉)를 자동 감지하여 필요한 만큼 로딩합니다.
크로스 타임프레임 오버레이
하위 타임프레임 차트에 상위 타임프레임 지표를 그리면(예: c5t.line("d_sma", ta.sma(d1.close, 20))),
Studio 테스트에서 각 평가 시점마다 해당 시점의 상위 지표 값이 1개씩 누적됩니다.
아직 마감되지 않은 봉의 종가가 매 틱마다 갱신되므로, 일봉 SMA가 장중에 어떻게 변화하는지
연속적으로 확인할 수 있습니다.
바 수 제한
상위 타임프레임일수록 사용 가능한 바 수가 적을 수 있습니다. c.bars로 사용 가능한 바 수를 확인하세요.
order_on과 주문 실행 타이밍
rule.order_on("5T")을 설정하면 BUY/SELL/EXIT는 5T 봉이 확정된 시점에서만 실행됩니다.
봉 미확정 구간에서는 주문이 블록되어 HOLD로 처리됩니다.
RELEASE만 예외로 order_on과 무관하게 즉시 실행됩니다.
자세한 내용은 의사결정 — order_on을 참조하세요.
성능 참고¶
백테스트에서 1T 평가 기준을 사용할 때, 각 스케일의 차트 데이터는 증분 업데이트 방식으로 처리됩니다. 스텝마다 전체 캔들을 재구축하지 않으므로 멀티 타임프레임 백테스트의 실행 속도가 캔들 수에 비례(선형)합니다.