# Crypto Trading Platform — Design Spec ## Overview Binance 현물 암호화폐 자동매매 플랫폼. 마이크로서비스 아키텍처 기반으로 데이터 수집, 전략 실행, 주문 처리, 포트폴리오 관리, 백테스팅을 독립 서비스로 운영한다. CLI로 제어하며, 전략은 플러그인 방식으로 확장 가능하다. - **시장:** 암호화폐 (Binance 현물) - **언어:** Python - **인터페이스:** CLI (Click) - **아키텍처:** 마이크로서비스 (Docker Compose) --- ## Architecture ### 서비스 구성 ``` ┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ Data │───▶│ Message Broker │◀──│ Strategy │ │ Collector │ │ (Redis Streams) │ │ Engine │ └─────────────┘ └──────────────────┘ └─────────────────┘ │ ▲ │ ▼ │ ▼ ┌──────────────────┐ ┌─────────────────┐ │ Backtester │ │ Order │ │ │ │ Executor │ └──────────────────┘ └─────────────────┘ │ ┌────────────────────────┘ ▼ ┌──────────────────┐ │ Portfolio │ │ Manager │ └──────────────────┘ CLI ──────▶ 각 서비스에 명령 전달 ``` | 서비스 | 역할 | 상시 실행 | |--------|------|-----------| | **data-collector** | Binance WebSocket/REST로 시세 수집, DB 저장 | Yes | | **strategy-engine** | 플러그인 전략 로드 및 시그널 생성 | 봇 실행 시 | | **order-executor** | 시그널 받아 실제 주문 실행 + 리스크 관리 | 봇 실행 시 | | **portfolio-manager** | 잔고, 손익, 포지션 추적 | Yes | | **backtester** | 과거 데이터로 전략 검증 | 요청 시 | | **shared** | 공통 모델, 이벤트 정의, 유틸리티 (라이브러리) | — | | **cli** | 사용자 인터페이스, 각 서비스 제어 | — | ### 통신 흐름 ``` [Binance WS] │ ▼ data-collector ──publish──▶ Redis Stream: "candles.{symbol}" │ ┌───────────────┤ ▼ ▼ strategy-engine backtester (과거 데이터는 DB에서) │ ▼ Redis Stream: "signals" │ ▼ order-executor │ ┌───────┴───────┐ ▼ ▼ [Binance API] Redis Stream: "orders" │ ▼ portfolio-manager ``` --- ## Project Structure ``` trading/ ├── services/ │ ├── data-collector/ │ │ ├── src/ │ │ │ ├── __init__.py │ │ │ ├── main.py # 서비스 진입점 │ │ │ ├── binance_ws.py # WebSocket 실시간 시세 │ │ │ ├── binance_rest.py # REST 과거 데이터 수집 │ │ │ ├── storage.py # DB 저장 로직 │ │ │ └── config.py │ │ ├── tests/ │ │ ├── Dockerfile │ │ └── pyproject.toml │ │ │ ├── strategy-engine/ │ │ ├── src/ │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── engine.py # 전략 로더 + 실행기 │ │ │ ├── plugin_loader.py # 플러그인 동적 로드 │ │ │ └── config.py │ │ ├── strategies/ # 플러그인 전략 디렉토리 │ │ │ ├── base.py # 전략 추상 클래스 │ │ │ ├── rsi_strategy.py # 예시: RSI 전략 │ │ │ └── grid_strategy.py # 예시: 그리드 전략 │ │ ├── tests/ │ │ ├── Dockerfile │ │ └── pyproject.toml │ │ │ ├── order-executor/ │ │ ├── src/ │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── executor.py # 주문 실행 로직 │ │ │ ├── risk_manager.py # 리스크 관리 (손절/익절) │ │ │ └── config.py │ │ ├── tests/ │ │ ├── Dockerfile │ │ └── pyproject.toml │ │ │ ├── portfolio-manager/ │ │ ├── src/ │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── portfolio.py # 잔고/포지션 추적 │ │ │ ├── pnl.py # 손익 계산 │ │ │ └── config.py │ │ ├── tests/ │ │ ├── Dockerfile │ │ └── pyproject.toml │ │ │ └── backtester/ │ ├── src/ │ │ ├── __init__.py │ │ ├── main.py │ │ ├── engine.py # 백테스팅 엔진 │ │ ├── simulator.py # 가상 주문 시뮬레이터 │ │ ├── reporter.py # 결과 리포트 생성 │ │ └── config.py │ ├── tests/ │ ├── Dockerfile │ └── pyproject.toml │ ├── shared/ │ ├── src/shared/ │ │ ├── __init__.py │ │ ├── models.py # 공통 데이터 모델 │ │ ├── events.py # 이벤트 타입 정의 │ │ ├── broker.py # Redis Streams 클라이언트 │ │ ├── db.py # DB 연결 (PostgreSQL) │ │ └── config.py # 공통 설정 │ ├── tests/ │ └── pyproject.toml │ ├── cli/ │ ├── src/ │ │ ├── __init__.py │ │ ├── main.py # Click 기반 CLI 진입점 │ │ ├── commands/ │ │ │ ├── data.py # 데이터 수집 명령 │ │ │ ├── trade.py # 매매 시작/중지 │ │ │ ├── backtest.py # 백테스팅 실행 │ │ │ ├── portfolio.py # 포트폴리오 조회 │ │ │ └── strategy.py # 전략 관리 │ │ └── config.py │ ├── tests/ │ └── pyproject.toml │ ├── docker-compose.yml # 전체 서비스 오케스트레이션 ├── .env.example # 환경변수 템플릿 ├── Makefile # 공통 명령어 └── README.md ``` --- ## Tech Stack | 용도 | 라이브러리 | |------|-----------| | 거래소 API | **ccxt** | | 메시지 브로커 | **Redis Streams** | | DB | **PostgreSQL** + **asyncpg** | | CLI | **Click** | | 데이터 분석 | **pandas**, **numpy** | | 기술 지표 | **pandas-ta** | | 비동기 처리 | **asyncio** + **aiohttp** | | 설정 관리 | **pydantic-settings** | | 컨테이너 | **Docker** + **docker-compose** | | 테스트 | **pytest** + **pytest-asyncio** | --- ## Data Models ### Core Models (shared/models.py) ```python class Candle: symbol: str # "BTCUSDT" timeframe: str # "1m", "5m", "1h" open_time: datetime open: Decimal high: Decimal low: Decimal close: Decimal volume: Decimal class Signal: strategy: str # "rsi_strategy" symbol: str side: "BUY" | "SELL" price: Decimal quantity: Decimal reason: str # 시그널 발생 근거 class Order: id: str signal_id: str # 추적용 symbol: str side: "BUY" | "SELL" type: "MARKET" | "LIMIT" price: Decimal quantity: Decimal status: "PENDING" | "FILLED" | "CANCELLED" | "FAILED" created_at: datetime filled_at: datetime | None class Position: symbol: str quantity: Decimal avg_entry_price: Decimal current_price: Decimal unrealized_pnl: Decimal ``` ### PostgreSQL Tables | 테이블 | 용도 | |--------|------| | `candles` | 시세 이력 (파티셔닝: symbol + timeframe) | | `signals` | 전략 시그널 이력 | | `orders` | 주문 이력 | | `trades` | 체결 이력 | | `positions` | 현재 포지션 | | `portfolio_snapshots` | 일별 포트폴리오 스냅샷 | ### Storage Strategy - **실시간 시세:** Redis 캐싱 + PostgreSQL 영구 저장 - **주문/체결:** PostgreSQL 즉시 기록 - **백테스팅 데이터:** PostgreSQL에서 bulk read (pandas DataFrame) --- ## Strategy Plugin System ### Base Interface ```python from abc import ABC, abstractmethod from shared.models import Candle, Signal class BaseStrategy(ABC): @abstractmethod def on_candle(self, candle: Candle) -> Signal | None: """캔들 데이터 수신 시 시그널 반환""" pass @abstractmethod def configure(self, params: dict) -> None: """전략 파라미터 설정""" pass ``` 새 전략 추가 = `BaseStrategy` 상속 파일 하나 작성 후 `strategies/` 디렉토리에 배치. ### 예시 전략 - **RSI Strategy:** RSI 과매도 시 매수, 과매수 시 매도 - **Grid Strategy:** 가격 구간을 나눠 자동 매수/매도 주문 배치 --- ## CLI Interface ```bash # 데이터 수집 trading data collect --symbol BTCUSDT --timeframe 1m trading data history --symbol BTCUSDT --from 2025-01-01 trading data list # 자동매매 trading trade start --strategy rsi --symbol BTCUSDT trading trade stop --strategy rsi trading trade status # 수동매매 trading order buy --symbol BTCUSDT --quantity 0.01 trading order sell --symbol BTCUSDT --price 70000 trading order cancel --id abc123 # 백테스팅 trading backtest run --strategy rsi --symbol BTCUSDT \ --from 2025-01-01 --to 2025-12-31 trading backtest report --id latest # 포트폴리오 trading portfolio show trading portfolio history --days 30 # 전략 관리 trading strategy list trading strategy info --name rsi # 서비스 관리 trading service up trading service down trading service logs --name strategy-engine ``` --- ## Risk Management ### Risk Check Pipeline (order-executor) 시그널 수신 시 다음 체크를 순서대로 통과해야 주문 실행: 1. 최대 포지션 크기 초과 여부 2. 일일 최대 손실 한도 도달 여부 3. 동일 심볼 중복 주문 방지 4. 주문 금액 < 가용 잔고 확인 5. 가격 급변 감지 (슬리피지 보호) ### Safety Mechanisms | 장치 | 설명 | |------|------| | **긴급 정지 (Kill Switch)** | `trading trade stop-all` — 모든 봇 중지, 미체결 주문 전량 취소 | | **일일 손실 한도** | 설정 비율 초과 시 자동 매매 중단 | | **최대 포지션 제한** | 총 자산 대비 단일 심볼 비율 제한 | | **연결 끊김 대응** | Binance 연결 끊기면 신규 주문 중단, 재연결 시도 | | **드라이런 모드** | 실제 주문 없이 시그널만 생성 — 전략 검증용 | --- ## Configuration (.env) ``` BINANCE_API_KEY= BINANCE_API_SECRET= REDIS_URL=redis://localhost:6379 DATABASE_URL=postgresql://user:pass@localhost:5432/trading LOG_LEVEL=INFO RISK_MAX_POSITION_SIZE=0.1 RISK_STOP_LOSS_PCT=5 RISK_DAILY_LOSS_LIMIT_PCT=10 DRY_RUN=true ``` --- ## Docker Compose Services ```yaml services: redis: # 메시지 브로커 (항상 실행) postgres: # 데이터 저장소 (항상 실행) data-collector: # 시세 수집 (항상 실행) strategy-engine: # 전략 엔진 (봇 실행 시) order-executor: # 주문 실행 (봇 실행 시) portfolio-manager: # 포트폴리오 (항상 실행) ```