Experiment Schema

모든 실험 (research/threads/<thread>/experiments/<NNN>-<slug>/) 은 이 스키마를 따른다. 이 스키마가 공정 비교 + 재현 가능성 의 기반이다.

실험 폴더 구조

NNN-slug/
├── README.md         ← 질문/가설/방법/결과/결론 (필수)
├── config.json       ← 재현 가능한 파라미터 (필수)
├── metrics.json      ← 결과 지표 스냅샷 (필수)
├── charts/           ← PNG/SVG 차트 (옵션)
├── trades.csv        ← 거래 원본 (옵션)
├── notebook.ipynb    ← 분석 notebook (옵션)
└── logs/             ← 실행 로그 (옵션)

README.md frontmatter (필수 4필드)

---
thread: exit                         # universe | entry | exit | ensemble | grid-search | catalyst | regime
id: 003-chandelier-atr               # NNN-slug, thread 내 unique
universe_snapshot: V3-p3_2026-04-21  # threads/universe/snapshots/<id>.csv 참조. 없으면 "UNKNOWN"
period: 2016-01-01 / 2024-12-31      # 전체 기간
oos_split: 2024-01-01                # OOS 시작일
---

4필드가 동일 → 실험 두 개 직접 비교 가능
하나라도 다름compare.py 가 caveat 출력

추가 선택 필드:

date: 2026-04-21                     # 실험 실행일
status: done | in-progress | dropped
depends_on:
  - exit/002-exit-v2
leads_to:
  - exit/007-profit-gated-time-stop

README.md 본문 구조

# NNN-slug
 
## Question
리서치 동기. 한 문장.
 
## Hypothesis
무엇이 참이면 이 실험이 성공인가.
 
## Method
- Universe: [[threads/universe/snapshots/V3-p3_2026-04-21]]
- Entry: ...
- Exit: ...
- Portfolio: ...
- Backtest period / OOS split
 
## Results
주요 metric 표 (Sharpe, OOS Sharpe, MDD, Trades 등).
 
## Conclusion
결정적 한 문단 + 다음 액션.
 
## Notes
관찰/이슈/limitations

config.json 구조

재현 가능하려면 백테스트 엔진에 그대로 넘길 수 있는 설정이 포함돼야 한다.

{
  "thread": "exit",
  "id": "003-chandelier-atr",
  "universe_snapshot": "V3-p3_2026-04-21",
  "period": { "start": "2016-01-01", "end": "2024-12-31" },
  "oos_split": "2024-01-01",
  "portfolio": {
    "initial": 100000,
    "max_pct": 0.125,
    "max_concurrent": 8,
    "cooldown_days": 90,
    "slippage_per_side": 0.005,
    "commission_per_trade": 0.0,
    "max_volume_pct": 0.10
  },
  "entry": { "name": "bb_30" },
  "exit": {
    "name": "chandelier_atr",
    "params": { "atr_multiplier": 3, "initial_stop_loss": -0.50 }
  }
}

metrics.json 구조

{
  "sharpe": 1.99,
  "sharpe_oos": 1.56,
  "total_return": 2.92,
  "mdd": -0.169,
  "trades": 16,
  "win_rate": 0.625,
  "avg_trade_return": 0.182,
  "computed_at": "2026-04-21T14:30:00Z"
}

Universe snapshot 참조 규칙

  • universe_snapshot 필드는 research/threads/universe/snapshots/<id>.csv 파일을 참조한다.
  • 스냅샷 ID 는 <spec>_<YYYY-MM-DD> 형태 (예: V3-p3_2026-04-21)
  • 스냅샷 CSV 내부: symbol 컬럼 단일. 해시는 <id>.hash 파일에 sha256 으로.
  • 없이 돌린 과거 실험: universe_snapshot: UNKNOWN 명시. compare.py 가 caveat 출력.

새 실험 시작 절차

  1. 어느 thread 인지 결정
  2. 그 thread 의 experiments/ 에서 다음 번호 부여 (3자리 NNN)
  3. research/TEMPLATE_EXPERIMENT.md 복사 → NNN-slug/README.md
  4. Universe snapshot 결정 (기존 것 재사용 or 새로 생성)
  5. 실험 실행 → config.json, metrics.json, charts/ 생성
  6. README.md 의 Results + Conclusion 채움
  7. Thread README.md 업데이트 (Experiments 매트릭스 + Open Questions)
  8. 중요 결정이면 Thread decisions.md 에 timestamp 항목 추가
  9. lint.py 실행해서 스키마 검증

Lint 규칙 (scripts/lint.py)

  • README.md frontmatter 에 4 필수 필드 모두 있나?
  • universe_snapshot 파일이 실재하나 (또는 UNKNOWN)?
  • config.json 과 frontmatter 의 값이 일치하나?
  • metrics.json 스키마 유효한가?
  • ID 가 thread 내에서 unique 한가?