10 KiB
Intraday ORB Reset/Comp Development Workflow
이 문서는 앞으로 intraday ORB 전략을 개발할 때 따를 기준이다. 핵심은 신호 알파와 자본 배분을 분리하는 것이다.
Principle
daily_budget_reset은 신호 개발용 truth다. 매일 같은 notional budget으로 평가하기 때문에 후반부 equity 크기가 목적함수를 지배하지 않는다.
compound_returns는 운용 검증용 truth다. 실제로 운용할 때 자본이 커지거나 줄어드는 경로 의존성이 반영된다.
따라서 ORB 개발은 다음 규칙을 따른다.
- Entry, ranking, overlay, exit 로직은 먼저 daily reset 전략에서 개발한다.
- Compound 성능이 부족하다고 entry/exit 신호를 comp total return에 맞춰 직접 튜닝하지 않는다.
- Comp 전용 변경은 capital allocator에 한정한다.
- 최종 후보는 reset과 comp를 모두 통과해야 한다.
Non-Negotiable SQS Policy
ORB SQS는 daily reset 전용 rank다. Compound run은 점수를 매기는 대상이 아니라 deployment diagnostic이다.
apps.intraday_bt.orb_validate는 기본적으로compound_returns=false,daily_budget_reset=true로 강제해서 SQS를 계산한다.--allow-compound로 실행한 결과는 SQS rank에 쓰지 않는다. JSON의 score source가compound_diagnostic_not_ranked이면 해당 결과는 운용 검증 메모로만 취급한다.- Compound 결과가 약하면 entry/ranking/exit를 comp total return에 맞춰 바꾸지 않는다.
- Compound에서 바꿀 수 있는 것은 allocator/capital policy뿐이다:
single_trade_loss_cap_basis,single_trade_loss_cap_pct,max_position_pct,risk_per_trade_pct,drawdown_governor_*,streak_sizing_*,settlement_days, GFV 관련 정책. - 특히 계좌가 커진 뒤 sizing이 눌리는 문제는 signal 문제가 아니라 capital policy 문제다. 예를 들어
single_trade_loss_cap_basis: initial은 복리 후반부 포지션을 고정 cap으로 누를 수 있고, comp 검증에서는equitybasis가 더 적절한지 별도로 본다.
File Pattern
한 버전은 가능한 한 두 파일로 관리한다.
*_reset_*.yaml: 신호 개발용 primary config.*_comp_allocator.yaml: 같은 신호를 쓰는 실제 복리 운용 검증용 companion config.
전략 YAML은 항상 standalone이어야 한다. extends 기반 상속은 지원하지 않으며, 로더는 extends 키를 발견하면 즉시 실패한다. Comp 배포용 파일도 원본 신호 설정을 완전히 materialize한 뒤 아래 capital overlay만 적용한다.
compound_returns: truedaily_budget_reset: falsesingle_trade_loss_cap_basis: equity
예시:
What Can Be Tuned
Daily reset signal layer에서 바꿀 수 있는 것:
min_rvol,min_breakout_rel_vol, gap filters, premarket volume filters.- ranking weights such as
weight_rvol,weight_gap,weight_premarket_dollar_vol. - entry overlays such as crowded-gap, countertrend-gap, stalled-gap, reclaim guards.
- ORB exit behavior such as ATR stop/trail/timeout, if the idea is signal-quality related.
Comp allocator layer에서만 바꿀 수 있는 것:
compound_returns,daily_budget_reset,settlement_days.max_position_pct,risk_per_trade_pctif used strictly as capital deployment.single_trade_loss_cap_pct,single_trade_loss_cap_basis.drawdown_governor_*,streak_sizing_*, rolling WR sizing.
Comp sweep에서 entry/ranking/exit filter를 같이 바꾸면 안 된다. 그렇게 하면 후반 equity 구간에 맞춘 과최적화가 된다.
Required Validation Matrix
새 ORB 후보의 기본 검증 기준은 504 trading days daily reset이다. 200d와 60d는 최근 구간 훼손 방지용 guard로만 사용한다. 한 구간의 total return만 보고 승격하지 않는다.
기본 검증 커맨드:
python -m apps.intraday_bt.orb_validate \
--config configs/intraday/strategies/<candidate_reset_config>.yaml \
--baseline-config configs/intraday/strategies/<current_baseline_reset_config>.yaml \
--backend official \
--start 2024-01-01 \
--end 2026-05-06 \
--output-json tmp/orb_validation/<candidate>_vs_<baseline>.json
이 커맨드는 아래를 한 번에 계산한다.
- Primary: 최근
504ddaily reset. - Chronological split: primary 504d 내부의
252d train / 126d valid / 126d test. - Guard: 최근
200d,60ddaily reset. - WFV:
252d train / 63d test / 63d steprolling walk-forward validation. - Baseline 대비 delta, promotion gate, 단일
ORB SQS.
ORB SQS는 PEAD의 SQS와 같은 목적으로 쓰는 ORB 전용 점수다. 단일 2년 total return을 직접 최적화하지 않도록 아래 네 축을 합산한 뒤 deployment gate로 감점한다.
primary_quality25%: 504d return, annualized return, Sharpe, PF, max DD, worst day, tail loss, activity.split_rqs30%: 252/126/126 chronological split의 RQS. valid/test가 약하면 점수가 크게 낮아진다.wfqs_v230%: rolling WFV test fold의 수익률, worst fold, positive fold rate, PF, DD, fold variance, trade credibility.temporal_robustness15%: 최근 200d에 수익이 과도하게 몰린 후보를 감점한다.
이 점수는 signal quality를 평가한다. Compound return, final equity, 후반부 equity growth는 ORB SQS 구성요소가 아니다.
--backend official이 승격 기준이다. 이 backend는 apps/intraday_bt/run.py를 직접 호출하므로 live/official backtest 경로와 같은 candidate augmentation, catalyst/attention feature, support ticker, market-quality logic을 사용한다. 실행 시간 때문에 official backend는 504d를 한 번 연속 실행한 뒤 그 일별 결과에서 guard/split/WFV metrics를 파생한다. --backend research는 빠른 탐색용으로만 쓴다.
기본 수동 재현 matrix는 아래와 같다.
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/<reset_config>.yaml \
--days 504
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/<reset_config>.yaml \
--start 2025-07-09 \
--end 2026-04-23
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/<comp_allocator_config>.yaml \
--days 200
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/<comp_allocator_config>.yaml \
--start 2025-07-09 \
--end 2026-04-23
각 결과는 전략 YAML의 _meta.description에 result path, total return, max DD, Sharpe, profit factor, trade count로 기록한다.
Acceptance Rule
Daily reset은 신호 채택 기준이다.
- 기본 rank는
ORB SQS다. 단일 200d/504d return이 높아도 SQS가 낮으면 채택하지 않는다. - 기존 reset champion보다
ORB SQS가 개선되어야 하고,504d기준 total return, DD, Sharpe, profit factor 중 최소 하나가 명확히 개선되어야 한다. 200d와60d는 최근 성능이 크게 훼손되지 않는지 확인하는 guard다. 최근 구간만 좋아지고504d가 망가지면 승격하지 않는다.- WFV의 test fold가 대부분 양수여야 한다. 단일 fold 또는 최근 1~2개월에만 의존하는 후보는 탈락시킨다.
- DD나 trade count가 악화되면 그 이유가 설명 가능해야 한다.
- 단일 날짜 수익에만 의존하는 후보는 탈락시킨다.
- Sharpe/PF가 비정상적으로 높아진 후보는 slippage stress와 주변 파라미터 안정성까지 통과해야 한다.
Comp는 운용 가능성 기준이다.
- Comp total return이 높아도 reset 성능이 약하면 채택하지 않는다.
- Comp DD가 reset 대비 커지는 것은 정상이나, DD 악화가 수익 개선 대비 과도하면 탈락시킨다.
- Comp 성능 보정은 signal retune이 아니라 allocator sweep으로 처리한다.
Robustness Gate
Sharpe/PF가 높거나 변경이 소수 trade에만 작동하는 후보는 추가 gate를 통과해야 한다.
- Rolling 200d와 anchored 200d를 모두 검증한다.
- 기본
slippage_bps=5뿐 아니라10,15bps stress도 같이 본다. - 하나의 exact parameter가 아니라 주변값 cluster가 같이 살아남아야 한다.
- 정렬 기준은 단일 Sharpe 최고점이 아니라 평균 return, worst return, 평균 PF, worst PF를 같이 본다.
- 좋은 후보가 한 구간 또는 한 slippage에서만 이기면 채택하지 않는다.
예시:
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers_v49_36_broad_reset_late_trade_throttle.yaml \
--sweep configs/intraday/sweep_orb_v49_37_broad_reset_robustness_gate.yaml \
--end 2026-04-24
python -u -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers_v49_36_broad_reset_late_trade_throttle.yaml \
--sweep configs/intraday/sweep_orb_v49_37_broad_reset_robustness_gate.yaml \
--end 2026-04-23
V49.37의 rank_rvol_pressure_size_scale=0.40은 이 gate에서 rolling/anchored 모두 평균 return/PF 기준으로 가장 안정적이었다. 반대로 0.60은 rolling 5bps 단일 조건에서는 좋아 보였지만 anchored와 slippage stress 기준으로는 덜 안정적이므로 채택하지 않는다.
Sweep Templates
Signal sweep은 reset config를 base로 둔다.
Allocator sweep은 comp allocator config를 base로 두고 capital controls만 포함한다.
V49.30 Baseline
V49.30은 이 workflow를 적용한 첫 baseline이다.
- Reset rolling 200d:
+339.87%, DD-1.14%, Sharpe5.75, PF9.75, 146 trades. - Reset anchored 200d:
+341.80%, DD-1.73%, Sharpe5.73, PF9.52, 142 trades. - Comp rolling 200d:
+412.23%, DD-2.73%, Sharpe5.64, PF13.93, 107 trades. - Comp anchored 200d:
+404.10%, DD-2.95%, Sharpe5.52, PF11.47, 104 trades.
이후 ORB 개발은 V49.30처럼 reset config를 먼저 만들고, 같은 신호의 comp allocator를 별도 검증하는 방식으로 진행한다.