You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fithia2/docs/orb_gainers_v23_strategy.md

16 KiB

ORB Gainers V23 전략 완전 해설

버전: V23 (id: 28)
상태: DEFINITIVE FINAL CHAMPION — 모든 개선 축 소진, 라이브 배포 중
배포일: 2026-04-20
백테스트 기준일: 200d 2025-07-XX ~ 2026-04-XX, 400d 2024-09-XX ~ 2026-04-XX


1. 전략 철학

ORB Gainers의 핵심은 당일 비정상 관심 종목의 장 초반 돌파를 잡는 것이다.

Yahoo Finance Top Gainers처럼 그날 강하게 움직이는 종목을 시스템으로 추린다. 진입 구조는 Opening Range Breakout(ORB) — 첫 5분봉의 고점 돌파 — 이지만, 실제 엣지의 원천은 압축 후 확장이 아니라 당일 attention / catalyst / 비정상 거래량이다.

핵심 철학:

  • 당일 갭 + 프리마켓 거래대금 + 상대 거래량 = catalyst proxy
  • ATR이 높은 종목만 선별해 폭발적 후속 움직임이 있는 후보만 취급
  • daily_budget_reset + compound_returns=false: 단리 방식으로 매일 초기자본($10k) 기준 sizing

2. V23 개발 계보 요약

V23은 V1부터 22번의 반복 개선 끝에 도달한 최종 버전이다.

버전 핵심 발견 200d 성과
V1-V3 초기 ORB 구조 실험 -19% (regime 미적용)
V4-V7 rolling loss filter, QQQ regime, min_candidate_breadth +2~9%
V8 weight_momentum=0.15 + QQQ threshold=0.0 +19.73%
V9 min_rvol=1.5 (momentum과 시너지) +23.50% (400d)
V10 trailing_at_r: 1.5→1.0 (더 일찍 트레일) +33.17% (400d)
V11 min_breakout_rel_vol=1.2 (돌파 거래량 확인) +36.19% (400d)
V15 streak_sizing + drawdown_governor + compound +41.60% (200d)
V16 max_gap_pct=0.10, simul=4, risk=0.035 +71.01% (200d)
V17 max_gap_pct=0.04, no_partial_exit, risk=0.04 +84.36% (200d)
V18 daily_reset 모드 전환, QQQ +0.15% filter, maxpos=0.80 +103.50% (200d DR)
V19 streak_win_bonus: 0.30→0.60 +85.56% WR 60.2%
V21 trailing_tighten_at_r: 2.5→2.0 +97.25% (200d)
V22 gov_threshold: 0.03→0.025, streak_bonus: 0.60→0.70 +98.73% (200d)
V23 min_atr_pct=0.04, maxpos: 0.80→0.70 +109.32% (200d 확정)

V24-V32: 9회 연속 실패 — V23이 daily_reset 국소 최적점임을 확정.


3. V23 핵심 변경사항 (from V22)

변경 1: min_atr_pct: 0.04

ATR-14 ÷ prev_close ≥ 4% 이상인 종목만 후보로 허용.

근거: 400d 거래 데이터 분석

  • ATR/price 2-3%: WR 42.3%, 총 P&L 기여 -8%
  • ATR/price 3-4%: WR 46.2%, 총 P&L 기여 -12%
  • ATR/price 4-5%: WR 57.8%
  • ATR/price >5%: WR 62.4%, 총 P&L 기여 +104%

에너지주/안정적 기술주처럼 변동성이 낮은 종목은 ORB 전략이 요구하는 돌파 후 후속 추진력이 없다. 이들을 걸러내면 WR이 크게 개선된다.

효과: 200d 수익률 +18.19pp, WR +0.1pp, DD 거의 동일

변경 2: max_position_pct: 0.80 → 0.70

ATR이 높은 종목은 개별 거래 변동성이 크다. 포지션 한도를 낮춰 포트폴리오 수준 DD를 억제.

검증:

  • max_position_pct=0.75 + min_atr_pct=0.04: 400d DD -24.32% (FAIL 게이트 기준 -24% 초과)
  • max_position_pct=0.70 + min_atr_pct=0.04: 400d DD -23.97% (PASS by 0.03pp)

