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_strategy_workfl...

354 lines
11 KiB
Markdown

# ORB Gainers Strategy Development And Validation
이 문서는 현재 ORB 전략 중 `gainers_leader` 계열을 어떻게 개발하고 검증하는지 정리한 운영 문서다.
목표는 단순하다.
- `Yahoo Finance Top Gainers`처럼 당일 비정상 강세 종목을 시스템적으로 잡는다.
- 장 초반 ORB 구조를 쓰되, 실제 edge는 `압축 후 확장`이 아니라 `same-day attention / catalyst / abnormal volume`에서 찾는다.
- 연구 helper 결과와 공식 `run.py` 결과가 항상 같도록 검증한다.
이 문서는 “어떤 아이디어를 어떻게 실험하고”, “무엇을 official truth로 보고”, “어떤 함정을 피해야 하는지”를 남들이 그대로 따라할 수 있게 쓰였다.
## 1. 전략 의도
현재 `ORB Gainers`의 철학은 아래와 같다.
1. 당일 강한 종목을 찾는다.
- 단순 compression setup보다 `당일 갭`, `초반 거래량`, `프리마켓 거래대금`이 중요하다.
2. 09:35 이후의 ORB 구조를 이용해 진입한다.
- 첫 5분 봉 방향과 breakout 구조는 유지한다.
3. 같은 날 관심이 몰린 종목만 남긴다.
- 명시적 뉴스 데이터가 없으므로 `premarket dollar volume``same-day catalyst proxy`로 쓴다.
4. 검증은 `2026 Q1`을 1차 test window로 본다.
- 이 기간은 최근 구조를 반영하면서도 30일보다 충분히 길다.
## 2. 현재 공식 전략
공식 전략 파일:
- [orb_gainers.yaml](/Users/yirugi/mycloud/personal/workspace/fithia2/configs/intraday/strategies/orb_gainers.yaml)
현재 공식 파라미터의 핵심:
- `engine_family: gainers_leader`
- `entry_direction: long_only`
- `orb_minutes: 5`
- `sim_bar_minutes: 5`
- `order_timeout_minutes: 45`
- `min_price: 10`
- `min_avg_dollar_volume: 25,000,000`
- `min_atr_14: 0.50`
- `min_rvol: 1.2`
- `min_abs_gap_pct: 0.02`
- `min_premarket_dollar_vol: 1,500,000`
- `max_gap_pct: null`
- `max_candidates: 12`
- `max_candidates_per_sector: 2`
- `min_candidates_to_trade: 1`
- `weight_rvol/gap/dollar_vol/premarket = 0.40 / 0.20 / 0.05 / 0.35`
- `atr_stop_multiplier: 0.5`
- `breakeven_at_r: 1.0`
- `trailing_at_r: 3.0`
- `trailing_stop_atr_multiplier: 0.3`
- `compound_returns: false`
왜 이렇게 바뀌었는가:
- 예전 `compression_breakout`은 원래 의도와 맞지 않았다.
- `0.10 ATR` stop은 너무 타이트해서 거의 바로 stop-out 됐다.
- `premarket dollar volume`을 강하게 쓰는 것이 Q1에서 가장 잘 작동했다.
## 3. Source Of Truth
ORB 개발에서 source of truth는 아래 순서다.
1. 공식 전략 config
- [orb_gainers.yaml](/Users/yirugi/mycloud/personal/workspace/fithia2/configs/intraday/strategies/orb_gainers.yaml)
2. 공식 단일 백테스트 실행기
- [apps/intraday_bt/run.py](/Users/yirugi/mycloud/personal/workspace/fithia2/apps/intraday_bt/run.py)
3. 연구 helper / lab
- [apps/intraday_bt/orb_research.py](/Users/yirugi/mycloud/personal/workspace/fithia2/apps/intraday_bt/orb_research.py)
- [apps/intraday_bt/lab.py](/Users/yirugi/mycloud/personal/workspace/fithia2/apps/intraday_bt/lab.py)
4. 실험 결과물
- `runs/intraday_orb/...`
중요:
- helper/lab은 빠른 연구용이다.
- 최종 성과와 전략 등록 판단은 반드시 `apps.intraday_bt.run`으로 다시 확인한다.
## 4. 현재 검증 기준
### Primary Test
현재 primary test window는:
- `2026-01-02 ~ 2026-03-31`
이 기간은 Q1 구간이며, 현재 ORB gainers 전략 개선은 이 구간을 기준으로 한다.
### Secondary Sanity Check
추가 sanity check는:
- `--days 30` 최근 30거래일
이유:
- Q1만 좋고 최근 30일에서 activity가 0이면 전략이 죽은 상태일 수 있다.
- 반대로 최근 30일만 좋고 Q1 전체가 약하면 과적합 가능성이 높다.
## 5. 현재 공식 성과
공식 `run.py` 기준 최신 결과:
### Q1 공식 검증
- 결과 파일:
[intraday_20260415_204341_9d8e4fee.json](/Users/yirugi/mycloud/personal/workspace/fithia2/runs/intraday_orb/intraday_20260415_204341_9d8e4fee.json)
- 기간:
`2026-01-02 ~ 2026-03-31`
- 결과:
- `+6.96%`
- `407 trades`
- `Sharpe 2.05`
- `Max drawdown -3.92%`
### 최근 30일 공식 검증
- 결과 파일:
[intraday_20260415_204456_60bdfe03.json](/Users/yirugi/mycloud/personal/workspace/fithia2/runs/intraday_orb/intraday_20260415_204456_60bdfe03.json)
- 기간:
`2026-03-04 ~ 2026-04-15`
- 결과:
- `+4.05%`
- `211 trades`
- `Sharpe 2.15`
- `30/30 days with trades`
## 6. 개발 루프
현재 ORB gainers 개발은 아래 순서로 한다.
### Step 1. 아이디어를 전략 언어로 번역
질문:
- “당일 리더를 찾는가?”
- “뉴스/촉매 proxy가 들어갔는가?”
- “큰 갭을 오히려 막고 있지 않은가?”
- “activity를 죽이는 규칙이 없는가?”
현재 유효했던 아이디어:
- `premarket dollar volume``same-day catalyst proxy`로 사용
- `gap + rvol + premarket attention` 랭킹
- `0.5 ATR stop + 3R ATR trail`
### Step 2. Helper로 좁은 실험
빠른 실험은 `orb_research.py`의 research snapshot / tape cache를 재사용한다.
핵심은:
- full raw intraday를 매번 다시 읽지 않는다.
- 같은 Q1 구간을 여러 파라미터로 빠르게 비교한다.
최근 Q1 비교 결과 파일:
- [focus2](/Users/yirugi/mycloud/personal/workspace/fithia2/runs/intraday_orb/lab/quick_real_202404_202603_gainers_q1_focus2.json)
- [focus3](/Users/yirugi/mycloud/personal/workspace/fithia2/runs/intraday_orb/lab/quick_real_202404_202603_gainers_q1_focus3.json)
- [focus4](/Users/yirugi/mycloud/personal/workspace/fithia2/runs/intraday_orb/lab/quick_real_202404_202603_gainers_q1_focus4.json)
이 단계의 목적은:
- 최고의 parameter cluster를 빠르게 찾는 것
- official result를 확정하는 것이 아님
### Step 3. Official `run.py` 재검증
helper에서 좋아 보여도 반드시 `run.py`로 다시 확인한다.
예시:
```bash
.venv/bin/python3 -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers.yaml \
--start 2026-01-02 \
--end 2026-03-31
```
최근 30일 sanity:
```bash
.venv/bin/python3 -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers.yaml \
--days 30
```
### Step 4. 결과가 맞으면 config 업데이트
official result까지 확인된 뒤에만 전략 파일을 바꾼다.
## 7. 꼭 체크해야 할 함정
### 7.1 Helper와 `run.py` 결과가 다를 수 있다
실제로 한 번 발생했다.
원인:
- `run.py` 경로가 `ticker_sectors`를 ORB simulator에 넘기지 않아서
`max_candidates_per_sector`가 공식 백테스트에서 무시되고 있었다.
- helper는 sector cap을 적용하고, official run은 적용하지 않아
결과가 크게 어긋났다.
수정 위치:
- [apps/intraday_bt/run.py](/Users/yirugi/mycloud/personal/workspace/fithia2/apps/intraday_bt/run.py)
원칙:
- helper에서 좋은 결과가 나오면 official run으로 trade count부터 먼저 맞춰본다.
### 7.2 `min_candidates_to_trade`는 activity를 쉽게 0으로 만든다
예전 compression 전략이 최근 30일 `0 trades`였던 직접 원인 중 하나다.
원칙:
- gainers 계열에서는 기본적으로 `min_candidates_to_trade = 1`부터 시작한다.
### 7.3 `max_gap_pct`는 gainers 전략과 상충할 수 있다
top gainers 전략은 본질적으로 큰 움직임을 잡는 전략이다.
원칙:
- gainers 계열에서는 `max_gap_pct`를 보통 `null`로 두고,
- 대신 `min_abs_gap_pct``min_premarket_dollar_vol`로 품질을 걸러낸다.
### 7.4 `0.10 ATR` stop은 지나치게 타이트할 수 있다
실제 Q1 비교에서:
- `0.10 ATR`은 매우 나빴다.
- `0.50 ATR` 쪽이 명확히 우세했다.
원칙:
- gainers 계열은 `0.10 ATR`을 baseline으로 두지 않는다.
## 8. 어떤 축을 우선 튜닝할 것인가
가장 효율적인 튜닝 순서:
1. `min_premarket_dollar_vol`
2. ranking weights
- `weight_rvol`
- `weight_gap`
- `weight_premarket_dollar_vol`
3. `atr_stop_multiplier`
4. `trailing_at_r`
5. `trailing_stop_atr_multiplier`
6. `max_candidates`
7. `max_candidates_per_sector`
현재까지는:
- `premarket dollar volume`이 가장 큰 설명력을 보였다.
## 9. Cache / Snapshot 구조
ORB 개발 속도를 위해 아래 캐시를 사용한다.
- raw daily cache:
[data/cache/daily](/Users/yirugi/mycloud/personal/workspace/fithia2/data/cache/daily)
- raw intraday cache:
[data/cache/intraday](/Users/yirugi/mycloud/personal/workspace/fithia2/data/cache/intraday)
- research snapshot:
[data/cache/orb_research](/Users/yirugi/mycloud/personal/workspace/fithia2/data/cache/orb_research)
- period metrics cache:
[data/cache/orb_eval](/Users/yirugi/mycloud/personal/workspace/fithia2/data/cache/orb_eval)
- prepared tape cache:
[data/cache/orb_tape](/Users/yirugi/mycloud/personal/workspace/fithia2/data/cache/orb_tape)
운영 원칙:
- helper 실험은 snapshot/tape를 적극 활용한다.
- official truth는 여전히 `run.py` 결과다.
## 10. 권장 검증 명령
### 코드/회귀 검증
```bash
python -m py_compile \
apps/intraday_bt/run.py \
apps/intraday_bt/lab.py \
libs/intraday/orb_simulator.py
pytest -q \
tests/unit/intraday/test_run_helpers.py \
tests/unit/intraday/test_orb_lab.py \
tests/unit/intraday/test_orb_simulator.py
```
### Q1 공식 백테스트
```bash
.venv/bin/python3 -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers.yaml \
--start 2026-01-02 \
--end 2026-03-31
```
### 최근 30일 sanity
```bash
.venv/bin/python3 -m apps.intraday_bt.run \
--config configs/intraday/strategies/orb_gainers.yaml \
--days 30
```
### Quick lab
```bash
python -u -m apps.intraday_bt.lab \
--config configs/intraday/strategies/orb_gainers.yaml \
--quick \
--beam-width 2 \
--output-dir runs/intraday_orb/lab/quick_orb_gainers
```
주의:
- lab 결과가 좋으면 반드시 `run.py`로 다시 확인한다.
## 11. 다음 개발자가 해야 할 일
다음 사람이 이어받으면 아래 순서로 하면 된다.
1. 공식 config를 읽는다.
- [orb_gainers.yaml](/Users/yirugi/mycloud/personal/workspace/fithia2/configs/intraday/strategies/orb_gainers.yaml)
2. Q1 official run을 먼저 돌린다.
3. 최근 30일 sanity를 확인한다.
4. 개선 아이디어는 먼저 helper로 좁게 비교한다.
5. helper winner를 official `run.py`로 검증한다.
6. trade count / return / sharpe가 helper와 공식 run에서 비슷한지 확인한다.
7. 일치하면 config를 업데이트한다.
## 12. 현재 상태 요약
현재 결론은 이렇다.
- `compression`보다 `gainers_leader`가 전략 의도에 맞다.
- `premarket dollar volume`은 매우 중요한 품질 필터다.
- `0.5 ATR stop + 3R ATR trail`이 지금까지는 가장 실전적이다.
- helper와 official run 차이는 반드시 의심하고 검증해야 한다.
- 현재 공식 `ORB Gainers`는:
- Q1 `+6.96%`
- 최근 30일 `+4.05%`
- activity도 충분히 나온다.