# 백테스트로 전략 평가하기 ## 백테스팅 시스템 컴포넌트 개요 pyqqq.backtest 모듈은 다음과 같은 주요 컴포넌트들로 구성되어 있습니다: ### 핵심 컴포넌트 - **Environment**: 트레이딩 시스템의 실행 환경을 정의 - `BacktestEnvironment`: 백테스팅을 위한 가상 환경 - `KISDomesticEnvironment`: 국내주식 실거래 환경 - `KISOverseasEnvironment`: 해외주식 실거래 환경 - **Broker**: 주문 처리와 시장 데이터 조회를 담당 - `MockBroker`: 백테스팅용 가상 브로커 - `TradingBroker`: 실제 거래 실행 브로커 - **PositionProvider**: 포지션 정보 관리 - `ManualPositionProvider`: 수동 포지션 관리 - `BackPositionProvider`: DB 기반 포지션 관리 - `KISPositionProvider`: 실시간 포지션 조회 - **WallClock**: 시스템의 시간 관리 - 실시간 모드: 실제 시간 기준 동작 - 백테스트 모드: 가상 시간 기준 동작 - **Strategy**: 실제 트레이딩 로직 구현 - `BaseStrategy`: 모든 전략의 기본 클래스 ### 컴포넌트 간 관계 ``` Environment ├── WallClock (시간 관리) └── Broker (주문 처리) └── PositionProvider (포지션 관리) Strategy ├── Environment 참조 └── 실제 매매 로직 구현 ``` ## Step 1: 전략 구현 및 백테스팅 ### 1.1 전략 코드 작성 5분 이동평선을 돌파하면 매수하고, %3 수익이 나면 매도하는 간단한 전략을 구현합니다. ```python # strategy.py from pyqqq.backtest.environment import BacktestEnvironment from pyqqq.backtest.strategy import BaseStrategy from pyqqq.datatypes import OrderSide, OrderType from pyqqq.utils.market_schedule import is_trading_time import asyncio import datetime as dtm class SimpleBreakoutStrategy(BaseStrategy): """5분봉 돌파 매매 전략""" def __init__(self, environment, symbol="168360"): super().__init__(environment) self.symbol = symbol async def run(self): while self.clock.is_alive(): try: if is_trading_time(self.clock.now()): self.on_trade() await self.clock.sleep(60) except Exception as e: self.logger.exception(f"Error in strategy: {e}") await self.clock.sleep(60) def on_trade(self): positions = self.broker.get_positions() current_price = self.broker.get_price(self.symbol) # 현재 포지션 확인 position = next((p for p in positions if p.asset_code == self.symbol), None) df = self.broker.get_minute_price(self.symbol) if len(df) < 5: return df["ma5"] = df["close"].rolling(5).mean() ohlcv = df.iloc[-1] ma5 = df["ma5"].iloc[-1] open = ohlcv["open"] close = ohlcv["close"] if not position and close > ma5 and ma5 > open: # 매수 신호 quantity = int(10_000_000 / current_price) # 1천만원어치 self.broker.create_order(self.symbol, OrderSide.BUY, quantity, OrderType.MARKET) self.logger.info(f"매수 주문: {quantity}주 @ {current_price}") elif position and position.current_pnl > 3: # 매도 신호 for position in positions: if position.asset_code == self.symbol: self.broker.create_order(self.symbol, OrderSide.SELL, position.quantity, OrderType.MARKET) self.logger.info(f"매도 주문: {position.quantity}주 @ {current_price}") ``` ### 1.2 백테스팅 실행 ```python # backtest.py import asyncio import datetime as dtm from pyqqq.backtest.environment import BacktestEnvironment from strategy import SimpleBreakoutStrategy async def run_backtest(): # 백테스팅 환경 설정 env = BacktestEnvironment( start_time=dtm.datetime(2024, 10, 2, 9, 0), end_time=dtm.datetime(2024, 10, 22, 15, 30), time_unit="minutes", ) # 초기 자본금 설정 env.get_broker().set_initial_cash(100_000_000) # 1억원 # 전략 실행 strategy = SimpleBreakoutStrategy(env) await strategy.run() # 결과 분석 broker = env.get_broker() # 1. 전체 거래 이력 분석 report = broker.show_trading_history_report(make_file=True) print(f"- 총 거래횟수: {report['count']}") print(f"- 총 수익률: {report['total_pnl']:.2f}%") print(f"- 평균 수익률: {report['avg_pnl']:.2f}%") print(f"- ROI: {report['roi']:.2f}") # 2. 최종 포지션 확인 broker.show_positions() if __name__ == "__main__": asyncio.run(run_backtest()) ``` ### 1.3 백테스트 결과 분석 백테스트 결과를 바탕으로 다음 사항들을 검토합니다: 1. 수익성 - 총 수익률과 ROI 확인 - 개별 거래의 평균 수익률 검토 - 최대 손실폭과 수익폭 확인 2. 리스크 관리 - 최대 손실 시점 분석 - 연속 손실 구간 확인 - 포지션 크기의 적절성 검토 3. 전략 개선점 도출 - 매매 타이밍 최적화 - 손절/익절 전략 추가 검토 - 포지션 사이징 조정 ## Step 2: 실전 거래 준비 및 실행 ### 2.1 계좌 설정 1. 한국투자증권 계좌 및 API 키 발급 2. 환경변수 설정: ```bash # 실전 계좌 export KIS_APP_KEY="your-app-key" export KIS_APP_SECRET="your-app-secret" export KIS_CANO="your-account-number" export KIS_ACNT_PRDT_CD="your-product-code" # 모의 계좌 (선택) export PAPER_KIS_APP_KEY="your-paper-app-key" export PAPER_KIS_APP_SECRET="your-paper-app-secret" export PAPER_KIS_CANO="your-paper-account-number" export PAPER_KIS_ACNT_PRDT_CD="your-paper-product-code" ``` ### 2.2 모의투자 테스트 백테스트에서 검증된 전략을 모의투자로 먼저 테스트합니다. ```python # paper_trading.py import asyncio from pyqqq.backtest.environment import KISDomesticEnvironment from strategy import SimpleBreakoutStrategy async def run_paper_trading(): # 모의투자 환경 설정 env = KISDomesticEnvironment(paper_trading=True) # 전략 실행 strategy = SimpleBreakoutStrategy(env) await strategy.run() if __name__ == "__main__": asyncio.run(run_paper_trading()) ``` ### 2.3 실전 거래 실행 모의투자에서 충분히 검증된 후 실전 거래를 시작합니다. ```python # live_trading.py import asyncio from pyqqq.backtest.environment import KISDomesticEnvironment from strategy import SimpleBreakoutStrategy async def run(): # 실전 환경 설정 env = KISDomesticEnvironment(paper_trading=False) # 전략 실행 strategy = SimpleBreakoutStrategy(env) await strategy.run() if __name__ == "__main__": asyncio.run(run()) ```