두 변경의 시너지

min_atr_pct 단독: 400d DD -24.38% (게이트 실패)
max_position_pct 단독: 효과 미미
함께: 고품질 후보 선별 + 변동성 관리 → 시너지


4. 전략 파라미터 전체

strategy_mode: orb

orb_strategy:
  # === 엔진/기본 ===
  engine_family: gainers_leader     # 당일 강세주 추적 엔진
  live_readiness: live_ready
  entry_direction: long_only
  orb_minutes: 5                    # 9:30-9:35 첫 5분봉
  sim_bar_minutes: 5
  order_timeout_minutes: 45         # 9:40-10:25 진입 대기

  # === 진입 허용 규칙 ===
  allow_doji_breakout: true         # 도지봉도 돌파 허용
  allow_red_to_green_breakout: true # 갭하 후 반등도 허용

  # === 후보 필터 ===
  min_price: 10.0                   # $10 이상
  min_avg_dollar_volume: 25000000   # 평균 거래대금 $25M 이상
  min_atr_14: 0.50                  # ATR-14 절대값 $0.50 이상
  min_atr_pct: 0.04                 # ★ V23: ATR/price ≥ 4% (변동성 확인)
  min_rvol: 1.5                     # 상대 거래량 1.5배 이상
  min_abs_gap_pct: 0.02             # 갭 2% 이상
  min_premarket_dollar_vol: 1500000 # 프리마켓 거래대금 $1.5M 이상
  max_gap_pct: 0.04                 # 갭 상한 4% (V17에서 도입)
  max_candidates: 20                # 후보 최대 20종목
  max_candidates_per_sector: 3      # 섹터당 최대 3종목
  min_candidates_to_trade: 1        # 최소 1종목 있으면 거래

  # === 시장 레짐 필터 ===
  min_candidate_breadth: 0.60       # 후보 60%가 양봉 돌파 조건 충족 시만 거래
  market_regime_spy_threshold: 0.0015
  market_regime_ticker: QQQ         # QQQ 기준 레짐 판단
  # QQQ 오픈 갭 > +0.15% → 거래 / ≤ 0.15% → 스킵 (V18에서 도입)

  # === 롤링 손실 제한 ===
  rolling_loss_days: 7              # 최근 7거래일
  rolling_loss_threshold: -0.07     # 7일 누적 손실 -7% 이하 시 거래 중단
  ticker_cooldown_days: 0           # 종목 재사용 쿨다운 없음

  # === 포지션 관리 ===
  max_simultaneous_entries: 3       # 동시 최대 3종목 진입
  min_breakout_rel_vol: 1.2         # 돌파봉 거래량 ≥ ORB 이후 평균 1.2배 (V11에서 도입)

  # === 후보 랭킹 가중치 ===
  weight_rvol: 0.35                 # 상대 거래량 35%
  weight_gap: 0.20                  # 갭 크기 20%
  weight_dollar_vol: 0.05           # 당일 거래대금 5%
  weight_premarket_dollar_vol: 0.25 # 프리마켓 거래대금 25%
  weight_body_ratio: 0.0            # 캔들 몸통 비율 미사용
  weight_momentum: 0.15             # 5일 모멘텀 15% (V8에서 도입)

  # === 리스크 관리 / 스탑 ===
  atr_stop_multiplier: 0.75         # 진입 후 스탑: 진입가 - 0.75×ATR
  breakeven_at_r: 1.0               # 1R 도달 시 본전 스탑으로 이동
  trailing_at_r: 1.0                # 1R 도달 시 트레일링 활성화 (V10에서 도입)
  trailing_stop_atr_multiplier: 0.8 # 트레일링 스탑: 고점 - 0.8×ATR
  trailing_tighten_at_r: 2.0        # 2R 도달 시 트레일 조임 (V21에서 2.5→2.0)
  trailing_stop_atr_multiplier_tight: 0.3  # 조인 트레일: 고점 - 0.3×ATR
  partial_exit_at_r: 99.0           # 사실상 부분 청산 없음 (V17에서 제거)
  partial_exit_pct: 0.50

  # === 사이징 ===
  risk_per_trade_pct: 0.05          # 거래당 리스크 5%
  max_position_pct: 0.70            # ★ V23: 일일 예산 대비 최대 포지션 70%
  daily_max_loss_pct: 0.05          # 일별 최대 손실 5%
  max_stops_per_day: 5              # 하루 최대 스탑아웃 5회
  exit_minutes_before_close: 5      # 장 마감 5분 전 강제 청산

  # === drawdown 거버너 ===
  drawdown_governor_threshold: 0.025  # 피크 대비 -2.5% 이상 DD 시 사이징 축소 시작 (V22에서 0.03→0.025)
  drawdown_governor_min_scale: 0.30   # DD 시 최소 30%까지 사이징 축소

  # === 스트릭 사이징 ===
  streak_sizing_win_bonus: 0.70       # 연승 시 70%씩 사이징 증가 (V22에서 0.60→0.70)
  streak_sizing_max: 2.5              # 최대 2.5배까지

  # === 실행 모드 ===
  slippage_bps: 5.0           # 백테스트 슬리피지 5bp
  initial_capital: 10000      # 초기 자본 $10,000
  compound_returns: false      # 단리 모드
  daily_budget_reset: true     # 매일 $10k 기준으로 사이징 리셋
  settlement_days: 1           # 백테스트: T+1 결제 (라이브에선 0으로 오버라이드)

