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-stopREADME.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
관찰/이슈/limitationsconfig.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 출력.
새 실험 시작 절차
- 어느 thread 인지 결정
- 그 thread 의
experiments/에서 다음 번호 부여 (3자리NNN) research/TEMPLATE_EXPERIMENT.md복사 →NNN-slug/README.md- Universe snapshot 결정 (기존 것 재사용 or 새로 생성)
- 실험 실행 →
config.json,metrics.json,charts/생성 README.md의 Results + Conclusion 채움- Thread
README.md업데이트 (Experiments 매트릭스 + Open Questions) - 중요 결정이면 Thread
decisions.md에 timestamp 항목 추가 lint.py실행해서 스키마 검증
Lint 규칙 (scripts/lint.py)
- README.md frontmatter 에 4 필수 필드 모두 있나?
-
universe_snapshot파일이 실재하나 (또는UNKNOWN)? - config.json 과 frontmatter 의 값이 일치하나?
- metrics.json 스키마 유효한가?
- ID 가 thread 내에서 unique 한가?