방법론 백테스트 엔진

제2장

백테스트 엔진

당사의 백테스트 엔진은 이벤트 기반 아키텍처로 자체 개발했습니다. 거래 의사결정을 현실에서 일어나는 그대로 시뮬레이션하며, 한 번에 바 하나씩 처리하고 미래의 정보는 절대 사용하지 않습니다.

1. 이벤트 기반 아키텍처

엔진의 핵심 설계 원칙은 전략이 현재 바와 그 이전의 데이터만 볼 수 있고, 미래의 바는 절대 볼 수 없다는 것입니다. 이는 정책이 아니라 아키텍처로 강제됩니다. 전략 코드가 미래 데이터에 접근하는 것은 물리적으로 불가능합니다.

처리 루프 (바마다)

데이터 피드

OHLCV 바 도착

지표 엔진

지표 재계산

전략 로직

진입/청산 규칙 평가

주문 생성

대기 주문 생성

주문 체결

다음 바 시가에 체결

포트폴리오 업데이트

손익, 자산 곡선

순차 처리

각 바는 시간 순서대로 하나씩 처리됩니다. 엔진은 엄격한 커서를 유지하여 바 T와 그 이전의 모든 바는 읽을 수 있지만, 바 T+1은 아직 존재하지 않습니다.

결정론적 결과

같은 데이터 파일과 같은 전략 파라미터를 사용하면 엔진은 매번 동일한 결과를 냅니다. 무작위성도 없고, 실행 간 부동소수점 편차도 없습니다.

멀티 에셋 지원

엔진은 여러 종목에 대해 동시에 전략을 실행할 수 있으며, 포트폴리오 수준의 자본 제약과 자산 간 상관관계를 반영합니다.

2. 신호 생성

매매 신호는 가격 시계열에 지표 함수를 적용해 생성됩니다. 바 T의 모든 지표 값은 바 T 시점에 사용 가능한 데이터, 즉 바 0부터 바 T까지(바 T 포함)의 가격만으로 계산됩니다. 신호는 이후 바 T+1의 시가에서 실행됩니다.

# 단순화한 의사 코드 — 미래 참조(look-ahead) 금지 방식을 보여줌 for T in range(warmup_period, len(bars)): current_bar = bars[T] # 이 바의 OHLCV만 볼 수 있음 history = bars[:T+1] # T까지 포함한 모든 바 # 지표는 [0..T]로 계산 — 미래의 바는 접근 불가 sma_fast = mean(history.close[-20:]) sma_slow = mean(history.close[-50:]) rsi = rsi_func(history.close, period=14) # 바 T에서 신호 → 바 T+1 시가에 실행 (다음 함수 호출) if sma_fast > sma_slow and rsi < 70: queue_order(side='BUY', qty=position_size(), exec_bar=T+1)

지원하는 지표 유형

  • ▸ 이동평균 (SMA, EMA, WMA, DEMA, TEMA, KAMA)
  • ▸ 모멘텀 (RSI, MACD, Stochastic, CCI, ROC)
  • ▸ 변동성 (ATR, Bollinger Bands, Keltner Channels, HV)
  • ▸ 거래량 (OBV, CMF, VWAP, Volume Profile)
  • ▸ 추세 (ADX, Parabolic SAR, Ichimoku Cloud)
  • ▸ 오실레이터 (Williams %R, Ultimate Oscillator, MFI)
  • ▸ 통계 (Z-score, 선형 회귀 기울기, 상관관계)
  • ▸ 사용자 정의 복합 지표 (전략별)

신호 유형

  • ▸ 매수 진입 / 매도 진입
  • ▸ 매수 청산 / 매도 청산 (명시적)
  • ▸ 손절 트리거 (가격 기준 또는 ATR 배수)
  • ▸ 이익 실현 트리거 (고정 목표 또는 추적)
  • ▸ 분할 추가 / 분할 축소 (피라미딩 진입)
  • ▸ 시간 기준 청산 (고정 보유 기간)
  • ▸ 장세 필터 (시장 상황 게이트)
  • ▸ 리스크 기준 청산 (포트폴리오 낙폭 임계값)

3. 체결 모델

체결 모델은 주문이 어떻게 체결되는지를 결정합니다. 당사는 실제 성과를 다소 낮게 추정하는 보수적인 가정을 의도적으로 사용합니다. 실망하는 것보다 기분 좋게 놀라는 편이 낫기 때문입니다.

체결 파라미터

체결 가격
다음 바 시가 (T+1 시가) 같은 바에서의 비현실적인 체결을 방지
슬리피지
거래당 0.05% (기본값) 유동성이 높은 종목에 대한 보수적 추정
수수료 — 홍콩
왕복 0.10% 홍콩 개인 투자자용 증권사의 일반적인 수준
수수료 — 미국
왕복 0.05% 미국 증권사의 일반적인 수준
수수료 — 일본/유럽
왕복 0.15% 지역별로 더 높은 비용을 반영
최소 거래 단위
거래소 규칙에 따라 적용 소수 단위 주식 불가
공매도
과거에 허용되었던 경우에만 허용 거래소의 업틱 룰 적용
대차 비용
연 0.5%–5% (전략에 따라 다름) 매도 포지션에 해당

왜 다음 바 시가인가?

