
⚡️ AI + 주식 자동매매 프로젝트 공유
5편. 실시간 자동매매 시스템 구축 — FastAPI · vLLM · 전략 Executor 설계
실전 자동매매 시스템은 **지연(latency), 안정성, 안전장치(리스크 제어)**가 관건입니다.
여기서는 FastAPI를 실시간 API 레이어로 사용하고, vLLM(로컬/호스팅 LLM)을 신호 보정/해석에 활용하며, 전략 Executor가 주문 결정과 브로커 연동을 책임지는 구조를 제시합니다.
1. 전체 아키텍처 (권장)
[Market Data Sources] -> [Ingest / Normalizer] -> [Feature Store / Vector DB]
|
┌──────────┴──────────┐
| |
[ML Inference] [vLLM Inference]
| |
└─────[Meta Signal Engine]─────┐
| |
FastAPI (API Layer)
| |
[Strategy Executor] ──> [Broker Adapter]
|
[Risk Engine / Circuit Breaker]
|
[Trade Blotter / DB / Alerting]
주요 원칙:
- 비동기 처리로 데이터 수집·추론과 주문 실행 분리.
- **결정 논리(Executor)**는 항상 idempotent(같은 시점에 한 번만 실행)해야 함.
- **로깅/감사(Trade Blotter)**는 모든 주문 전/후에 남겨야 함.
2. 컴포넌트 역할 요약
- Ingest / Normalizer: 실시간 체결·호가를 정규화, feature store에 적재.
- ML Inference: XGBoost/LSTM 등 빠른 예측 모델(벡터화 추론).
- vLLM Inference: 뉴스·공시 해석, 시점별 보정·설명 생성(비교적 느리므로 분당/주기적 사용).
- Meta Signal Engine: ML + vLLM 결과를 결합해 최종 시그널 생성.
- FastAPI: 외부/내부로 시그널, 주문 요청, 상태 조회 제공.
- Strategy Executor: 시그널을 주문으로 변환, 브로커에 전송, 체결 로직 적용.
- Risk Engine: 포지션/노출 한도, 슬ippage/ADV 제한, circuit breaker.
- Broker Adapter: 실제 브로커 API (REST/WebSocket) 연결 및 주문 관리.
3. FastAPI 핵심 설계 (비동기 + 인증 + 상태 조회)
간단한 FastAPI 서버 골격(핵심부분만):
# app/main.py
from fastapi import FastAPI, BackgroundTasks, HTTPException
from pydantic import BaseModel
import asyncio
import uvicorn
app = FastAPI(title="AutoTrader API")
# 의사 데이터 구조
class Signal(BaseModel):
symbol: str
side: str # 'buy' or 'sell'
size: int
score: float
ts: str
# 내부 큐(간단 예)
order_queue = asyncio.Queue()
@app.post("/api/v1/signal")
async def receive_signal(sig: Signal, background_tasks: BackgroundTasks):
# 간단한 인증/검증은 생략(실무: OAuth2/mTLS)
# 시그널 수신 → executor로 전달
await order_queue.put(sig.dict())
return {"status":"queued", "symbol": sig.symbol}
@app.get("/api/v1/status")
async def status():
return {"queue_size": order_queue.qsize()}
# background worker example
async def executor_worker():
while True:
sig = await order_queue.get()
try:
# 실제로는 비동기 broker adapter 호출
await execute_signal(sig)
except Exception as e:
# 실패 로깅 + 알람
print("EXEC ERROR", e)
finally:
order_queue.task_done()
async def execute_signal(sig):
# 여기는 Executor 로직으로 대체된다.
print("Executing", sig)
await asyncio.sleep(0.1) # 모의 체결
@app.on_event("startup")
async def startup_event():
# 워커 3개 띄우기
for _ in range(3):
asyncio.create_task(executor_worker())
if __name__ == "__main__":
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=False)
실무 권장 사항:
- Uvicorn + Gunicorn(uvloop) 조합으로 멀티 워커 운영.
- 인증: mTLS 또는 OAuth2 + JWT, 내부 서비스는 mTLS 권장.
- Health check(읽기 전용 endpoint)와 readiness probe 설정.
4. Strategy Executor 설계 (핵심 로직)
Executor는 단순 주문 송신기가 아니라 체결 모델, 리스크 체크, 재시도, 부분체결 처리를 담당합니다.
핵심 흐름:
- 시그널 수신 → ID 발급(UID) → 시그널 검증(중복/타임스탬프)
- 리스크 엔진 호출(노출 한도, 포지션 제한, 시장 상황)
- 주문 분할(슬리피지/ADV 대비) → Broker Adapter로 전송
- 체결 응답 수신 → 트레이드 블로터 기록
- 포지션·캐시 업데이트 → 알람(조건 충족 시)
간단한 Executor 코드 (핵심만):
# executor.py
import uuid
from datetime import datetime
class RiskEngine:
def __init__(self, max_notional):
self.max_notional = max_notional
def permit(self, symbol, side, notional):
# 예시: 총 노출 제한 검사 (실무는 포지션별/시장별 고도 로직)
return notional <= self.max_notional
class BrokerAdapter:
async def place_order(self, symbol, side, qty, price=None):
# 실제 브로커 호출 (REST/WebSocket)
# 응답: {order_id, status, filled_qty, avg_price}
return {"order_id": "abc", "status": "filled", "filled_qty": qty, "avg_price": price or 100.0}
async def handle_signal(sig, risk_engine:RiskEngine, broker:BrokerAdapter):
uid = str(uuid.uuid4())
ts = datetime.fromisoformat(sig['ts'])
notional = sig['size'] * 100 # 예시 가격 가정
if not risk_engine.permit(sig['symbol'], sig['side'], notional):
# 거부 로깅 및 알림
return {"uid": uid, "status": "rejected"}
# 주문 분할 로직 (ADV 대비)
chunks = [sig['size']] # 단순화: 실제는 분할
trades = []
for qty in chunks:
resp = await broker.place_order(sig['symbol'], sig['side'], qty)
trades.append(resp)
# 부분 체결/재시도 로직 추가
# 트레이드 로그 저장
return {"uid": uid, "status": "executed", "trades": trades}
주의:
- 브로커 장애 시 롤백 불가 → idempotency key로 중복 주문 방지.
- 브로커 별 응답 시간 다름 → 타임아웃 엄격 설정.
5. vLLM(또는 LLM) 활용 패턴 (실시간 보정 전략)
vLLM은 대형 모델을 로컬 혹은 전용 서버에 배포해 느리지만 해석적 보정을 맡기는 방식으로 쓰세요.
패턴:
- Batch inference: 뉴스/공시가 발생할 때마다 배치로 LLM 호출(분 단위)
- 요약 + 영향도 평가: LLM이 요약문과 영향 점수를 반환 → Meta Signal Engine에서 가중치 적용
- Explainability: LLM 결과를 로그로 남겨 판단 근거 제공 (운영자 모니터링에 중요)
프롬프트 설계 원칙:
- 입력 길이 제한 고려(핵심 문장만 제공)
- 명확한 출력 형식(JSON)을 요구
- 비용·지연 최소화를 위해 사전 필터링(중요 기사만) 적용
6. 리스크 엔진 & Circuit Breaker
실전에서는 다음 안전 장치 필수:
- 노출 상한: 종목별/종목군별/포트폴리오 총액 상한
- 포지션 체크포인트: 실시간 마크투마켓 손익 기준으로 자동 청산 트리거
- 시장 서지 보호: 거래량 폭증/스프레드 급팽창 시 자동 거래 중지
- 시간 기반 차단: 일정 시간 내 연속 실패(예: 5회) 시 휴지 상태로 전환
- Kill Switch: 운영자가 즉시 전체 자동매매 정지 가능
간단한 Circuit Breaker 상태 머신:
STATE: NORMAL -> (n 실패) -> DEGRADED -> (m 실패) -> HALT
7. 모니터링·로깅·알림
- Trade Blotter: DB(ClickHouse/Postgres)에 모든 주문·체결·수수료 기록
- Metrics: Prometheus로 latency, queue depth, success rate, P&L 집계
- Dashboards: Grafana/Streamlit로 실시간 포지션/PNL/시그널 품질 시각화
- Alerting: Slack/Teams/메일 + SMS(중요)로 실패·리스크 이상 알림
- Trace: OpenTelemetry로 요청 트레이스 (FastAPI → Executor → Broker)
8. 배포·운영(실무 권장)
- 컨테이너화: Docker + Kubernetes(또는 ECS)
- 구성 관리: Helm/Terraform으로 인프라 선언적 관리
- 비밀 관리: Secrets Manager / Vault (API 키, 브로커 자격증명)
- Canary 배포: 모델/전략 코드 변경 시 Canary로 소량 자금에만 적용 후 전체 롤아웃
- 로컬 개발: 브로커 에뮬레이터(샌드박스)로 실제 주문 없이 통합 테스트 수행
9. 실제 운영에서 마주친 문제와 해결 사례
- 문제: 브로커 주문 응답 지연으로 중복 주문 발생
→ 해결: idempotency key + 주문 상태 폴링 대신 WebSocket 체결 콜백 사용으로 정합성 확보. - 문제: vLLM 추론 비용·지연으로 실시간 의사결정이 느려짐
→ 해결: LLM은 보정용(분 단위), ML은 실시간(초 단위) 역할 분리. LLM 결과는 포스트팩터로만 반영. - 문제: 급락장(Flash Crash)에서 포지션 과다 노출
→ 해결: ADV 기반 포지션 제한 및 시장충격 감지 시 자동 비상정지(계정 단위).
10. 실전 팁 3가지
✔ TIP 1 — 실시간과 비실시간 역할을 명확히 분리하라
실시간(초 단위): 가격 피드·ML 예측·즉시 체결.
비실시간(분~시간): LLM 해석·심층 리포트.
역할을 섞으면 지연·비용·리스크가 늘어납니다.
✔ TIP 2 — 모든 주문에 대해 Idempotency Key를 사용하라
네트워크/브로커 장애로 인한 중복 주문 위험을 막습니다.
strategy_id + signal_ts + uid 조합으로 키를 만들면 충분합니다.
✔ TIP 3 — Canary 배포로 실제 자금 위험을 줄여라
새 전략/모델을 바로 전체 자금에 적용하지 말고, 소액으로 Canary 테스트 후 문제 없을 때만 확장하세요.
실거래 로그와 백테스트 로그를 항상 대조해 이상 징후를 빨리 찾을 수 있습니다.
11. 코드 · 템플릿 저장소 제안 (운영 체크리스트)
프로젝트 루트에 다음 저장소 구조 권장:
/infra # k8s, terraform, helm
/app
/api # FastAPI
/executor # 전략 Executor
/models # ML 모델 서빙 코드
/llm # vLLM 프롬프트/서빙
/tests # 통합 테스트 / broker emulator
/docs
각 파트에 README.md로 실행·테스트 절차를 명시하세요.
12. 다음 편 예고 (원하시면 작성)
6편. 운영 중 발생하는 모델 드리프트 탐지와 온라인 재학습 파이프라인
- 데이터·성능 드리프트 감지
- 포괄적 A/B 테스트와 룰 기반 롤백
- 안전한 온라인 학습 전략
원하시면 6편을 지금 바로 작성해 드립니다.
📌 추천 태그
#자동매매 #실시간트레이딩 #FastAPI #vLLM #AI트레이딩
#전략엔진 #리스크관리 #백오피스 #Kubernetes #Quant
'AI 기반 자동매매 & 금융데이터 분석' 카테고리의 다른 글
| 4편. ML + LLM 기반 시그널 생성 실험기 — 모델 학습·검증·운영 파이프라인 (0) | 2025.12.05 |
|---|---|
| 3편. 백테스트 시스템 만들기 — 실전급 백테스트 엔진 설계와 구현 (0) | 2025.12.05 |
| 2편. 감성 분석 기반 시그널 실험 — 뉴스·트위터·리포트로 투자심리 점수 만들기 (0) | 2025.12.05 |
| 1편. 국내/미국 주식 데이터 수집 자동화 실전 가이드 (0) | 2025.12.05 |
| TimeParents v1.2.0 — Windows Game Time Management Tool for Kids (0) | 2025.11.30 |