universe:
  source: midlarge             # mid+large cap 유니버스 (S&P400 + S&P500)

5. 후보 선별 메커니즘

5.1 프리마켓 스크리닝 (09:20 ET)

  1. 유니버스 로드: midlarge universe (S&P 400 + S&P 500)
  2. 일봉 데이터 수집: Oracle /api/v1/price/data 경유
  3. 기본 필터:
    • min_price ≥ $10
    • min_avg_dollar_volume ≥ $25M
    • min_atr_14 ≥ $0.50
    • min_atr_pct ≥ 4% (V23 신규)
  4. 프리마켓 데이터:
    • Oracle snapshots API로 프리마켓 갭, 거래대금 수집
    • min_abs_gap_pct ≥ 2%, max_gap_pct ≤ 4%
    • min_premarket_dollar_vol ≥ $1.5M
  5. 랭킹: rvol(0.35) + gap(0.20) + dollar_vol(0.05) + premkt_dollar_vol(0.25) + momentum(0.15) 가중합
  6. 상위 20종목, 섹터당 최대 3종목

5.2 ORB 감지 (09:40 ET)

  1. 인트라데이 9:30-9:35 5분봉 수집 (Oracle 경유)
  2. ORB 레벨 확정: 첫 5분봉 고가(breakout level)
  3. 레짐 체크:
    • QQQ 오픈 갭 > 0.15% 이어야 거래
    • 후보 중 60% 이상이 양봉 조건 충족해야 거래
  4. 롤링 손실 체크: 최근 7일 누적 -7% 초과 시 거래 스킵

5.3 돌파 감지 (09:40~10:25, 5분 간격)

  • 현재가 > ORB 고가 → 진입 트리거
  • min_breakout_rel_vol ≥ 1.2: 돌파봉 거래량 ≥ ORB 이후 평균 거래량 × 1.2배
  • 동시 최대 3종목
  • 45분 이내 미진입 → 자동 만료

6. 포지션 관리 메커니즘

스탑 로직 (orb_simulator.py:477-580 미러링)

진입 후:
  초기 스탑 = 진입가 - 0.75×ATR

1R 도달 시 (수익 = 리스크×1):
  스탑 → 본전 (breakeven_at_r=1.0)
  트레일링 활성화

트레일링 중:
  스탑 = max(현재 스탑, 최고가 - 0.8×ATR)

2R 도달 시 (trailing_tighten_at_r=2.0):
  스탑 = max(현재 스탑, 최고가 - 0.3×ATR)  ← 더 빠듯하게 조임

강제 청산: 15:55 ET

사이징

# daily_budget_reset=true: 매일 initial_equity($10k) 기준
daily_budget = 10,000  # (compound_returns=false, 단리)

