# Backtest Module Plan
## 핵심 구분
| 시간 | 실제 시계 | 내가 제어 |
| 데이터 | 브로커 실시간 | 히스토리 CSV/DB |
| Fill | 브로커가 결정 | 내가 시뮬레이션 |
| API | `Alpaca::paper()` | `SimulatedExchange` |
| 속도 | 실시간 | 수년치 수초만에 |
Paper trading은 이미 `Alpaca::paper()`로 존재. 백테스팅 프레임워크 밖의 영역.
## 모듈 구조
```
src/
backtest/
mod.rs # Clock + Engine (이벤트 루프, 시간 제어)
simulated.rs # SimulatedExchange — TradingApi impl (로컬 fill 로직)
feed.rs # HistoricalSource — Source<Q,T> impl (과거 데이터 피드)
...기존 그대로
```
`lib.rs`에 `pub mod backtest;` 추가.
## 핵심 컴포넌트
### 1. Clock — 시간 제어
시뮬레이션 시간을 단계별로 전진시키는 이터레이터.
```rust
pub struct Clock {
current: DateTime,
end: DateTime,
interval: Interval,
}
impl Clock {
pub fn new(start: DateTime, end: DateTime, interval: Interval) -> Self;
pub fn advance(&mut self) -> Option<DateTime>;
}
```
### 2. HistoricalSource — 과거 데이터 피드
`Source<Q, T>` trait 구현. 시점별 데이터를 리턴.
```rust
pub struct HistoricalSource {
// 시점 → 데이터 매핑 (CSV/JSON 로드)
}
impl Source<OptionChainQuery, Vec<OptionChainSnapshot>> for HistoricalSource {
async fn fetch(&self, query: &OptionChainQuery) -> Result<Vec<OptionChainSnapshot>, Box<dyn Error>>;
}
```
데이터 로딩: CSV/JSON 파일에서 히스토리 로드. 시점 기반 조회.
### 3. SimulatedExchange — 로컬 주문 매칭
`TradingApi` trait 구현. 가상 잔고, 포지션, 주문 관리.
```rust
pub struct SimulatedExchange {
balance: f64,
positions: HashMap<String, Position>,
orders: Vec<Order>,
fills: Vec<Fill>,
}
impl TradingApi for SimulatedExchange {
async fn submit_order(&self, order: &OrderRequest) -> Result<Order, Box<dyn Error>>;
async fn get_account(&self) -> Result<TradingAccount, Box<dyn Error>>;
async fn cancel_order(&self, order_id: &str) -> Result<(), Box<dyn Error>>;
// ...
}
```
Fill 로직: 시장가 즉시 fill, 지정가 가격 도달 시 fill, 슬리피지 설정 가능.
### 4. Engine — 이벤트 루프
Clock + Feed + Exchange를 묶어서 전략을 실행하는 하네스.
```rust
let clock = Clock::new(start, end, Interval::Day);
let feed = HistoricalSource::from_csv("nvda_2024.csv")?;
let exchange = SimulatedExchange::new(initial_balance);
while let Some(tick) = clock.advance() {
let data = feed.at(tick);
strategy.on_tick(&exchange, &data);
exchange.process(tick);
}
let report = exchange.summary(); // PnL, 승률, drawdown
```
## 전략 인터페이스
전략은 `TradingApi` + `Source<Q,T>` trait bound만 봄. live/paper/backtest 구분 불필요.
```rust
// 동일한 전략 코드
async fn run_strategy(api: &impl TradingApi, data: &impl Source<OptionChainQuery, Vec<OptionChainSnapshot>>) {
let chain = data.fetch(&OptionChainQuery { underlying_symbol: "NVDA".into() }).await?;
// 분석 → 주문
api.submit_order(&request).await?;
}
```
## 구현 순서
1. `Clock` — 시간 이터레이터 (가장 단순)
2. `HistoricalSource` — CSV 파서 + Source impl
3. `SimulatedExchange` — TradingApi impl + fill 로직
4. `Engine` — 이벤트 루프 하네스
5. 리포트 — PnL, drawdown, 승률 등 통계 출력
6. 전략 크레이트에서 backtest 실행 예제
## 의존성 후보
| `chrono` | 날짜/시간 처리 |
| `csv` | CSV 히스토리 데이터 로딩 |
기존 `serde`, `serde_json`은 그대로 활용.