7.2 KiB
7.2 KiB
Strategy Module
매매 전략을 관리하고 실행하는 핵심 모듈
모듈 구조
strategy/
├── __init__.py # 모듈 내보내기
├── base_strategy.py # BaseStrategy 추상 클래스
├── signal.py # Signal 데이터 클래스
├── strategy_manager.py # 전략 관리자 (등록/실행)
├── indicators.py # 보조지표 (RSI, BB, MACD 등)
├── scanner.py # 종목 스캔
├── strategies/ # 구체적 전략 구현
│ ├── __init__.py
│ └── day_trading.py # 데이트레이딩 전략
└── README.md
사용 방법
1. 전략 구현
BaseStrategy를 상속받아 analyze() 메서드 구현:
from app.strategy import BaseStrategy, Signal, SignalType
from datetime import datetime
import pytz
class MyStrategy(BaseStrategy):
def __init__(self):
super().__init__(name="MyStrategy", config={"param1": 10})
async def analyze(self, stock_code, market_data, portfolio_data=None):
current_price = market_data.get("current_price")
# 매수 조건 체크
if self._should_buy(market_data):
return Signal(
stock_code=stock_code,
signal_type=SignalType.BUY,
strategy_name=self.name,
timestamp=datetime.now(pytz.timezone("Asia/Seoul")),
price=current_price,
confidence=0.8,
reason="매수 조건 충족"
)
return None
def _should_buy(self, market_data):
# 실제 로직 구현
return True
2. 전략 등록 및 실행
from app.strategy import strategy_manager
from app.strategy.strategies import DayTradingStrategy
# 전략 인스턴스 생성
day_trading = DayTradingStrategy(
name="DayTrading_ORB",
config={
"max_positions": 3,
"stop_loss_pct": 0.025
}
)
# 전략 등록 (priority 낮을수록 먼저 실행)
strategy_manager.register_strategy(day_trading, priority=10)
# 단일 전략 실행
signal = await strategy_manager.run_strategy(
"DayTrading_ORB",
stock_code="005930",
market_data={
"current_price": 75000,
"minute_chart": [...],
}
)
if signal:
print(f"신호 발생: {signal}")
# 모든 전략 동시 실행
signals = await strategy_manager.run_all_strategies(
stock_code="005930",
market_data={...},
parallel=True # 병렬 실행
)
# 신호 충돌 해결
final_signal = strategy_manager.resolve_conflicts(
signals,
method="highest_confidence" # or "priority", "majority_vote"
)
3. Signal 데이터 구조
from app.strategy import Signal, SignalType
from datetime import datetime
import pytz
signal = Signal(
stock_code="005930",
signal_type=SignalType.BUY,
strategy_name="MyStrategy",
timestamp=datetime.now(pytz.timezone("Asia/Seoul")),
# 주문 정보
quantity=10,
price=75000, # None = 시장가
confidence=0.85,
# 손익 관리
stop_loss_price=73000,
take_profit_price=78000,
trailing_stop_pct=0.02, # 2% 트레일링
# 메타데이터
reason="RSI 과매도 반등",
metadata={"rsi": 25, "bb_lower": 74000}
)
# JSON 변환
data = signal.to_dict()
4. 보조지표 사용
from app.strategy.indicators import rsi, bollinger_bands, sma, macd, atr
# 종가 리스트
closes = [75000, 75500, 76000, 74500, 75000, ...]
# RSI
rsi_value = rsi(closes, period=14)
if rsi_value and rsi_value < 30:
print("과매도 구간")
# 볼린저 밴드
bb = bollinger_bands(closes, period=20, std_mult=2.0)
if bb:
upper, middle, lower = bb
if closes[-1] < lower:
print("하단 돌파")
# SMA
sma_20 = sma(closes, 20)
sma_60 = sma(closes, 60)
if sma_20 and sma_60 and sma_20 > sma_60:
print("골든 크로스 발생")
# ATR
highs = [76000, 76500, ...]
lows = [74500, 75000, ...]
atr_value = atr(highs, lows, closes, period=14)
5. 종목 스캔
from app.strategy.scanner import Scanner, filter_price_range, filter_volume_min
# 스캀너 생성
scanner = Scanner()
# 필터 추가
scanner.add_filter(filter_price_range(10000, 100000)) # 1만~10만원
scanner.add_filter(filter_volume_min(100000)) # 최소 거래량 10만주
# 커스텀 필터
def custom_filter(data):
# 등락률 5% 이상
return data.get("change_rate", 0) >= 5.0
scanner.add_filter(custom_filter)
# 스캔 실행
kospi_codes = ["005930", "000660", "035420", ...] # KOSPI 종목 리스트
matched = await scanner.scan(kospi_codes, max_concurrent=10)
for stock in matched:
print(f"{stock['stock_name']} ({stock['stock_code']}): "
f"{stock['current_price']}원, +{stock['change_rate']}%")
주요 기능
BaseStrategy
- ✅ 전략 추상화 (템플릿 메서드 패턴)
- ✅
analyze()구현 강제 - ✅
on_signal_executed()콜백 - ✅
on_error()에러 핸들링 - ✅ 설정 관리 (config)
- ✅ 활성화/비활성화
StrategyManager
- ✅ 전략 등록/삭제
- ✅ 우선순위 관리
- ✅ 단일/복수 전략 실행
- ✅ 병렬 실행 지원
- ✅ 신호 충돌 해결
highest_confidence: 가장 높은 신뢰도priority: 전략 우선순위majority_vote: 다수결
- ✅ 신호 이력 관리
- ✅ 통계 정보
Signal
- ✅ 표준화된 신호 데이터 구조
- ✅ 6가지 신호 타입 (BUY/SELL/HOLD/CLOSE/STOP_LOSS/TAKE_PROFIT)
- ✅ 손익 관리 필드
- ✅ 신뢰도 평가
- ✅ JSON 직렬화
Indicators
- ✅ SMA (Simple Moving Average)
- ✅ EMA (Exponential Moving Average)
- ✅ RSI (Relative Strength Index)
- ✅ Bollinger Bands
- ✅ MACD
- ✅ ATR (Average True Range)
- ✅ VWAP (Volume Weighted Average Price)
Scanner
- ✅ 조건 기반 종목 필터링
- ✅ 동시 다중 종목 스캔
- ✅ 사전 정의 필터
- 가격 범위
- 거래량 최소값
- 등락률 범위
- 시가총액 최소값
- ✅ 커스텀 필터 추가 가능
기존 코드 마이그레이션
기존 services/ 폴더의 전략 파일들을 새 구조로 변환:
| 기존 파일 | 새 위치 |
|---|---|
day_trading_strategy.py |
strategy/strategies/day_trading.py |
swing_trading_strategy.py |
strategy/strategies/swing_trading.py |
momentum_strategy.py |
strategy/strategies/momentum.py |
변환 패턴:
# 기존
def check_signal(stock_code, market_data):
if condition:
return DayTradeSignal(...)
return None
# 새 구조
class DayTradingStrategy(BaseStrategy):
async def analyze(self, stock_code, market_data, portfolio_data=None):
if condition:
return Signal(...)
return None
Phase 2 완료 체크리스트
strategy/base_strategy.py생성strategy/signal.py생성strategy/strategy_manager.py생성strategy/indicators.py생성strategy/scanner.py생성strategy/strategies/day_trading.py예시 생성- README 문서 작성
다음 단계 (Phase 3)
- WebSocket 모듈 분리 (
realtime/) - 실시간 시세 수신 구조 개선
- 장 스케줄 관리
작성일: 2026-03-06
작성자: 서영우