# 기본 사이징
risk_amount = daily_budget × risk_per_trade_pct(0.05) = $500
position_size = risk_amount / (ATR × atr_stop_multiplier)
max_dollars = daily_budget × max_position_pct(0.70) = $7,000
actual_position = min(position_size, max_dollars)

# drawdown 거버너 조정
# DD > 2.5% 시 0.30~1.0 스케일 적용

# 스트릭 사이징 조정
# 연승 시 +70%씩 증가, 최대 2.5배

7. 검증 결과

TRUE BASELINE (확정, 2026-04-20)

200d 백테스트 (intraday_20260420_203705_99ded639.json + 재확인 5597b16d):

지표 수치
수익률 +109.32%
승률 (WR) 58.1%
Sharpe 3.01
최대 DD -12.91%
거래 수 160건

참고: 이전 기록 +116.92%는 데이터 파이프라인 버그(AH 클로즈 포함) 결과임. 정식 기준치는 +109.32%.

400d 검증

지표 V22 V23 게이트
수익률 +89.62% +120.87% ≥88% ✓
WR 52.2% 57.7% ≥52% ✓
DD -20.93% -23.97% ≥-24% ✓ (0.03pp 마진)
Sharpe 1.67 1.94
거래 수 312건 286건

분기별 400d 성과 분포

기간 수익률
2024-Q3 -4.4%
2024-Q4 +1.2%
2025-Q1 -8.4%
2025-Q2 +13.0%
2025-Q3 +42.4%
2025-Q4 +11.0%
2026-Q1 +35.2%

2024-Q3 및 2025-Q1 손실은 변동성 높은 매크로 환경에서 발생. 전략이 2024-2026 AI/crypto/biotech 모멘텀 레짐에 최적화되어 있음.


8. 리스크 관리

8.1 다층 리스크 필터

단계 필터 용도
종목 선별 min_atr_pct ≥ 4% 저변동성 drag 종목 제거
시장 레짐 QQQ 갭 > 0.15% 플랫/하락장 스킵
후보 품질 breadth ≥ 60% 분산된 강세 확인
롤링 손실 7일 -7% 연속 손실 후 거래 중단
돌파 확인 breakout_rel_vol ≥ 1.2 허위 돌파 제거
거버너 DD > 2.5% → 사이징 축소 자본 보호
회로 차단기 DD > 25% → 세션 정지 극단적 손실 방지

8.2 계좌 수준 회로 차단기

apps/orb_trader/engine.py:46:

_ACCOUNT_CIRCUIT_BREAKER_PCT = 25.0

피크 대비 25% 이상 DD 시 해당 세션의 모든 거래 정지.

8.3 알려진 한계 (CRITICAL)

600d 백테스트: +31.16%, DD -51.25%

V23은 2024-2026 고ATR 모멘텀 레짐(AI/crypto/biotech)에 맞춰 최적화됨. 2023년 후반 이전 기간을 포함하면 DD가 -51%로 급증. 시장 레짐이 바뀌면 전략 성과가 크게 저하될 수 있음.

레짐 변화 신호 모니터링 권장:

  • 7일 롤링 WR이 40% 미만으로 하락하면 전략 효능 의심
  • 연속 3일 이상 "no candidates" 발생 시 레짐 체크

9. 라이브 배포

인프라

항목
DB data/paper/orb.db
세션 ID e492695e
세션명 V23 ORB Gainers
초기 자본 $10,000
상태 파일 data/paper/.orb_auto_state.json
데몬 apps/orb_trader/daemon.py

일별 스케줄 (ET)

시간 동작
09:20 AM run_pre_screen() — 일봉 + 프리마켓 스크리닝
09:30-09:35 AM ORB 윈도우 (5분봉 형성)
09:40 AM run_orb_detection() — 인트라데이 바 → 후보 확정
09:40-10:25 AM run_breakout_check() 매 5분 — 돌파 감지 + 진입
09:40-15:55 PM run_stop_check() 매 5분 — 스탑/트레일링 체크
03:55 PM run_eod_exit() — 전체 포지션 청산
04:00 PM run_post_close() — 일별 스냅샷 기록

