## CRITICAL 수정 (20건) - day_trading: global 선언 누락, loss_tracker 연동, ban 체크 추가 - trade_executor: BUY 체결가 order_price로 수정, remaining_pct 누적 계산 - risk_validator: get_current_price dict 파싱, MAX_POSITION_SIZE 동기화, DB 세션 누수 - risk_management/recommendations: date.today() → KST 변환 - mdd_manager: Lock 밖 executed_key 참조 수정 - correlation_filter: output → output2 키 수정 - portfolio: 해외 종목 USD/KRW 환율 적용 분리 - Sharpe Ratio 거래빈도 기반 연간화 - telegram_notifier: send_message() 공개 래퍼 추가 - position_manager: 앱 재시작 시 DB 포지션 복원 - swing exit_service: remaining_pct 조건 범위 수정 - run_backtest: original_qty 기반 remaining_pct 계산 - us_market_schedule: 2027년 미국 공휴일 추가 - Login.tsx: res.ok 검증 추가 - mean_reversion_strategy: RSI 로그 하드코딩 수정 ## HIGH 수정 (10건) - db_worker: DLQ 파일 백업 메커니즘 추가 - korea_investment_api: 만료 토큰 임의 연장 제거 - market_data: chart_cache 최대 100개 + TTL 만료 - main.py: rate_limit_store 1시간 미접근 IP 정리 - recommendations: fire-and-forget try/except 추가 - swing/scheduler: DB 세션 3개 분리 - Dashboard: wsMessages 전체 순회 - Layout: /health 엔드포인트 + 30초 폴링 - ml_ensemble: POST /train require_api_key 추가 - day_trading: record_trade_result_safe() 전환 ## 코드 정리 - 프론트엔드: isUsStock, formatTime 공통 유틸 추출 - 백엔드: dead code 제거, 중복 import 통합 - MCP: JSON 파싱 헬퍼 추출 (~60줄 감소) - 전체 ~100개 파일 한국어 주석 추가 - 테스트 13건 코드 기준 수정 (468 passed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Realtime Module
WebSocket 기반 실시간 시세 수신 및 이벤트 처리 모듈
모듈 구조
realtime/
├── __init__.py # 모듈 내보내기
├── websocket_client.py # KIS WebSocket 클라이언트
├── event_handler.py # 이벤트 핸들러 관리자
├── market_scheduler.py # 장 스케줄 관리
├── examples.py # 사용 예시
└── README.md
사용 방법
1. 기본 WebSocket 연결
from app.realtime import KISWebSocketClient, event_handler, EventType
from app.realtime.websocket_client import create_websocket_client
# 핸들러 등록
async def on_price_update(event_data):
print(f"{event_data['stock_code']}: {event_data['current_price']}원")
event_handler.register(EventType.PRICE_UPDATE, on_price_update)
# WebSocket 연결
ws_client = create_websocket_client()
await ws_client.connect()
# 종목 구독
await ws_client.subscribe_price("005930") # 삼성전자
# 메시지 수신 시작
await ws_client.listen()
2. 이벤트 핸들러
from app.realtime import event_handler, EventType
# 특정 이벤트 핸들러
async def handle_price_update(event_data):
stock_code = event_data['stock_code']
price = event_data['current_price']
print(f"{stock_code}: {price}원")
event_handler.register(EventType.PRICE_UPDATE, handle_price_update)
# 글로벌 핸들러 (모든 이벤트 수신)
async def global_handler(event_type, event_data):
print(f"[이벤트] {event_type.value}: {event_data}")
event_handler.register_global(global_handler)
# 핸들러 해제
event_handler.unregister(EventType.PRICE_UPDATE, handle_price_update)
3. 장 스케줄러
from app.realtime import market_scheduler, MarketStatus
# 현재 장 상태 확인
status = market_scheduler.get_current_status()
print(f"현재 장 상태: {status}")
# 장 개장 여부
if market_scheduler.is_market_open():
print("장 개장 중")
# 다음 장 시작까지 남은 시간
seconds = market_scheduler.get_seconds_until_market_open()
print(f"장 시작까지 {seconds}초 남음")
# 콜백 등록
async def on_market_open():
print("🔔 장 시작!")
# WebSocket 연결, 구독 등
async def on_market_close():
print("🔕 장 종료!")
# WebSocket 연결 해제
market_scheduler.register_callbacks(
on_open=on_market_open,
on_close=on_market_close
)
# 스케줄러 실행
await market_scheduler.run()
4. 실시간 전략 실행
from app.realtime import event_handler, EventType
from app.strategy import strategy_manager
from app.trading import order_manager, market_data_provider
# 핸들러: 실시간 시세 → 전략 실행 → 주문
async def on_price_update(event_data):
stock_code = event_data['stock_code']
current_price = event_data['current_price']
# 시장 데이터 구성
market_data = {
"current_price": current_price,
"minute_chart": await market_data_provider.get_minute_chart(stock_code),
}
# 전략 실행
signal = await strategy_manager.run_strategy(
"DayTrading",
stock_code=stock_code,
market_data=market_data
)
# 신호 발생 시 주문
if signal:
await order_manager.place_order(
stock_code=signal.stock_code,
order_type=signal.signal_type.value,
quantity=10,
price=signal.price
)
event_handler.register(EventType.PRICE_UPDATE, on_price_update)
5. 전체 시스템 통합
import asyncio
from app.realtime import event_handler, EventType, market_scheduler
from app.realtime.websocket_client import create_websocket_client
from app.strategy import strategy_manager
from app.strategy.strategies import DayTradingStrategy
from app.trading import order_manager, market_data_provider
# 1. 전략 등록
strategy = DayTradingStrategy()
strategy_manager.register_strategy(strategy)
# 2. 이벤트 핸들러
async def on_price_update(event_data):
# ... 전략 실행 로직
pass
event_handler.register(EventType.PRICE_UPDATE, on_price_update)
# 3. 장 스케줄러
ws_client = None
async def on_market_open():
global ws_client
ws_client = create_websocket_client()
await ws_client.connect()
# 관심 종목 구독
for code in ["005930", "000660"]:
await ws_client.subscribe_price(code)
asyncio.create_task(ws_client.listen())
async def on_market_close():
if ws_client:
await ws_client.disconnect()
market_scheduler.register_callbacks(
on_open=on_market_open,
on_close=on_market_close
)
# 4. 실행
await market_scheduler.run()
주요 기능
KISWebSocketClient
- ✅ KIS API WebSocket 연결
- ✅ 실시간 현재가/호가 수신
- ✅ 체결 데이터 수신
- ✅ 종목 구독/구독해제
- ✅ 자동 재연결
- ✅ 이벤트 기반 데이터 전달
EventHandler
- ✅ 7가지 이벤트 타입
PRICE_UPDATE: 현재가 업데이트ORDERBOOK_UPDATE: 호가 업데이트EXECUTION: 체결 발생ORDER_CONFIRM: 주문 확인ERROR: 에러CONNECTED: 연결DISCONNECTED: 연결 해제
- ✅ 타입별 핸들러 등록
- ✅ 글로벌 핸들러 (모든 이벤트)
- ✅ 비동기 핸들러 실행
- ✅ 에러 핸들링
MarketScheduler
- ✅ 4가지 장 상태
PRE_MARKET: 장 전 (08:00~09:00)MARKET_OPEN: 정규장 (09:00~15:30)AFTER_MARKET: 장 후 (15:30~18:00)MARKET_CLOSED: 휴장
- ✅ 장 시작/종료 콜백
- ✅ 남은 시간 계산
- ✅ 자동 상태 감지
이벤트 데이터 구조
PRICE_UPDATE
{
"stock_code": "005930",
"stock_name": "삼성전자",
"current_price": 75000,
"change_rate": 1.5,
"volume": 1000000,
"timestamp": datetime(...)
}
EXECUTION
{
"order_id": "0000123456",
"stock_code": "005930",
"executed_price": 75000,
"executed_quantity": 10,
"timestamp": datetime(...)
}
설치 요구사항
pip install websockets
사용 예시 파일
상세한 예시는 examples.py 참고:
- 기본 실시간 시세 수신
- 실시간 전략 실행
- 장 스케줄러 활용
- 전체 시스템 통합
Phase 3 완료 체크리스트
realtime/websocket_client.py생성realtime/event_handler.py생성realtime/market_scheduler.py생성realtime/examples.py생성- README 문서 작성
다음 단계
- 기존 WebSocket 코드 마이그레이션
- API 엔드포인트 통합
- 프론트엔드 WebSocket 연결
작성일: 2026-03-06
작성자: 서영우