[STK3-03] 백테스트

작업 내용 (설계 의도)

변경 사항

  • backtest.py run_backtest() — 워크포워드(warmup 20, 시점 t까지 종가만 → 룩어헤드 배제).
  • overall/signal 승률·평균수익, edge = signal_avg_return − overall_avg_return.
  • 뉴스 감성 미포함(과거 시계열 복원 불가) — note 명시.

의존

  • 선행: Phase 2 시그널 완료
  • 후행: STK3-05

다이어그램

처리 흐름

sequenceDiagram
    participant B as backtest.py
    Note over B: warmup=20 스킵
    loop t in [20, len-horizon-1]
        B->>B: score(prices[0:t+1])
        Note over B: 룩어헤드 배제 (t 이후 미참조)
        B->>B: ret = (prices[t+horizon] - prices[t]) / prices[t]
    end
    B->>B: overall_win_rate, signal_win_rate 계산
    B->>B: edge = signal_avg_return - overall_avg_return
    B-->>B: BacktestResult(samples, win_rate, avg_return, edge, note)

클래스 의존

flowchart LR
    subgraph Application["Application"]
        main["main.py\n/backtest/{symbol}"]
    end
    subgraph Domain["ML 도메인"]
        bt["backtest.py\nrun_backtest()"]
        signal["signal.py\nscore()"]
    end
    main --> bt
    bt --> signal

테스트 케이스

  • 시점 t의 점수가 prices[0:t+1]만으로 계산되어 미래 데이터를 참조하지 않는다.
  • warmup(20) 이전 구간은 건너뛰고 samples 카운트에 포함되지 않는다.
  • signal_avg_return이 overall_avg_return보다 크면 edge가 양수로 산출된다.
  • 가격 데이터가 warmup+horizon보다 짧으면 samples=0이 반환된다.
  • 결과 note에 “뉴스 감성 미포함” 문구가 포함된다.