Oracle 의존성 (CRITICAL)

Oracle 서버 (stock-oracle 프로젝트, 로컬 localhost:18001)가 09:20 ET 이전에 반드시 실행 중이어야 한다.

  • AlpacaBroker.get_bars() → Oracle /api/v1/price/data
  • AlpacaBroker.get_intraday_bars() → Oracle
  • Oracle 없이: 바 데이터 수집 실패 → 후보 0개 → 거래 없음
  • Alpaca SDK 폴백 없음 — Oracle이 유일한 데이터 경로

run_pre_screen() 시작 시 Oracle 헬스 체크 자동 실행 (3초 타임아웃). 미응답 시 로그에 CRITICAL 경고.


10. 소진된 개선 축 (참고용)

V23이 local optimum임을 보여주는 실패 기록. 이 축들은 더 이상 탐색할 필요 없음.

파라미터 스윕 (V24, 17개 변형)

  • trailing/risk/governor/streak/atr_stop/rvol 조정 → 전부 -2pp 이상 열화
  • min_atr_pct 0.05: 과필터 (+79%)
  • min_atr_pct 0.03: 불충분 (+88%)

유니버스 변형

유니버스 200d 판정
midlarge (현재) +109.32% CHAMPION
largecap +28.1% FAIL
midcap +33.3% FAIL
smallmid +2.1% FAIL
sp500 +1.3% FAIL

레짐 필터 추가 시도 (V24 regime kill-switch)

  • QQQ 50d/20d 트렌드 필터
  • VIX max 25
  • rolling 30일 -7%/-5% 손실 필터
  • 결론: 2024년 나쁜 날들은 어떤 관측 가능한 신호로도 미리 구분 불가. 필터 추가 무의미.

ORB 타임프레임

  • 10분봉: -18.87% (재앙)
  • 15분봉: -11.14% (재앙) → 5분봉이 유일한 최적점

기타 전부 실패

  • compound 모드: DD -24.74% (게이트 실패)
  • VWAP 확인/청산: 중립 또는 마이너스
  • 진입바 클로즈 진입: -22.80pp (재앙)
  • 부분 청산 1.5R/50%: 마이너스 (V17에서 제거)

11. 실행 명령어

백테스트

# 200d 공식 백테스트
.venv/bin/python3 -m apps.intraday_bt.run \
  --config configs/intraday/strategies/orb_gainers_v23.yaml \
  --days 200

# 최근 30일 sanity check
.venv/bin/python3 -m apps.intraday_bt.run \
  --config configs/intraday/strategies/orb_gainers_v23.yaml \
  --days 30

# 400d 검증
.venv/bin/python3 -m apps.intraday_bt.run \
  --config configs/intraday/strategies/orb_gainers_v23.yaml \
  --days 400

라이브 상태 확인

# 데몬 상태 확인
python -m apps.web.orb_trading_service status

# 최근 로그
tail -50 data/paper/orb_daemon.log

# DB 조회 — 오늘 거래
python -c "
import sqlite3
conn = sqlite3.connect('data/paper/orb.db')
rows = conn.execute('SELECT * FROM trades ORDER BY entry_time DESC LIMIT 20').fetchall()
for r in rows: print(r)
"

코드 검증

python -m py_compile \
  apps/intraday_bt/run.py \
  libs/intraday/orb_simulator.py \
  apps/orb_trader/engine.py

pytest -q tests/unit/intraday/

12. 다음 단계 (미래 연구)

V23은 현재 아키텍처 내의 최종 버전이다. 추가 개선은 근본적으로 다른 전략 아키텍처를 필요로 한다:

  • VWAP deviation 전략 (개장 후 VWAP 이탈 포착)
  • Opening Range Reversal (ORB 실패 후 반전)
  • 뉴스 데이터 통합 (현재는 프리마켓 거래대금으로 proxy 사용)
  • 멀티 타임프레임 확인 (1분봉 엔트리 + 5분봉 필터)

이들은 V23의 파라미터 튜닝이 아닌 새 연구 트랙으로 진행해야 한다.