대부분의 개인용 백테스트 도구는 신호를 만든 바와 같은 바에서 주문을 체결할 수 있게 하지만, 이는 현실에서는 불가능합니다. 바 T의 종가에서 교차가 발생했다면, 신호는 바가 마감된 뒤에야 알 수 있으므로 바 T의 종가로 거래할 수 없습니다.

당사의 규칙: 바 T의 종가에서 신호 발생 → 주문 대기 → 바 T+1의 시가에 체결. 이것이 현실적으로 실행 가능한 가장 이른 시점입니다.
당사가 절대 하지 않는 것: 바 T의 종가, 고가 또는 저가로 체결하는 것. 이 가격들은 바가 마감된 뒤에야 알 수 있으므로 실시간으로 거래할 수 없습니다.

4. 포지션 사이징 모델

포지션 사이징은 각 거래에 얼마의 자본을 배분할지 결정합니다. 리포트에 사용된 사이징 모델은 항상 리포트 머리글에 공개됩니다. 전략마다 위험 특성에 따라 서로 다른 모델을 사용합니다.

고정 비율 (자기자본 대비 %)

가장 일반적

가장 널리 쓰이는 모델입니다. 각 거래에서 현재 계좌 자기자본의 일정 비율을 위험에 노출합니다. 계좌가 커지면 포지션 크기도 비례해서 커지고, 줄어들면 함께 줄어듭니다.

# 공식
포지션 크기 = 계좌 자기자본 × 위험% ÷ (진입 가격 – 손절 가격)
# 예시
계좌: HK$100,000 | 위험: 2% | 진입: HK$10 | 손절: HK$9 → 크기 = HK$2,000 ÷ HK$1 = 2,000주

고정 금액

단순한 전략

계좌 규모와 관계없이 각 거래에 일정한 금액을 배분합니다. 이해하기 쉽지만 계좌 성장에 맞춰 조정되지는 않습니다.

# 공식
포지션 크기 = 고정 금액 ÷ 진입 가격
# 예시
고정: HK$10,000 | 진입: HK$10 → 크기 = 1,000주

변동성 조정 (ATR 기반)

추세 전략

포지션 크기는 평균 실제 범위(ATR)로 측정한 종목의 최근 변동성에 반비례하여 조정됩니다. 변동성이 큰 종목은 포지션이 작아지고, 변동성이 작은 종목은 커집니다.

# 공식
포지션 크기 = (계좌 자기자본 × 위험%) ÷ (ATR(14) × ATR 배수)
# 예시
계좌: HK$100,000 | 위험: 2% | ATR: HK$0.50 | 배수: 2 → 크기 = HK$2,000 ÷ HK$1 = 2,000주

켈리 기준 (하프 켈리)

고급 활용

켈리 공식은 전략의 과거 승률과 손익비를 바탕으로 장기 성장을 최적화합니다. 변동성을 줄이기 위해 공식 결과의 50%인 하프 켈리를 사용합니다.

# 공식
f* = (W × R – (1–W)) ÷ R → 하프 켈리 = f* ÷ 2
# 예시
승률: 55% | 손익비: 2:1 → f* = (0.55×2 – 0.45)/2 = 32.5% → 하프 켈리 = 자기자본의 16.25%

5. 포트폴리오 수준 시뮬레이션

전략이 여러 종목을 동시에 거래할 때 엔진은 포트폴리오 수준의 제약을 적용합니다. 이를 통해 무제한의 거래를 동시에 보유할 수 있다는 비현실적인 상황을 방지합니다.

자본 배분

보유 중인 각 포지션은 자본을 소비합니다. 엔진은 투입된 총 자본을 추적하고, 남은 현금이 최소 포지션 크기 미만이 되면 신규 진입을 거부합니다. 전략에서 명시하지 않는 한 레버리지는 사용하지 않습니다.

최대 보유 포지션 수

각 전략은 동시에 보유할 수 있는 포지션의 최대 개수를 정합니다. 한도에 도달하면 신규 진입 신호는 대기열에 들어가고, 기존 포지션이 청산됨에 따라 체결됩니다. 이를 통해 과도한 분산을 방지합니다.

포트폴리오 낙폭 중단

전체 포트폴리오 낙폭이 설정 가능한 임계값(기본값: 25%)을 넘으면 모든 포지션이 청산되고 일정한 냉각 기간 동안 신규 진입이 중단됩니다. 이는 리스크 관리 원칙을 시뮬레이션한 것입니다.

리밸런싱과 비중 이탈

멀티 에셋 전략의 경우 엔진이 주기적으로 포지션 비중을 목표 배분으로 되돌리는 리밸런싱을 수행합니다. 리밸런싱 주기와 허용 범위는 전략별로 설정할 수 있습니다.

6. 지원하는 시간 단위

엔진은 여러 데이터 해상도를 지원합니다. 전략에 적합한 시간 단위는 보유 기간과 신호 빈도에 따라 달라집니다.

시간 단위 일반적인 보유 기간 전략 유형 지원 범위
일봉 (종가) 5일 ~ 12개월 스윙 트레이딩, 포지션 트레이딩 모든 시장
주봉 1~6개월 추세 추종, 장기 모든 시장
월봉 3~24개월 매크로 전략, 팩터 모델 모든 시장
4시간 1~5일 단기 스윙 홍콩, 미국 (집계 방식)
1시간 4~48시간 장중 스윙 홍콩, 미국만 해당
15분 1~8시간 데이 트레이딩 홍콩, 미국만 해당
5분 30분 ~ 4시간 스캘핑 전략 미국만 해당 (제한된 이력)