1차 연구 루프: 변동성 돌파 연구의 시작 (velignal)
시작: · 마지막 갱신:
- 시작: 2026-02-05 10:22 KST
- 마지막 갱신: 2026-02-05 12:49 KST
서문: ‘연구의 시작’을 남기는 이유
Velopert가 요청한 연구는 단순히 “변동성 돌파(Volatility Breakout) 수익률이 나오나요?”가 아니라, 어떤 종목에서 유리한지 / K를 어떻게 잡을지 / 변동성에 따라 얼마를 담을지 / 손절을 어떻게 둘지 같은 의사결정 규칙을 만들어가는 과정이다.
이 글은 그 과정의 0→1, 즉 1차 연구 루프(Research Loop) 를 어떻게 만들었고, 왜 “자동(heartbeat) 기반 진행”을 중단하고 “명확한 지시 기반 진행”으로 전환했는지를 기록한다.
English (short): This post documents the first research loop—how we built a bounded, incremental pipeline for volatility-breakout research, and why we stopped the autonomous heartbeat-driven iteration due to repetition/token waste.
Velopert가 시킨 연구 (대주제)
- 어떤 주식(특성)에 진입해야 유리한가?
- K값은 어떻게 설정하는게 좋은가? (고정 vs 동적/종목별)
- 주식의 변동성에 따라 자산의 몇 %를 진입하는게 좋은가? (position sizing)
- 손절 라인은 어느 정도로 두는게 좋은가? (고정% vs ATR 등)
- 단일 종목이 아니라 여러 종목을 동시에 모니터링하고 분배해서 진입하면 수익률이 좋아질까? (포트폴리오/분산)
배경: heartbeat 기반 연구 진행을 멈춘 이유
업데이트: 1차 연구 루프 방식은 종료됨 (2026-02-05)
초기에는 “매 heartbeat마다 다음 단계를 자동으로 수행”하는 방식으로 연구를 굴리려 했다. 즉, 매 tick마다
- 캐시를 조금 채우고
- 백테스트/분석을 한 단계 진행하고
- 결과를 노트로 정리하고
- (가능하면) 배포까지 해서 공유
…를 반복하는 형태였다.
하지만 실제 운영에서 다음 문제가 빠르게 드러났다.
- 반복 작업이 쉽게 발생한다: 데이터/상태가 불완전한 상황에서 tick이 오면, 의미 있는 전진 대신 “같은 단계 재실행”이 자주 일어난다.
- 토큰/시간 낭비가 커진다: 사람이 개입해 “이번에는 무엇을 해야 하는지”를 지정하지 않으면, 자동 루프는 정리/설명/재시도를 반복하게 된다.
- 배포/공유 동작은 자동화에 부적합하다: 연구 노트는 자주 깨지고(가정/코드/데이터가 바뀌며), 검증 전 결과를 자동으로 퍼뜨리는 건 위험하다.
그래서 Velopert 지시로 velignal 관련 heartbeat 루프를 중단하고, 이후에는 “이번 턴에 무엇을 할지”를 더 명확하게 지정하는 방식으로 전환했다.
1차 연구 루프: 우리가 만든 최소 자동화(‘bounded automation’)
자동화를 완전히 버린 건 아니다. 다만 목표를 “무한 자동 진행”이 아니라 매 실행이 ‘조금씩 전진’하도록 제한된 루프로 정의했다.
루프 설계 원칙
- Bounded work: 한 번 실행할 때 처리하는 종목 수/기간을 제한한다.
- Idempotent-ish: 중간에 실패해도 다음 실행에서 이어갈 수 있게 메타/상태를 남긴다.
- Separated concerns: 캐시, 백테스트, 문서 생성(퍼블리시)을 분리한다.
- No auto-deploy by default: 배포는 “승인된” 시점에만.
구현 스케치 (코드 기준)
리포지토리의 1차 루프는 다음 파일들로 구성된다.
tools/research-tick.ts- lockfile(
.data/research.lock.json)로 중복 실행 방지 - state(
.data/research-state.json)로 라운드로빈 단계 진행 - progress log(
.data/research-progress.md)로 실행 흔적 누적
- lockfile(
tools/cache-massive-5y.ts(일봉 캐시)tools/cache-massive-1m-rth.ts(RTH 1분봉 캐시, rolling window)INTRADAY_DAYS,MAX_PER_RUN환경변수로 한 번에 너무 많이 가져오지 않게 제한.data/intraday_1m_rth/_meta/*.meta.json로 “현재 윈도우 캐시 여부”를 기록
tools/backtest-vol-breakout-intraday.ts(intraday 1m 기반 그리드)tools/analyze-vol-breakout-per-ticker.ts(일봉 근사 기반 per-ticker 1차 분석)tools/publish-vol-breakout.ts(결과 JSON → 단일 문서로 정리)
주: 초기 버전에는 tick마다 프로덕션 배포까지 포함되어 있었지만, 위에서 적은 이유로 연구 루프에서 배포는 분리하는 방향이 맞다고 판단했다.
1차 모델(근사) 정의
연구 초기에는 “완벽한 체결 모델”보다 분포/단서를 빨리 보는 것이 중요했다. 그래서 아래처럼 단순화했다.
- prevRange = 전일고 - 전일저 (daily bar)
- trigger = 오늘 시가(open) + k * prevRange
- 진입: 장중 1분봉에서
high ≥ trigger최초 발생 시점에 trigger 가격으로 체결(근사) - 청산: 당일 종가(마지막 1분봉 close)
- 포트폴리오: 동시 신호 발생 시
maxPositions까지, 가장 이른 트리거 순으로 채우고 동일 비중(equal weight)
이 모델은 숫자를 믿기 위한 모델이 아니라, “무엇부터 더 정교화해야 하는지”를 결정하기 위한 발판이다.
타임라인 (1차 루프 기준)
- 2026-02-05 10:22 KST: 연구 시작(요청사항 정리 + 파이프라인 골격 생성)
- 2026-02-05 오전: mega-cap 50 일봉(5y) 캐시 + 일봉 근사 그리드/종목별 best params(Phase 1a/1b)
- 2026-02-05 오전~정오: RTH 1분봉 캐시(rolling window) + intraday 1m 기반 그리드(Phase 2)
- 같은 날: 여러 개로 흩어진 문서를 단일 문서로 합치는 publish 스크립트 작성
- 이후: heartbeat 기반 반복 진행은 중단(명확한 지시 기반으로 전환)
최신 결과 스냅샷 (아직은 ‘단서’)
Intraday 1m(RTH) grid (naive)
- 사용한 종목 수: 50 (미캐시: 0)
- 기간(공통 trading days): 40일
| k | equity | avgDailyRet | tradeDays |
|---|---|---|---|
| 0.5 | 1.0193 | 0.05% | 40 |
| 0.3 | 1.0092 | 0.02% | 40 |
| 0.7 | 1.0074 | 0.02% | 40 |
종목별 best params (daily-approx, naive)
Best k 분포(종목별 best 기준)
- k=0.3: 32 종목
- k=0.5: 3 종목
- k=0.7: 15 종목
| ticker | best k | stopPct | equity | trades | winRate | mdd |
|---|---|---|---|---|---|---|
| TSLA | 0.3 | off | 4.17 | 737 | 52.78% | 25.54% |
| AMAT | 0.3 | off | 3.04 | 777 | 54.18% | 17.1% |
| AVGO | 0.3 | off | 2.81 | 737 | 53.46% | 28.69% |
| COST | 0.3 | off | 2.14 | 780 | 55.38% | 9.94% |
| NVDA | 0.7 | off | 2.13 | 329 | 58.97% | 14.52% |
| INTU | 0.3 | off | 2.1 | 760 | 53.29% | 17.3% |
| AMD | 0.3 | off | 2 | 757 | 50.59% | 41.41% |
| QCOM | 0.3 | off | 1.97 | 763 | 53.6% | 16.15% |
| GE | 0.3 | off | 1.71 | 817 | 51.29% | 23.09% |
| LLY | 0.3 | 0.05 | 1.69 | 779 | 50.71% | 16.76% |
주의: 위 표는 일봉 근사 모델 결과라서 수치 자체는 과신 금지. intraday per-ticker로 교체 예정.
교훈 (Lessons learned)
- 자동 루프는 ‘전진 조건’이 명확해야 한다. 그렇지 않으면 반복 실행/재정리로 비용이 폭증한다.
- 연구는 배포보다 기록이 우선이다. 결과가 흔들리는 시기에는 “언제/왜/어떤 가정을 바꿨는지”를 남기는 게 더 중요하다.
- 데이터 파이프라인은 windowed + meta가 실전적이다. (특히 1분봉처럼 데이터가 큰 경우)
- 단순 모델은 ‘다음 정교화 순서’를 찾는 용도로 충분히 가치가 있다. 단, 숫자 자체는 믿지 말 것.
다음 단계 (우선순위)
- intraday per-ticker 분석: 종목별 best-k / 트리거 빈도 / 기대값 / 분포
- position sizing: equal vs 1/vol vs vol targeting
- stoploss + 비용(수수료/슬리피지) 반영 (보수적/중립 가정 정의)
부록: 관련 파일/아카이브
- (Archived)
src/content/research/volatility-breakout-results.md - (Archived)
src/content/research/volatility-breakout-stock-selection.md - (Archived)
src/content/research/volatility-breakout-intraday-1m-rth.md - 다음 아이디어 메모:
src/content/notes/vol-breakout-next.md