diff --git a/.obsidian/app.json b/.obsidian/app.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.obsidian/app.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.obsidian/appearance.json b/.obsidian/appearance.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.obsidian/appearance.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.obsidian/core-plugins.json b/.obsidian/core-plugins.json new file mode 100644 index 0000000..639b90d --- /dev/null +++ b/.obsidian/core-plugins.json @@ -0,0 +1,33 @@ +{ + "file-explorer": true, + "global-search": true, + "switcher": true, + "graph": true, + "backlink": true, + "canvas": true, + "outgoing-link": true, + "tag-pane": true, + "footnotes": false, + "properties": true, + "page-preview": true, + "daily-notes": true, + "templates": true, + "note-composer": true, + "command-palette": true, + "slash-command": false, + "editor-status": true, + "bookmarks": true, + "markdown-importer": false, + "zk-prefixer": false, + "random-note": false, + "outline": true, + "word-count": true, + "slides": false, + "audio-recorder": false, + "workspaces": false, + "file-recovery": true, + "publish": false, + "sync": true, + "bases": true, + "webviewer": false +} \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json new file mode 100644 index 0000000..d78fa87 --- /dev/null +++ b/.obsidian/workspace.json @@ -0,0 +1,198 @@ +{ + "main": { + "id": "2368ff66953844f9", + "type": "split", + "children": [ + { + "id": "6495286b42a8bf9b", + "type": "tabs", + "children": [ + { + "id": "b9821d41e3b2938c", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "docs/01-overview.md", + "mode": "source", + "source": false + }, + "icon": "lucide-file", + "title": "01-overview" + } + } + ] + } + ], + "direction": "vertical" + }, + "left": { + "id": "2075a9d64fc12fa3", + "type": "split", + "children": [ + { + "id": "89fdefcb560ce022", + "type": "tabs", + "children": [ + { + "id": "8e1a145557d38a09", + "type": "leaf", + "state": { + "type": "file-explorer", + "state": { + "sortOrder": "alphabetical", + "autoReveal": false + }, + "icon": "lucide-folder-closed", + "title": "파일 탐색기" + } + }, + { + "id": "e8e754d9105c8a4b", + "type": "leaf", + "state": { + "type": "search", + "state": { + "query": "", + "matchingCase": false, + "explainSearch": false, + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical" + }, + "icon": "lucide-search", + "title": "검색" + } + }, + { + "id": "15dba3d38380203c", + "type": "leaf", + "state": { + "type": "bookmarks", + "state": {}, + "icon": "lucide-bookmark", + "title": "북마크" + } + } + ] + } + ], + "direction": "horizontal", + "width": 300 + }, + "right": { + "id": "7146911a3f689133", + "type": "split", + "children": [ + { + "id": "ab65bae9b04cd26f", + "type": "tabs", + "children": [ + { + "id": "3961c9ce54d34607", + "type": "leaf", + "state": { + "type": "backlink", + "state": { + "file": "docs/01-overview.md", + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical", + "showSearch": false, + "searchQuery": "", + "backlinkCollapsed": false, + "unlinkedCollapsed": true + }, + "icon": "links-coming-in", + "title": "01-overview 의 백링크" + } + }, + { + "id": "380d358f7c71933e", + "type": "leaf", + "state": { + "type": "outgoing-link", + "state": { + "file": "docs/01-overview.md", + "linksCollapsed": false, + "unlinkedCollapsed": true + }, + "icon": "links-going-out", + "title": "01-overview 의 나가는 링크" + } + }, + { + "id": "496a75e972ab4f2c", + "type": "leaf", + "state": { + "type": "tag", + "state": { + "sortOrder": "frequency", + "useHierarchy": true, + "showSearch": false, + "searchQuery": "" + }, + "icon": "lucide-tags", + "title": "태그" + } + }, + { + "id": "913da9b646423c5e", + "type": "leaf", + "state": { + "type": "all-properties", + "state": { + "sortOrder": "frequency", + "showSearch": false, + "searchQuery": "" + }, + "icon": "lucide-archive", + "title": "모든 속성" + } + }, + { + "id": "ab0c0c2b8374c194", + "type": "leaf", + "state": { + "type": "outline", + "state": { + "file": "docs/01-overview.md", + "followCursor": false, + "showSearch": false, + "searchQuery": "" + }, + "icon": "lucide-list", + "title": "01-overview 의 개요" + } + } + ] + } + ], + "direction": "horizontal", + "width": 300, + "collapsed": true + }, + "left-ribbon": { + "hiddenItems": { + "switcher:빠른 전환기 열기": false, + "graph:그래프 뷰 열기": false, + "canvas:새 캔버스 만들기": false, + "daily-notes:오늘의 일일 노트 열기": false, + "templates:템플릿 삽입": false, + "command-palette:명령어 팔레트 열기": false, + "bases:새 베이스 생성하기": false + } + }, + "active": "b9821d41e3b2938c", + "lastOpenFiles": [ + "components/phase3/audit.md", + "docs/01-overview.md", + "components/phase2/analytics.md", + "components/phase1/mgmt.md", + "components/phase1/balance.md", + "specification.md", + "README.md", + "AGENTS.md", + "diagram.md" + ] +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e7936e3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,52 @@ +# Repository Guidelines + +## 프로젝트 구조 및 모듈 구성 + +- `specification.md`는 컴포넌트 사양, 데이터 모델, TypeScript 스타일 인터페이스의 기준 문서입니다. +- `components/phase1/`, `components/phase2/`, `components/phase3/`에 단계별 컴포넌트 문서가 있습니다. + - Phase 1: `balance.md`, `mgmt.md`, `strategy.md`, `scheduler.md`, `data.md`, `risk.md` + - Phase 2: `analytics.md`, `monitor.md` + - Phase 3: `audit.md`, `simulation.md` +- `docs/`는 개요와 아키텍처 문서가 모여 있습니다(`01-overview.md`~`05-roadmap.md`). +- `diagram.md`에는 아키텍처 및 워크플로우를 설명하는 Mermaid 다이어그램이 있습니다. + +이 저장소는 구현 코드가 없는 문서 중심 리포지토리입니다. + +## 빌드, 테스트, 개발 명령 + +- 정의된 빌드/테스트 명령은 없습니다. +- 문서 변경 후 Markdown 미리보기나 Mermaid 뷰어로 확인하세요(예: `diagram.md`). + +## 코딩 스타일 및 네이밍 규칙 + +- 문서 본문은 한국어를 기본으로 하며, 컴포넌트명과 인터페이스 식별자는 영어를 사용합니다. +- `specification.md`의 섹션 구조(책임, 주요 기능, 데이터 모델)를 유지하세요. +- 리스트, 코드 블록, Mermaid 블록은 Markdown 규칙을 따릅니다. +- 인터페이스 변경 시 관련 컴포넌트 문서의 타입 정의도 함께 업데이트합니다. + +## 테스트 가이드 + +- 자동화된 테스트 프레임워크는 없습니다. +- 데이터 모델이나 워크플로우 변경 시 `specification.md`와 관련 컴포넌트 문서의 일관성을 함께 점검하세요. + +## 커밋 및 PR 가이드 + +- Git 이력이 거의 없어 확정된 커밋 규칙은 없습니다. +- 커밋 메시지는 변경 내용을 구체적으로 작성하세요(예: "리스크 모델 필드 업데이트"). +- PR에는 요약, 영향받는 파일, 다이어그램/워크플로우 변경 여부를 포함하세요. + +## 아키텍처 및 워크플로우 정합성 + +- 실행 플로우(스케줄러 → 전략 → 리스크 → 주문)를 바꾸면 `docs/04-workflows.md`와 `diagram.md`를 함께 수정합니다. +- 컨테이너 기반 자산 격리, 리스크 우선 설계 등 핵심 원칙은 유지합니다. +- 다이어그램을 수정했다면 텍스트 설명도 동기화하세요. + +## 문서 변경 체크리스트 + +- 데이터 모델 변경 시 `specification.md`와 관련 컴포넌트 문서를 모두 갱신합니다. +- Phase별 영향 범위를 확인하고 연동 문서를 함께 수정합니다. +- 외부 연동(브로커/데이터 소스) 가정이 바뀌면 `docs/02-architecture.md`도 점검합니다. + +## 작업 전 확인 + +- `CLAUDE.md`에 있는 저장소 특성(문서 전용, 한국어 중심, 리스크 우선 설계)과 수정 가이드를 먼저 확인합니다. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..77e5776 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,166 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is the specification repository for **QuantBench**, a quantitative trading platform for individual investors. It contains system architecture documentation, component specifications, and design diagrams but **no actual implementation code**. + +The platform enables: +- Multi-account management with multiple brokers (한국투자증권, 삼성증권, 키움증권) +- Container-based asset isolation for running multiple strategies in parallel +- Strategy-based automated trading with backtesting +- Risk management and performance analytics + +## System Architecture + +### Three-Phase Development Approach + +**Phase 1: MVP (Core Trading System)** +- `balance`: Broker API integration and account management +- `mgmt`: Virtual container management for asset isolation +- `strategy`: Strategy implementation, execution, and backtesting +- `scheduler`: Automated execution scheduling with approval workflows +- `risk`: Pre-trade risk validation and position monitoring +- `data`: Market data collection, storage, and quality management + +**Phase 2: Production Ready** +- `analytics`: Performance measurement, attribution analysis, and reporting +- `monitor`: System health monitoring, anomaly detection, and alerting + +**Phase 3: Enterprise Grade** +- `audit`: Immutable audit logging and compliance reporting +- `simulation`: Paper trading, scenario testing, and parameter optimization + +### Key Architectural Concepts + +**Container-Based Asset Isolation**: The core innovation is the virtual container system that allows multiple strategies to run independently within a single brokerage account. Each container has: +- Virtual balance tracking (isolated from other containers) +- Independent risk limits and constraints +- Dedicated strategy assignment +- Rebalancing schedules + +**Strategy Execution Flow**: +``` +scheduler trigger → mgmt (container info) → strategy (signal generation) → +data (market data) → risk (validation) → balance (order execution) → +mgmt (update positions) → analytics (performance calc) → monitor (alerts) +``` + +**Risk Management Integration**: All orders pass through risk validation before execution, checking: +- Balance sufficiency +- Position size limits +- Concentration limits +- Value at Risk (VaR) +- Maximum drawdown +- Leverage limits + +## Component Relationships + +### Core Dependencies +- `scheduler` orchestrates execution by calling `mgmt`, `strategy`, `risk`, and `balance` +- `strategy` depends on `data` for market data and `risk` for validation +- `mgmt` manages virtual balances and coordinates with `balance` for actual positions +- `analytics` consumes data from `mgmt`, `balance`, and `data` for performance calculation +- `monitor` observes all components and triggers alerts + +### Data Flow +- Real-time market data: Broker APIs → `data` → Redis cache → `strategy`/`monitor` +- Historical data: External providers → `data` → Time-series DB → `analytics`/backtesting +- Order flow: `strategy` signals → `risk` validation → `balance` execution → `mgmt` reconciliation + +## Working with This Repository + +### File Structure +- `specification.md`: Comprehensive component specifications with data models (44KB, Korean) +- `diagram.md`: Mermaid diagrams for architecture visualization +- `README.md`: Empty placeholder + +### Understanding the Specifications + +The `specification.md` file is structured with: +1. Component responsibilities and main functions +2. TypeScript interface definitions for data models +3. Function signatures with descriptions +4. Workflow examples showing component interactions + +Each component section follows this pattern: +``` +### Component Name (책임) +#### 주요 기능 +- Function descriptions with signatures +**데이터 모델** +- TypeScript interfaces +``` + +### Key Design Patterns + +**Broker Abstraction**: The `BrokerAdapter` interface in the `balance` component abstracts different broker APIs (한국투자증권, 삼성증권, 키움증권) behind a unified interface for portability. + +**Strategy Interface**: All strategies must implement `StrategyInterface` with required methods: +- `initialize(context: StrategyContext)` +- `generateSignals(data: MarketData): Signal[]` + +**Approval Workflow**: The scheduler supports both AUTO and APPROVAL_REQUIRED modes. In approval mode, execution waits for user confirmation before submitting orders. + +**Immutable Audit Trail**: Phase 3 introduces hash-chained audit events with `previousHash` links to ensure tamper-proof logging. + +## Important Considerations + +### Multi-Language Documentation +All specifications are written in Korean. Component names and code interfaces use English, but descriptions, comments, and documentation are in Korean. + +### No Implementation Code +This repository contains only specifications and diagrams. When discussing implementation: +- Reference the TypeScript interfaces defined in specifications +- Maintain consistency with the defined data models +- Follow the component interaction patterns described in workflows + +### Risk-First Design +The architecture prioritizes safety: +- All orders must pass risk validation before execution +- Container-level constraints prevent over-allocation +- Reconciliation functions detect discrepancies between virtual and actual balances +- Stop-loss and take-profit mechanisms support automatic position closure + +### Real-World Trading Constraints +The design accounts for practical trading considerations: +- Market hours and holidays (Korean exchanges) +- Commission and slippage modeling +- Order types (market, limit, stop) +- Partial fills and order status tracking +- Corporate actions (dividends, stock splits) + +## Diagram Reference + +The `diagram.md` file contains 10 Mermaid diagrams: +1. Overall system architecture (all phases) +2. Phase 1 component relationships +3. Phase-by-phase component structure +4. Strategy execution sequence diagram +5. Risk management flow +6. Data flow diagram +7. Container lifecycle state machine +8. Approval workflow +9. Monitoring and alerting system +10. Simulation environment structure + +Use these diagrams to understand component interactions visually before making specification changes. + +## Specification Modification Guidelines + +When updating specifications: + +1. **Maintain Interface Consistency**: Changes to data models should be reflected across all dependent components +2. **Update All Phases**: If a core data model changes, check impact across all three phases +3. **Preserve Type Safety**: Keep TypeScript interfaces complete with all required fields +4. **Document Workflows**: Update sequence descriptions when component interactions change +5. **Version Strategies**: Strategy changes should use the versioning system (`StrategyVersion`) + +## Related Systems + +The specifications reference external systems that must be integrated: +- Broker APIs: 한국투자증권, 삼성증권, 키움증권 +- Data providers: Yahoo Finance, Alpha Vantage +- Infrastructure: PostgreSQL, Redis, Message Queue (Kafka/RabbitMQ), S3 +- Notification channels: Email, SMS, Push, Slack diff --git a/components/phase1/balance.md b/components/phase1/balance.md new file mode 100644 index 0000000..6c2e973 --- /dev/null +++ b/components/phase1/balance.md @@ -0,0 +1,759 @@ +# balance - 계좌 관리 + +## 개요 + +**balance** 컴포넌트는 증권사 API 통합 및 계좌 자산 관리를 담당합니다. + +### 책임 + +- 증권사 API 인증 및 세션 관리 +- 다중 계좌 등록/수정/삭제 +- 계좌 잔고 및 포지션 조회 +- 시장 시세 조회 (현재가, 호가, 과거 데이터) +- 주문 처리 (제출, 취소, 상태 조회) + +### 의존성 + +```mermaid +graph LR + Balance[balance] --> Broker1[한국투자증권 API] + Balance --> Broker2[삼성증권 API] + Balance --> Broker3[키움증권 API] + + Mgmt[mgmt] --> Balance + Scheduler[scheduler] --> Balance + Monitor[monitor] --> Balance + + Balance --> DB[(Database)] + Balance --> Cache[(Redis Cache)] + + style Balance fill:#00BCD4,color:#fff +``` + +## 주요 기능 + +### 1. 계좌 연동 관리 + +#### 1.1 계좌 등록 + +```typescript +/** + * 새로운 증권사 계좌를 등록합니다 + */ +async function registerAccount(params: { + brokerId: string // 증권사 식별자 (예: 'korea_investment') + accountNumber: string // 계좌 번호 + accountName: string // 계좌 별칭 + accountType: AccountType // 계좌 유형 + credentials: { // 인증 정보 + apiKey: string + apiSecret: string + accountPassword?: string + } +}): Promise +``` + +**처리 흐름**: +1. 증권사 식별자 검증 +2. API 키 암호화 (AES-256) +3. 테스트 연결 수행 (인증 정보 유효성 검증) +4. 계좌 정보 데이터베이스 저장 +5. 초기 잔고 조회 + +#### 1.2 API 키 암호화 저장 + +```typescript +/** + * API 키를 AES-256으로 암호화하여 저장 + */ +function encryptCredentials(credentials: { + apiKey: string + apiSecret: string + accountPassword?: string +}): EncryptedCredentials { + const iv = crypto.randomBytes(16) + const cipher = crypto.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, iv) + + const encrypted = Buffer.concat([ + cipher.update(JSON.stringify(credentials), 'utf8'), + cipher.final() + ]) + + return { + encryptedData: encrypted.toString('base64'), + iv: iv.toString('base64'), + algorithm: 'aes-256-gcm' + } +} +``` + +### 2. 자산 조회 + +#### 2.1 현재 잔고 조회 + +```typescript +/** + * 계좌의 현재 잔고를 조회합니다 + */ +async function getCurrentBalance(accountId: string): Promise { + const account = await getAccount(accountId) + const adapter = getBrokerAdapter(account.brokerId) + + // 증권사 API 호출 + const balance = await adapter.getBalance(account) + + // 캐시 업데이트 + await cache.set(`balance:${accountId}`, balance, 60) // 60초 TTL + + return balance +} +``` + +**반환 데이터**: +```typescript +interface Balance { + accountId: string + cash: { + krw: number // 원화 잔고 + usd: number // 달러 잔고 (해외 주식용) + } + positions: Position[] // 보유 종목 + totalEquity: number // 총 자산 평가액 + buyingPower: number // 매수 가능 금액 + withdrawableCash: number // 출금 가능 금액 + timestamp: Date // 조회 시점 +} +``` + +#### 2.2 포트폴리오 스냅샷 + +```typescript +/** + * 자산 클래스별 비중 및 종목별 손익률을 포함한 포트폴리오 스냅샷 + */ +async function getPortfolioSnapshot(accountId: string): Promise { + const balance = await getCurrentBalance(accountId) + + // 자산 클래스별 비중 계산 + const assetAllocation = calculateAssetAllocation(balance.positions) + + // 종목별 손익률 계산 + const positionsWithPnL = balance.positions.map(position => ({ + ...position, + unrealizedPnLPct: (position.unrealizedPnL / (position.averagePrice * position.quantity)) * 100 + })) + + return { + ...balance, + assetAllocation, + positions: positionsWithPnL + } +} +``` + +### 3. 시세 조회 + +#### 3.1 현재가 조회 + +```typescript +/** + * 종목의 현재가 및 호가 정보를 조회합니다 + */ +async function getCurrentPrice(symbol: string): Promise { + // 캐시 우선 조회 (실시간 시세) + const cached = await cache.get(`quote:${symbol}`) + if (cached && Date.now() - cached.timestamp < 5000) { // 5초 이내 캐시 + return cached + } + + // 증권사 API 호출 + const adapter = getBrokerAdapter('default') + const quote = await adapter.getQuote(symbol) + + // 캐시 업데이트 + await cache.set(`quote:${symbol}`, quote, 10) // 10초 TTL + + return quote +} +``` + +**반환 데이터**: +```typescript +interface Quote { + symbol: string // 종목 코드 + price: number // 현재가 + change: number // 전일 대비 변동 + changePct: number // 변동률 (%) + volume: number // 거래량 + bidPrice: number // 매수 호가 1 + askPrice: number // 매도 호가 1 + bidSize: number // 매수 호가 수량 + askSize: number // 매도 호가 수량 + timestamp: Date // 시세 시간 +} +``` + +#### 3.2 과거 가격 조회 + +```typescript +/** + * 과거 가격 데이터를 조회합니다 (백테스트용) + */ +async function getHistoricalPrices(params: { + symbol: string + from: Date + to: Date + interval: Interval // '1d', '1w', '1M' 등 +}): Promise { + const adapter = getBrokerAdapter('default') + const prices = await adapter.getHistoricalPrices(params) + + // 배당 및 액면분할 조정 + const adjustedPrices = await adjustForCorporateActions(prices, params.symbol) + + return adjustedPrices +} +``` + +### 4. 주문 처리 + +#### 4.1 주문 제출 + +```typescript +/** + * 주문을 제출합니다 + */ +async function placeOrder(order: Order): Promise { + // 1. 주문 검증 + await validateOrder(order) + + // 2. 증권사 어댑터 선택 + const account = await getAccount(order.accountId) + const adapter = getBrokerAdapter(account.brokerId) + + // 3. 주문 제출 + try { + const result = await adapter.submitOrder(order) + + // 4. 주문 상태 저장 + await saveOrderStatus(result) + + // 5. 감사 로그 기록 + await audit.logEvent({ + eventType: 'ORDER', + action: 'CREATE', + entity: 'Order', + entityId: result.orderId!, + after: result + }) + + return result + + } catch (error) { + // 에러 로깅 + await logger.error('Order submission failed', { order, error }) + + // 알림 발송 + await monitor.sendAlert({ + type: 'EXECUTION', + severity: 'ERROR', + message: `주문 제출 실패: ${order.symbol} ${order.side} ${order.quantity}`, + metadata: { order, error } + }) + + throw error + } +} +``` + +**주문 검증**: +```typescript +async function validateOrder(order: Order): Promise { + // 계좌 존재 여부 확인 + const account = await getAccount(order.accountId) + if (!account.isActive) { + throw new Error('계좌가 비활성 상태입니다') + } + + // 주문 수량 검증 + if (order.quantity <= 0) { + throw new Error('주문 수량은 0보다 커야 합니다') + } + + // 호가 단위 검증 (지정가 주문인 경우) + if (order.orderType === 'LIMIT' && order.price) { + validatePriceTick(order.price, order.symbol) + } + + // 잔고 확인 (매수 주문인 경우) + if (order.side === 'BUY') { + const balance = await getCurrentBalance(order.accountId) + const requiredCash = order.quantity * (order.price || await getCurrentPrice(order.symbol).price) + + if (balance.buyingPower < requiredCash) { + throw new Error('매수 가능 금액이 부족합니다') + } + } +} +``` + +#### 4.2 주문 취소 + +```typescript +/** + * 미체결 주문을 취소합니다 + */ +async function cancelOrder(orderId: string): Promise { + // 1. 주문 정보 조회 + const order = await getOrder(orderId) + + if (!['PENDING', 'SUBMITTED', 'PARTIALLY_FILLED'].includes(order.status)) { + throw new Error(`취소 불가능한 주문 상태: ${order.status}`) + } + + // 2. 증권사 어댑터로 취소 요청 + const account = await getAccount(order.accountId) + const adapter = getBrokerAdapter(account.brokerId) + + const success = await adapter.cancelOrder(orderId) + + if (success) { + // 3. 주문 상태 업데이트 + await updateOrderStatus(orderId, 'CANCELLED') + + // 4. 감사 로그 기록 + await audit.logEvent({ + eventType: 'ORDER', + action: 'CANCEL', + entity: 'Order', + entityId: orderId + }) + } + + return success +} +``` + +#### 4.3 주문 상태 조회 + +```typescript +/** + * 주문의 현재 상태를 조회합니다 + */ +async function getOrderStatus(orderId: string): Promise { + const order = await getOrder(orderId) + + // 최종 상태가 아닌 경우 증권사 API에서 최신 상태 조회 + if (!['FILLED', 'CANCELLED', 'REJECTED', 'EXPIRED'].includes(order.status)) { + const account = await getAccount(order.accountId) + const adapter = getBrokerAdapter(account.brokerId) + + const latestStatus = await adapter.getOrderStatus(orderId) + + // 상태가 변경된 경우 업데이트 + if (latestStatus.status !== order.status) { + await updateOrderStatus(orderId, latestStatus.status, latestStatus) + } + + return latestStatus + } + + return { + orderId: order.orderId!, + status: order.status, + filledQuantity: order.filledQuantity, + averageFillPrice: order.averageFillPrice + } +} +``` + +## 증권사 추상화 인터페이스 + +### BrokerAdapter 인터페이스 + +```typescript +/** + * 모든 증권사 어댑터가 구현해야 하는 인터페이스 + */ +interface BrokerAdapter { + /** + * 증권사 API에 연결하고 세션을 생성합니다 + */ + connect(credentials: Credentials): Promise + + /** + * 계좌 잔고를 조회합니다 + */ + getBalance(account: Account): Promise + + /** + * 종목의 현재 시세를 조회합니다 + */ + getQuote(symbol: string): Promise + + /** + * 과거 가격 데이터를 조회합니다 + */ + getHistoricalPrices(params: HistoricalPricesParams): Promise + + /** + * 주문을 제출합니다 + */ + submitOrder(order: Order): Promise + + /** + * 주문을 취소합니다 + */ + cancelOrder(orderId: string): Promise + + /** + * 주문 상태를 조회합니다 + */ + getOrderStatus(orderId: string): Promise + + /** + * 주문 이력을 조회합니다 + */ + getOrderHistory(account: Account, from: Date, to: Date): Promise + + /** + * 세션을 종료합니다 + */ + disconnect(): Promise +} +``` + +### 구현 예시: 한국투자증권 Adapter + +```typescript +class KoreaInvestmentAdapter implements BrokerAdapter { + private accessToken?: string + private tokenExpiry?: Date + + async connect(credentials: Credentials): Promise { + // OAuth 토큰 발급 + const response = await axios.post('https://openapi.koreainvestment.com/oauth2/token', { + grant_type: 'client_credentials', + appkey: credentials.apiKey, + appsecret: credentials.apiSecret + }) + + this.accessToken = response.data.access_token + this.tokenExpiry = new Date(Date.now() + response.data.expires_in * 1000) + + return { + sessionId: response.data.access_token, + expiresAt: this.tokenExpiry + } + } + + async getBalance(account: Account): Promise { + await this.ensureConnected() + + const response = await axios.get( + 'https://openapi.koreainvestment.com/uapi/domestic-stock/v1/trading/inquire-balance', + { + headers: { + authorization: `Bearer ${this.accessToken}`, + appkey: account.credentials.apiKey, + appsecret: account.credentials.apiSecret, + tr_id: 'TTTC8434R' + }, + params: { + CANO: account.accountNumber.slice(0, 8), + ACNT_PRDT_CD: account.accountNumber.slice(8, 10) + } + } + ) + + // API 응답을 공통 Balance 형식으로 변환 + return this.transformBalance(response.data) + } + + async submitOrder(order: Order): Promise { + await this.ensureConnected() + + const response = await axios.post( + 'https://openapi.koreainvestment.com/uapi/domestic-stock/v1/trading/order-cash', + { + CANO: order.accountId.slice(0, 8), + ACNT_PRDT_CD: order.accountId.slice(8, 10), + PDNO: order.symbol, + ORD_DVSN: order.orderType === 'MARKET' ? '01' : '00', + ORD_QTY: order.quantity.toString(), + ORD_UNPR: order.price?.toString() || '0' + }, + { + headers: { + authorization: `Bearer ${this.accessToken}`, + tr_id: order.side === 'BUY' ? 'TTTC0802U' : 'TTTC0801U' + } + } + ) + + return { + ...order, + orderId: response.data.ODNO, + status: 'SUBMITTED', + submittedAt: new Date() + } + } + + private async ensureConnected(): Promise { + if (!this.accessToken || !this.tokenExpiry || this.tokenExpiry < new Date()) { + throw new Error('세션이 만료되었습니다. 다시 연결하세요.') + } + } + + private transformBalance(apiResponse: any): Balance { + // 증권사 API 응답을 공통 형식으로 변환 + // ... + } + + // ... 기타 메서드 구현 +} +``` + +## 데이터 모델 + +주요 데이터 모델은 [공통 데이터 모델](../../docs/03-data-models.md)을 참조하세요. + +- [Account](../../docs/03-data-models.md#11-account-계좌) +- [Balance](../../docs/03-data-models.md#12-balance-잔고) +- [Position](../../docs/03-data-models.md#13-position-포지션) +- [Order](../../docs/03-data-models.md#41-order-주문) +- [Quote](../../docs/03-data-models.md#52-quote-현재가) + +## API 명세 + +### REST API + +#### GET /api/accounts +계좌 목록 조회 + +**응답**: +```json +{ + "accounts": [ + { + "id": "account-123", + "brokerId": "korea_investment", + "accountNumber": "1234567890", + "accountName": "메인 계좌", + "accountType": "STOCK", + "isActive": true + } + ] +} +``` + +#### POST /api/accounts +계좌 등록 + +**요청**: +```json +{ + "brokerId": "korea_investment", + "accountNumber": "1234567890", + "accountName": "메인 계좌", + "accountType": "STOCK", + "credentials": { + "apiKey": "...", + "apiSecret": "..." + } +} +``` + +#### GET /api/accounts/:accountId/balance +잔고 조회 + +**응답**: +```json +{ + "accountId": "account-123", + "cash": { + "krw": 5000000, + "usd": 0 + }, + "positions": [ + { + "symbol": "005930", + "symbolName": "삼성전자", + "quantity": 100, + "averagePrice": 70000, + "currentPrice": 75000, + "marketValue": 7500000, + "unrealizedPnL": 500000, + "unrealizedPnLPct": 7.14 + } + ], + "totalEquity": 12500000, + "buyingPower": 4800000, + "timestamp": "2024-01-15T09:30:00Z" +} +``` + +#### POST /api/orders +주문 제출 + +**요청**: +```json +{ + "accountId": "account-123", + "symbol": "005930", + "side": "BUY", + "orderType": "LIMIT", + "quantity": 10, + "price": 74000 +} +``` + +## 구현 고려사항 + +### 1. 에러 처리 및 재시도 + +```typescript +// 지수 백오프 재시도 로직 +async function retryWithBackoff( + fn: () => Promise, + maxRetries: number = 3 +): Promise { + for (let i = 0; i < maxRetries; i++) { + try { + return await fn() + } catch (error) { + if (i === maxRetries - 1) throw error + + // 재시도 가능한 에러인지 확인 + if (!isRetryableError(error)) throw error + + // 지수 백오프 + const delay = Math.pow(2, i) * 1000 + await sleep(delay) + } + } + + throw new Error('Should not reach here') +} + +function isRetryableError(error: any): boolean { + // 네트워크 에러, 타임아웃, 5xx 에러 등 + return ( + error.code === 'ECONNRESET' || + error.code === 'ETIMEDOUT' || + (error.response?.status >= 500 && error.response?.status < 600) + ) +} +``` + +### 2. Rate Limiting + +증권사 API는 요청 제한이 있으므로 Rate Limiter 구현 필요: + +```typescript +class RateLimiter { + private queue: Array<() => Promise> = [] + private running: number = 0 + private maxConcurrent: number + private minInterval: number + + constructor(maxConcurrent: number = 5, minInterval: number = 100) { + this.maxConcurrent = maxConcurrent + this.minInterval = minInterval + } + + async execute(fn: () => Promise): Promise { + return new Promise((resolve, reject) => { + this.queue.push(async () => { + try { + const result = await fn() + resolve(result) + } catch (error) { + reject(error) + } + }) + + this.processQueue() + }) + } + + private async processQueue() { + if (this.running >= this.maxConcurrent || this.queue.length === 0) { + return + } + + const fn = this.queue.shift()! + this.running++ + + try { + await fn() + } finally { + this.running-- + setTimeout(() => this.processQueue(), this.minInterval) + } + } +} +``` + +### 3. 캐싱 전략 + +- **실시간 시세**: Redis에 5-10초 TTL로 캐싱 +- **계좌 잔고**: 1분 TTL +- **주문 상태**: 캐싱 안함 (항상 최신 데이터) + +### 4. 보안 + +- API 키는 절대 로그에 기록하지 않음 +- 평문 API 키는 메모리에만 존재 (복호화 후 즉시 사용) +- HTTPS 필수 +- API 키 로테이션 주기적 수행 + +## 테스트 + +### 단위 테스트 예시 + +```typescript +describe('balance - placeOrder', () => { + it('should place a valid buy order', async () => { + const order = { + accountId: 'test-account', + symbol: 'TEST', + side: 'BUY', + orderType: 'LIMIT', + quantity: 10, + price: 1000 + } + + const result = await balance.placeOrder(order) + + expect(result.orderId).toBeDefined() + expect(result.status).toBe('SUBMITTED') + }) + + it('should reject order with insufficient balance', async () => { + const order = { + accountId: 'test-account', + symbol: 'TEST', + side: 'BUY', + orderType: 'LIMIT', + quantity: 1000000, + price: 100000 + } + + await expect(balance.placeOrder(order)).rejects.toThrow('매수 가능 금액이 부족합니다') + }) +}) +``` + +## 관련 문서 + +- [시스템 개요](../../docs/01-overview.md) +- [전체 아키텍처](../../docs/02-architecture.md) +- [공통 데이터 모델](../../docs/03-data-models.md) +- [주요 워크플로우](../../docs/04-workflows.md) +- [구현 로드맵](../../docs/05-roadmap.md) + +### 관련 컴포넌트 +- [mgmt - 컨테이너 관리](./mgmt.md) +- [data - 데이터 관리](./data.md) +- [scheduler - 실행 스케줄러](./scheduler.md) diff --git a/components/phase1/data.md b/components/phase1/data.md new file mode 100644 index 0000000..49db6cc --- /dev/null +++ b/components/phase1/data.md @@ -0,0 +1,135 @@ +# data - 데이터 관리 + +## 개요 + +**data** 컴포넌트는 시계열 데이터 수집, 정제, 저장, 제공을 담당합니다. + +### 책임 + +- 외부 데이터 소스 연동 및 수집 스케줄링 +- 실시간 시세 스트리밍 및 캐시 업데이트 +- 데이터 품질 검증/보정 +- 백테스트 및 전략 실행을 위한 데이터 제공 + +### 의존성 + +```mermaid +graph LR + Data[data] --> Providers[Data Providers] + Data --> DB[(Time-series DB)] + Data --> Cache[(Redis Cache)] + + Strategy[strategy] --> Data + Analytics[analytics] --> Data + Monitor[monitor] --> Data + + style Data fill:#9C27B0,color:#fff +``` + +## 주요 기능 + +### 1. 데이터 수집 + +```typescript +collectMarketData(symbols: string[], from: Date, to: Date): void +updateRealTimeData(symbols: string[]): void +``` + +- 외부 제공자(Yahoo Finance, Alpha Vantage 등)에서 시세를 수집합니다. +- 증분 업데이트로 중복 수집을 방지합니다. + +### 2. 데이터 제공 + +```typescript +getPriceHistory(symbol: string, from: Date, to: Date, interval: Interval): PriceBar[] +getLatestPrice(symbol: string): Price +getMultipleSymbols(symbols: string[], date: Date): Record +``` + +- 실시간 데이터는 캐시 우선으로 제공합니다. + +### 3. 데이터 품질 관리 + +```typescript +validateData(symbol: string, from: Date, to: Date): ValidationReport +adjustForCorporateActions(symbol: string): void +fillMissingData(symbol: string, method: 'FORWARD_FILL' | 'INTERPOLATE'): void +``` + +- 결측치/이상치 탐지 및 보정 정책을 적용합니다. + +### 4. 데이터 소스 관리 + +```typescript +addDataSource(source: DataSourceConfig): DataSource +syncDataSource(sourceId: string): SyncResult +``` + +## 데이터 모델 + +```typescript +interface PriceBar { + symbol: string + timestamp: Date + open: number + high: number + low: number + close: number + volume: number + adjustedClose?: number +} + +interface DataSource { + id: string + name: string + provider: 'BROKER' | 'YAHOO' | 'ALPHA_VANTAGE' | 'CUSTOM' + config: { + apiKey?: string + endpoint?: string + rateLimit?: number + } + coverage: { + symbols: string[] + intervals: string[] + delay: number + } + priority: number + isActive: boolean +} + +interface ValidationReport { + symbol: string + period: { from: Date, to: Date } + issues: { + type: 'MISSING_DATA' | 'OUTLIER' | 'ZERO_VOLUME' | 'PRICE_GAP' + date: Date + description: string + severity: 'LOW' | 'MEDIUM' | 'HIGH' + }[] + completeness: number + quality: 'EXCELLENT' | 'GOOD' | 'FAIR' | 'POOR' +} +``` + +## API 명세 + +### GET /api/data/prices +가격 데이터 조회 + +### POST /api/data/sources +데이터 소스 추가 + +## 구현 고려사항 + +- 데이터 소스별 레이트 리밋을 준수합니다. +- 기업 이벤트(배당, 액면분할) 반영 규칙을 문서화합니다. + +## 관련 문서 + +- [공통 데이터 모델](../../docs/03-data-models.md) +- [주요 워크플로우](../../docs/04-workflows.md) + +### 관련 컴포넌트 +- [strategy - 전략 관리](./strategy.md) +- [analytics - 성과 분석](../phase2/analytics.md) +- [monitor - 모니터링](../phase2/monitor.md) diff --git a/components/phase1/mgmt.md b/components/phase1/mgmt.md new file mode 100644 index 0000000..05e2d24 --- /dev/null +++ b/components/phase1/mgmt.md @@ -0,0 +1,550 @@ +# mgmt - 컨테이너 관리 + +## 개요 + +**mgmt** 컴포넌트는 가상 자산 컨테이너 생성 및 운영 관리를 담당합니다. + +### 책임 + +- 컨테이너 생명주기 관리 (생성, 수정, 삭제, 활성화/비활성화) +- 가상 자산 격리 및 밸런스 관리 +- 컨테이너 간 자산 이동 +- 실제 계좌 vs 컨테이너 총합 일치성 검증 (Reconciliation) + +### 핵심 개념 + +**컨테이너(Container)**는 하나의 실제 계좌 내에서 가상으로 분리된 자산 공간입니다. + +```mermaid +graph TB + subgraph "실제 계좌 (한국투자증권)" + Account[계좌 총 자산: 1억원] + + subgraph "컨테이너 A" + A_Cash[현금: 500만원] + A_Stock[삼성전자: 2500만원] + A_Total[총 3000만원] + end + + subgraph "컨테이너 B" + B_Cash[현금: 1000만원] + B_ETF[KODEX 200: 4000만원] + B_Total[총 5000만원] + end + + subgraph "컨테이너 C" + C_Cash[현금: 2000만원] + C_Total[총 2000만원] + end + end + + Account --> A_Total + Account --> B_Total + Account --> C_Total + + style Account fill:#4CAF50,color:#fff + style A_Total fill:#2196F3,color:#fff + style B_Total fill:#2196F3,color:#fff + style C_Total fill:#2196F3,color:#fff +``` + +### 의존성 + +```mermaid +graph LR + Mgmt[mgmt] --> Balance[balance] + Mgmt --> Risk[risk] + Mgmt --> DB[(Database)] + + Scheduler[scheduler] --> Mgmt + Analytics[analytics] --> Mgmt + Monitor[monitor] --> Mgmt + + style Mgmt fill:#4CAF50,color:#fff +``` + +## 주요 기능 + +### 1. 컨테이너 생명주기 관리 + +#### 1.1 컨테이너 생성 + +```typescript +/** + * 새로운 컨테이너를 생성합니다 + */ +async function createContainer(params: { + accountId: string // 소속 계좌 ID + name: string // 컨테이너 이름 + description?: string // 설명 + initialAmount: number // 초기 할당 금액 + cashReserve: number // 최소 현금 보유량 + constraints: Constraints // 제약 조건 +}): Promise { + // 1. 계좌 잔고 확인 + const balance = await balance.getCurrentBalance(params.accountId) + + // 2. 할당 가능 금액 검증 + const allocatedSum = await getTotalAllocated(params.accountId) + if (allocatedSum + params.initialAmount > balance.totalEquity) { + throw new Error('할당 가능 금액을 초과합니다') + } + + // 3. 컨테이너 생성 + const container = await db.containers.create({ + ...params, + status: 'ACTIVE', + allocation: { + initialAmount: params.initialAmount, + currentEquity: params.initialAmount, + cashReserve: params.cashReserve + }, + createdAt: new Date() + }) + + // 4. 초기 가상 잔고 생성 + await createVirtualBalance(container.id, { + cash: params.initialAmount, + positions: [] + }) + + // 5. 감사 로그 + await audit.logEvent({ + eventType: 'CONFIG_CHANGE', + action: 'CREATE', + entity: 'Container', + entityId: container.id, + after: container + }) + + return container +} +``` + +#### 1.2 컨테이너 상태 관리 + +```mermaid +stateDiagram-v2 + [*] --> Created: createContainer() + + Created --> Active: activate() + Created --> [*]: delete() + + Active --> Running: scheduler trigger + Active --> Paused: pause() + Active --> [*]: delete() + + Running --> Active: execution complete + Running --> Error: execution failed + Running --> Paused: emergency stop + + Paused --> Active: resume() + Paused --> [*]: delete() + + Error --> Active: resolve & restart + Error --> Paused: manual intervention + Error --> [*]: delete() +``` + +```typescript +/** + * 컨테이너를 일시 정지합니다 + */ +async function pauseContainer(containerId: string): Promise { + const container = await getContainer(containerId) + + if (container.status === 'ARCHIVED') { + throw new Error('삭제된 컨테이너는 일시 정지할 수 없습니다') + } + + await updateContainerStatus(containerId, 'PAUSED') + + // 실행 중인 스케줄 일시 정지 + await scheduler.pauseSchedulesByContainer(containerId) + + await audit.logEvent({ + eventType: 'CONFIG_CHANGE', + action: 'UPDATE', + entity: 'Container', + entityId: containerId, + before: { status: container.status }, + after: { status: 'PAUSED' } + }) +} +``` + +### 2. 가상 자산 격리 + +#### 2.1 가상 잔고 관리 + +```typescript +/** + * 컨테이너의 가상 잔고를 조회합니다 + */ +async function getContainerBalance(containerId: string): Promise { + const virtualBalance = await db.virtualBalances.findOne({ containerId }) + + // 실시간 시세 반영 + const updatedPositions = await Promise.all( + virtualBalance.positions.map(async (position) => { + const quote = await balance.getCurrentPrice(position.symbol) + return { + ...position, + currentPrice: quote.price, + marketValue: position.quantity * quote.price, + unrealizedPnL: (quote.price - position.averagePrice) * position.quantity + } + }) + ) + + const totalValue = virtualBalance.cash + updatedPositions.reduce((sum, p) => sum + p.marketValue, 0) + + return { + containerId, + cash: virtualBalance.cash, + positions: updatedPositions, + totalValue, + availableCash: virtualBalance.cash, + allocatedValue: virtualBalance.allocatedValue, + timestamp: new Date() + } +} +``` + +#### 2.2 포지션 업데이트 + +```typescript +/** + * 주문 체결 후 컨테이너 포지션을 업데이트합니다 + */ +async function updatePosition( + containerId: string, + update: { + symbol: string + quantity: number // +: 매수, -: 매도 + price: number + commission: number + } +): Promise { + const virtualBalance = await db.virtualBalances.findOne({ containerId }) + + if (update.quantity > 0) { + // 매수 + const totalCost = update.quantity * update.price + update.commission + if (virtualBalance.cash < totalCost) { + throw new Error('가상 잔고가 부족합니다') + } + + virtualBalance.cash -= totalCost + + // 기존 포지션 업데이트 또는 신규 추가 + const existingPosition = virtualBalance.positions.find(p => p.symbol === update.symbol) + + if (existingPosition) { + // 평균 매입가 재계산 + const totalQuantity = existingPosition.quantity + update.quantity + const totalCost = existingPosition.averagePrice * existingPosition.quantity + update.price * update.quantity + existingPosition.averagePrice = totalCost / totalQuantity + existingPosition.quantity = totalQuantity + } else { + virtualBalance.positions.push({ + symbol: update.symbol, + quantity: update.quantity, + averagePrice: update.price, + currentPrice: update.price, + marketValue: update.quantity * update.price, + unrealizedPnL: 0, + unrealizedPnLPct: 0 + }) + } + + } else { + // 매도 + const position = virtualBalance.positions.find(p => p.symbol === update.symbol) + if (!position || position.quantity < Math.abs(update.quantity)) { + throw new Error('매도할 수량이 부족합니다') + } + + const sellAmount = Math.abs(update.quantity) * update.price - update.commission + virtualBalance.cash += sellAmount + + position.quantity += update.quantity // update.quantity는 음수 + + // 실현 손익 계산 + const realizedPnL = (update.price - position.averagePrice) * Math.abs(update.quantity) - update.commission + + // 포지션 완전 청산 시 제거 + if (position.quantity === 0) { + virtualBalance.positions = virtualBalance.positions.filter(p => p.symbol !== update.symbol) + } + } + + await db.virtualBalances.update({ containerId }, virtualBalance) +} +``` + +### 3. 컨테이너 간 자산 이동 + +```typescript +/** + * 컨테이너 간 현금을 이동합니다 + */ +async function transferCash(params: { + fromContainerId: string + toContainerId: string + amount: number + reason?: string +}): Promise { + // 1. 출발 컨테이너 잔고 확인 + const fromBalance = await getContainerBalance(params.fromContainerId) + if (fromBalance.availableCash < params.amount) { + throw new Error('이동 가능한 현금이 부족합니다') + } + + // 2. 두 컨테이너가 같은 계좌 소속인지 확인 + const fromContainer = await getContainer(params.fromContainerId) + const toContainer = await getContainer(params.toContainerId) + + if (fromContainer.accountId !== toContainer.accountId) { + throw new Error('같은 계좌 내 컨테이너 간에만 이동 가능합니다') + } + + // 3. 트랜잭션으로 원자적 실행 + await db.transaction(async (tx) => { + // 출발 컨테이너에서 차감 + await tx.virtualBalances.update( + { containerId: params.fromContainerId }, + { $inc: { cash: -params.amount } } + ) + + // 도착 컨테이너에 추가 + await tx.virtualBalances.update( + { containerId: params.toContainerId }, + { $inc: { cash: params.amount } } + ) + + // 이동 기록 생성 + const transfer = await tx.transfers.create({ + fromContainerId: params.fromContainerId, + toContainerId: params.toContainerId, + amount: params.amount, + reason: params.reason, + createdAt: new Date() + }) + + return transfer + }) + + // 4. 감사 로그 + await audit.logEvent({ + eventType: 'CONFIG_CHANGE', + action: 'TRANSFER', + entity: 'Transfer', + entityId: transfer.id, + metadata: params + }) + + return transfer +} +``` + +### 4. 밸런스 조정 (Reconciliation) + +```typescript +/** + * 실제 계좌 잔고와 컨테이너 총합이 일치하는지 검증합니다 + */ +async function reconcileAssets(accountId: string): Promise { + // 1. 실제 계좌 잔고 조회 + const actualBalance = await balance.getCurrentBalance(accountId) + + // 2. 모든 컨테이너 잔고 합산 + const containers = await getContainersByAccount(accountId) + const virtualBalances = await Promise.all( + containers.map(c => getContainerBalance(c.id)) + ) + + const virtualTotal = { + cash: virtualBalances.reduce((sum, vb) => sum + vb.cash, 0), + positions: aggregatePositions(virtualBalances.map(vb => vb.positions)) + } + + // 3. 차이 검증 + const cashDiscrepancy = actualBalance.cash.krw - virtualTotal.cash + const positionDiscrepancies = findPositionDiscrepancies(actualBalance.positions, virtualTotal.positions) + + const isReconciled = Math.abs(cashDiscrepancy) < 100 && positionDiscrepancies.length === 0 + + const report: ReconciliationReport = { + accountId, + isReconciled, + actual: { + cash: actualBalance.cash.krw, + positions: actualBalance.positions + }, + virtual: { + cash: virtualTotal.cash, + positions: virtualTotal.positions + }, + discrepancies: { + cash: cashDiscrepancy, + positions: positionDiscrepancies + }, + timestamp: new Date() + } + + // 4. 불일치 시 알림 + if (!isReconciled) { + await monitor.sendAlert({ + type: 'SYSTEM', + severity: 'ERROR', + message: `밸런스 불일치 감지: 계좌 ${accountId}`, + metadata: report + }) + } + + return report +} + +function aggregatePositions(positionGroups: Position[][]): Position[] { + const aggregated = new Map() + + for (const positions of positionGroups) { + for (const position of positions) { + if (aggregated.has(position.symbol)) { + const existing = aggregated.get(position.symbol)! + existing.quantity += position.quantity + existing.marketValue += position.marketValue + } else { + aggregated.set(position.symbol, { ...position }) + } + } + } + + return Array.from(aggregated.values()) +} +``` + +## 데이터 모델 + +주요 데이터 모델: +- [Container](../../docs/03-data-models.md#21-container-컨테이너) +- [VirtualBalance](../../docs/03-data-models.md#22-virtualbalance-가상-잔고) + +## API 명세 + +### POST /api/containers +컨테이너 생성 + +**요청**: +```json +{ + "accountId": "account-123", + "name": "성장주 전략", + "initialAmount": 10000000, + "cashReserve": 1000000, + "constraints": { + "maxSinglePositionPct": 20, + "maxDrawdown": 15, + "allowedAssetClasses": ["STOCK"] + } +} +``` + +### GET /api/containers/:containerId +컨테이너 조회 + +**응답**: +```json +{ + "id": "container-456", + "accountId": "account-123", + "name": "성장주 전략", + "strategyId": "strategy-momentum", + "status": "ACTIVE", + "allocation": { + "initialAmount": 10000000, + "currentEquity": 10500000, + "cashReserve": 1000000 + } +} +``` + +### GET /api/containers/:containerId/balance +가상 잔고 조회 + +**응답**: +```json +{ + "containerId": "container-456", + "cash": 3000000, + "positions": [ + { + "symbol": "005930", + "quantity": 100, + "averagePrice": 70000, + "currentPrice": 75000, + "marketValue": 7500000, + "unrealizedPnL": 500000 + } + ], + "totalValue": 10500000, + "availableCash": 3000000 +} +``` + +## 구현 고려사항 + +### 1. 원자성 보장 + +컨테이너 간 자산 이동은 반드시 트랜잭션으로 처리하여 데이터 무결성을 보장해야 합니다. + +### 2. 정기적인 Reconciliation + +매일 장 마감 후 자동으로 Reconciliation 실행: + +```typescript +scheduler.scheduleDaily('MARKET_CLOSE', async () => { + const accounts = await balance.getAllAccounts() + + for (const account of accounts) { + const report = await mgmt.reconcileAssets(account.id) + + if (!report.isReconciled) { + await monitor.sendAlert({ + type: 'SYSTEM', + severity: 'CRITICAL', + message: `밸런스 불일치: ${account.accountName}` + }) + } + } +}) +``` + +### 3. 컨테이너 삭제 시 주의사항 + +컨테이너 삭제 시 보유 포지션이 있다면 경고: + +```typescript +async function deleteContainer(containerId: string): Promise { + const balance = await getContainerBalance(containerId) + + if (balance.positions.length > 0) { + throw new Error('포지션이 남아있는 컨테이너는 삭제할 수 없습니다. 먼저 모든 포지션을 청산하세요.') + } + + // ARCHIVED 상태로 변경 (소프트 삭제) + await updateContainerStatus(containerId, 'ARCHIVED') +} +``` + +## 관련 문서 + +- [시스템 개요](../../docs/01-overview.md) +- [전체 아키텍처](../../docs/02-architecture.md) +- [공통 데이터 모델](../../docs/03-data-models.md) + +### 관련 컴포넌트 +- [balance - 계좌 관리](./balance.md) +- [strategy - 전략 관리](./strategy.md) +- [risk - 리스크 관리](./risk.md) diff --git a/components/phase1/risk.md b/components/phase1/risk.md new file mode 100644 index 0000000..0b5002a --- /dev/null +++ b/components/phase1/risk.md @@ -0,0 +1,169 @@ +# risk - 리스크 관리 + +## 개요 + +**risk** 컴포넌트는 사전 주문 검증과 포지션 리스크 모니터링을 담당합니다. + +### 책임 + +- 주문 전 리스크 체크 (잔고, 포지션 한도, 레버리지) +- 포지션 리스크 지표 계산 (VaR, 베타, 집중도) +- 손절/익절 조건 관리 및 트리거 평가 +- 리스크 한도 설정 및 위반 감지 + +### 의존성 + +```mermaid +graph LR + Risk[risk] --> Mgmt[mgmt] + Risk --> Balance[balance] + Risk --> Data[data] + Risk --> DB[(Database)] + + Scheduler[scheduler] --> Risk + Monitor[monitor] --> Risk + + style Risk fill:#E53935,color:#fff +``` + +## 주요 기능 + +### 1. 사전 주문 검증 + +```typescript +validateOrder(order: Order, container: Container): RiskCheckResult +validateOrderBatch(orders: Order[], container: Container): RiskCheckResult[] +``` + +- 잔고 충분성, 포지션 사이즈, 집중도, 레버리지를 검증합니다. + +### 2. 포지션 리스크 모니터링 + +```typescript +calculatePositionRisk(containerId: string): PositionRisk +checkRiskLimits(containerId: string): LimitViolation[] +``` + +### 3. 손절/익절 관리 + +```typescript +setStopLoss(containerId: string, symbol: string, config: StopLossConfig): void +setTakeProfit(containerId: string, symbol: string, level: number): void +checkStopConditions(containerId: string): StopTrigger[] +``` + +### 4. 리스크 한도 설정 + +```typescript +setRiskLimits(containerId: string, limits: RiskLimits): void +getRiskProfile(containerId: string): RiskProfile +``` + +### 5. 포트폴리오 리스크 분석 + +```typescript +calculatePortfolioVaR(containerId: string, confidence: number, horizon: number): VaRResult +calculateCorrelationMatrix(containerId: string): CorrelationMatrix +stressTest(containerId: string, scenarios: Scenario[]): StressTestResult[] +``` + +## 데이터 모델 + +```typescript +interface RiskLimits { + containerId: string + position: { + maxSinglePositionPct: number + maxSectorPct: number + maxTotalLeverage: number + } + loss: { + maxDailyLossPct: number + maxDrawdownPct: number + stopLossEnabled: boolean + } + exposure: { + maxLongExposure: number + maxShortExposure: number + maxGrossExposure: number + } +} + +interface RiskCheckResult { + passed: boolean + violations: { + rule: string + severity: 'BLOCKING' | 'WARNING' + message: string + currentValue: number + limitValue: number + }[] + recommendations?: string[] +} + +interface PositionRisk { + containerId: string + positions: { + symbol: string + marketValue: number + weightPct: number + VaR95: number + beta: number + sector: string + }[] + portfolio: { + totalValue: number + totalVaR95: number + beta: number + correlationRisk: number + } + limits: { + type: string + current: number + limit: number + utilizationPct: number + }[] + calculatedAt: Date +} + +interface StopLossConfig { + type: 'FIXED' | 'TRAILING' | 'TIME_BASED' + fixedPrice?: number + fixedPct?: number + trailingPct?: number + holdingPeriodDays?: number + autoExecute: boolean +} + +interface VaRResult { + confidence: number + horizon: number + VaR: number + VaRPct: number + method: 'HISTORICAL' | 'PARAMETRIC' | 'MONTE_CARLO' + calculatedAt: Date +} +``` + +## API 명세 + +### POST /api/risk/check +주문 리스크 체크 + +### GET /api/risk/containers/:containerId +리스크 프로필 조회 + +## 구현 고려사항 + +- 리스크 위반은 monitor 알림과 연동합니다. +- 한도 변경은 감사 로그로 추적합니다. + +## 관련 문서 + +- [공통 데이터 모델](../../docs/03-data-models.md) +- [주요 워크플로우](../../docs/04-workflows.md) + +### 관련 컴포넌트 +- [mgmt - 컨테이너 관리](./mgmt.md) +- [balance - 계좌 관리](./balance.md) +- [strategy - 전략 관리](./strategy.md) diff --git a/components/phase1/scheduler.md b/components/phase1/scheduler.md new file mode 100644 index 0000000..9d28a8f --- /dev/null +++ b/components/phase1/scheduler.md @@ -0,0 +1,149 @@ +# scheduler - 실행 스케줄러 + +## 개요 + +**scheduler** 컴포넌트는 전략 실행 자동화, 리밸런싱, 승인 워크플로우를 관리합니다. + +### 책임 + +- 컨테이너별 실행 일정 관리 +- 실행 트리거 및 리밸런싱 스케줄링 +- 승인 요청 및 실행 흐름 제어 +- 실행 이력 저장 및 알림 + +### 의존성 + +```mermaid +graph LR + Scheduler[scheduler] --> Mgmt[mgmt] + Scheduler --> Strategy[strategy] + Scheduler --> Risk[risk] + Scheduler --> Balance[balance] + Scheduler --> Monitor[monitor] + Scheduler --> DB[(Database)] + + style Scheduler fill:#FF9800,color:#fff +``` + +## 주요 기능 + +### 1. 스케줄 관리 + +```typescript +createSchedule(containerId: string, schedule: ScheduleConfig): Schedule +updateSchedule(scheduleId: string, config: Partial): Schedule +pauseSchedule(scheduleId: string): boolean +resumeSchedule(scheduleId: string): boolean +``` + +- Cron/interval/이벤트 기반 트리거를 지원합니다. +- 시장 시간 및 휴일을 고려해 다음 실행 시점을 계산합니다. + +### 2. 실행 트리거 + +```typescript +executeStrategy(containerId: string, mode: 'AUTO' | 'MANUAL'): Execution +scheduleRebalancing(containerId: string): void +``` + +- 신호 생성 → 리스크 체크 → 주문 생성 → 승인 처리 순서로 실행합니다. + +### 3. 승인 워크플로우 + +```typescript +requestApproval(execution: Execution): ApprovalRequest +approveExecution(requestId: string, approved: boolean): boolean +autoExecuteWithNotification(execution: Execution): ExecutionResult +``` + +- 승인 모드에서는 예상 주문 내역과 비용을 사용자에게 제공합니다. + +### 4. 실행 이력 관리 + +```typescript +getExecutionHistory(containerId: string, from: Date): Execution[] +getExecutionDetail(executionId: string): ExecutionDetail +``` + +## 데이터 모델 + +```typescript +interface Schedule { + id: string + containerId: string + trigger: { + type: 'CRON' | 'INTERVAL' | 'EVENT' + expression?: string + intervalMinutes?: number + event?: 'MARKET_OPEN' | 'MARKET_CLOSE' + } + executionMode: 'AUTO' | 'APPROVAL_REQUIRED' + constraints: { + marketHoursOnly: boolean + skipHolidays: boolean + minIntervalHours?: number + } + isActive: boolean + nextRun?: Date + lastRun?: Date +} + +interface Execution { + id: string + containerId: string + strategyId: string + status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'RUNNING' | 'COMPLETED' | 'FAILED' + signals: Signal[] + plannedOrders: Order[] + executedOrders: Order[] + estimatedCost: { + commission: number + totalValue: number + } + approvalRequest?: ApprovalRequest + startedAt?: Date + completedAt?: Date + error?: string +} + +interface ApprovalRequest { + id: string + executionId: string + summary: { + numOrders: number + buyValue: number + sellValue: number + estimatedCommission: number + } + orders: Order[] + requestedAt: Date + expiresAt: Date + approvedAt?: Date + approvedBy?: string + decision?: 'APPROVED' | 'REJECTED' +} +``` + +## API 명세 + +### POST /api/schedules +스케줄 생성 + +### POST /api/executions/:executionId/approve +승인/거부 처리 + +## 구현 고려사항 + +- 승인 만료 처리 및 재요청 정책을 정의해야 합니다. +- 실행 실패 시 재시도/중단 기준을 명확히 둡니다. + +## 관련 문서 + +- [주요 워크플로우](../../docs/04-workflows.md) +- [공통 데이터 모델](../../docs/03-data-models.md) + +### 관련 컴포넌트 +- [mgmt - 컨테이너 관리](./mgmt.md) +- [strategy - 전략 관리](./strategy.md) +- [risk - 리스크 관리](./risk.md) +- [balance - 계좌 관리](./balance.md) diff --git a/components/phase1/strategy.md b/components/phase1/strategy.md new file mode 100644 index 0000000..a192519 --- /dev/null +++ b/components/phase1/strategy.md @@ -0,0 +1,177 @@ +# strategy - 전략 관리 + +## 개요 + +**strategy** 컴포넌트는 전략 등록, 버전 관리, 신호 생성, 백테스트를 담당합니다. + +### 책임 + +- 전략 코드/메타데이터 등록 및 버전 관리 +- 시장 데이터 기반 매매 신호 생성 +- 신호를 주문으로 변환 +- 백테스트 실행 및 성과 지표 계산 +- 파라미터 관리 및 검증 + +### 의존성 + +```mermaid +graph LR + Strategy[strategy] --> Data[data] + Strategy --> Risk[risk] + Strategy --> DB[(Database)] + + Scheduler[scheduler] --> Strategy + Analytics[analytics] --> Strategy + + style Strategy fill:#2196F3,color:#fff +``` + +## 주요 기능 + +### 1. 전략 등록 및 버전 관리 + +```typescript +registerStrategy(strategy: StrategyDefinition): Strategy +updateStrategy(id: string, version: StrategyVersion): Strategy +getStrategy(id: string, version?: string): Strategy +``` + +- 전략 코드와 파라미터 메타데이터를 저장합니다. +- 새 버전은 불변으로 보존하고 변경 이력을 추적합니다. + +### 2. 전략 실행 엔진 + +```typescript +calculateSignals(strategyId: string, marketData: MarketData): Signal[] +generateOrders(containerId: string, signals: Signal[]): Order[] +``` + +- 전략 신호를 생성하고 현재 포지션과 목표 포지션 차이로 주문을 계산합니다. + +### 3. 백테스트 + +```typescript +runBacktest(config: BacktestConfig): BacktestResult +calculateMetrics(backtestResult: BacktestResult): PerformanceMetrics +``` + +- 거래 비용과 슬리피지를 반영해 성과 지표를 산출합니다. + +### 4. 파라미터 관리 + +```typescript +getParameters(strategyId: string): Parameter[] +setParameters(strategyId: string, params: Record): void +``` + +- 파라미터 타입/범위를 검증하고 실행 컨텍스트에 반영합니다. + +### 전략 인터페이스 + +```typescript +interface StrategyInterface { + initialize(context: StrategyContext): void + generateSignals(data: MarketData): Signal[] + + onMarketOpen?(): void + onMarketClose?(): void + onOrderFilled?(order: Order): void +} +``` + +## 데이터 모델 + +```typescript +interface Strategy { + id: string + name: string + description: string + category: 'ASSET_ALLOCATION' | 'MOMENTUM' | 'VALUE' | 'ARBITRAGE' | 'CUSTOM' + versions: StrategyVersion[] + currentVersion: string + parameters: Parameter[] + requiredData: string[] + createdBy: string + createdAt: Date + isPublic: boolean +} + +interface StrategyVersion { + version: string + code: string + changelog?: string + createdAt: Date + backtestResults?: BacktestResult[] +} + +interface Signal { + symbol: string + action: 'BUY' | 'SELL' | 'HOLD' + targetWeight?: number + targetQuantity?: number + reason?: string + confidence?: number + generatedAt: Date +} + +interface BacktestConfig { + strategyId: string + strategyVersion: string + startDate: Date + endDate: Date + initialCapital: number + universe: string[] + benchmark?: string + costs: { + commission: number + slippage: number + } +} + +interface BacktestResult { + strategyId: string + config: BacktestConfig + equity: { + date: Date + value: number + cash: number + positions: Record + }[] + trades: { + date: Date + symbol: string + action: 'BUY' | 'SELL' + quantity: number + price: number + commission: number + }[] + metrics: PerformanceMetrics + runAt: Date +} +``` + +## API 명세 + +### POST /api/strategies +전략 등록 + +### GET /api/strategies/:strategyId +전략 조회 (version 파라미터 지원) + +### POST /api/strategies/:strategyId/backtests +백테스트 실행 + +## 구현 고려사항 + +- 전략 코드 저장 시 보안 검토 및 샌드박스 실행 환경을 고려합니다. +- 파라미터 변경은 감사 로그에 기록합니다. + +## 관련 문서 + +- [시스템 개요](../../docs/01-overview.md) +- [공통 데이터 모델](../../docs/03-data-models.md) + +### 관련 컴포넌트 +- [data - 데이터 관리](./data.md) +- [risk - 리스크 관리](./risk.md) +- [scheduler - 실행 스케줄러](./scheduler.md) diff --git a/components/phase2/analytics.md b/components/phase2/analytics.md new file mode 100644 index 0000000..dab9fc9 --- /dev/null +++ b/components/phase2/analytics.md @@ -0,0 +1,211 @@ +# analytics - 성과 분석 및 리포팅 + +## 개요 + +**analytics** 컴포넌트는 실거래 성과 측정, 귀속 분석, 리포팅을 담당합니다. + +### 책임 + +- 기간별 수익률 및 리스크 지표 계산 +- 귀속 분석(자산 배분, 종목 선택, 타이밍) +- 거래 분석 및 비용 추정 +- 정기 리포트 생성 및 배포 +- 벤치마크 대비 성과 비교 + +### 의존성 + +```mermaid +graph LR + Analytics[analytics] --> Mgmt[mgmt] + Analytics --> Balance[balance] + Analytics --> Data[data] + Analytics --> DB[(Database)] + + Monitor[monitor] --> Analytics + + style Analytics fill:#3F51B5,color:#fff +``` + +## 주요 기능 + +### 1. 성과 측정 + +```typescript +calculatePerformance(containerId: string, period: DateRange): PerformanceReport +getReturnsTimeseries(containerId: string, from: Date): TimeseriesData +``` + +### 2. 귀속 분석 + +```typescript +analyzeReturns(containerId: string, period: DateRange): AttributionReport +``` + +### 3. 거래 분석 + +```typescript +analyzeTrades(containerId: string, from: Date): TradeAnalysis +calculateTradingCosts(containerId: string, period: DateRange): CostAnalysis +``` + +### 4. 리포트 생성 + +```typescript +generateReport(containerId: string, type: ReportType, period: DateRange): Report +scheduleReport(config: ReportSchedule): void +``` + +### 5. 벤치마크 비교 + +```typescript +compareWithBenchmark(containerId: string, benchmarkSymbol: string, period: DateRange): ComparisonReport +``` + +## 데이터 모델 + +```typescript +interface PerformanceReport { + containerId: string + period: DateRange + returns: { + total: number + annualized: number + daily: number + weekly: number + monthly: number + ytd: number + } + risk: { + volatility: number + sharpeRatio: number + sortinoRatio: number + maxDrawdown: number + calmarRatio: number + } + benchmark?: { + symbol: string + returns: number + excessReturn: number + beta: number + alpha: number + trackingError: number + informationRatio: number + } + generatedAt: Date +} + +interface AttributionReport { + containerId: string + period: DateRange + totalReturn: number + attribution: { + assetAllocation: number + stockSelection: number + timing: number + interaction: number + } + sectorContribution: { + sector: string + weight: number + return: number + contribution: number + }[] + topContributors: { + symbol: string + contribution: number + }[] + topDetractors: { + symbol: string + contribution: number + }[] +} + +interface TradeAnalysis { + containerId: string + period: DateRange + summary: { + totalTrades: number + winningTrades: number + losingTrades: number + winRate: number + avgWin: number + avgLoss: number + profitFactor: number + avgHoldingPeriod: number + turnoverRate: number + } + longestWinStreak: number + longestLossStreak: number + largestWin: { + symbol: string + return: number + date: Date + } + largestLoss: { + symbol: string + return: number + date: Date + } +} + +interface CostAnalysis { + period: DateRange + costs: { + commission: number + estimatedSlippage: number + tax: number + other: number + total: number + } + impact: { + grossReturn: number + netReturn: number + costDrag: number + } + costByType: { + buy: number + sell: number + } +} + +interface Report { + id: string + containerId: string + type: ReportType + period: DateRange + sections: { + summary: PerformanceSummary + positions: CurrentPositions + trades: RecentTrades + performance: PerformanceCharts + attribution: AttributionAnalysis + risk: RiskMetrics + } + format: 'PDF' | 'HTML' | 'JSON' + fileUrl?: string + generatedAt: Date +} +``` + +## API 명세 + +### GET /api/analytics/containers/:containerId/performance +성과 리포트 조회 + +### POST /api/analytics/containers/:containerId/reports +리포트 생성 + +## 구현 고려사항 + +- 성과 계산 시 배당/분할 조정 데이터를 일관되게 사용합니다. +- 리포트 생성은 비동기 작업으로 처리합니다. + +## 관련 문서 + +- [공통 데이터 모델](../../docs/03-data-models.md) +- [구현 로드맵](../../docs/05-roadmap.md) + +### 관련 컴포넌트 +- [data - 데이터 관리](../phase1/data.md) +- [monitor - 모니터링](./monitor.md) +- [risk - 리스크 관리](../phase1/risk.md) diff --git a/components/phase2/monitor.md b/components/phase2/monitor.md new file mode 100644 index 0000000..18af450 --- /dev/null +++ b/components/phase2/monitor.md @@ -0,0 +1,209 @@ +# monitor - 모니터링 및 알림 + +## 개요 + +**monitor** 컴포넌트는 시스템 상태 감시, 이상 탐지, 알림 발송을 담당합니다. + +### 책임 + +- 컴포넌트 헬스 체크 및 연결 상태 모니터링 +- 이상 거래/리스크 이벤트 탐지 +- 알림 규칙 관리 및 다채널 발송 +- 대시보드용 실시간 지표 제공 + +### 의존성 + +```mermaid +graph LR + Monitor[monitor] --> Balance[balance] + Monitor --> Analytics[analytics] + Monitor --> Risk[risk] + Monitor --> DB[(Database)] + + Scheduler[scheduler] --> Monitor + + style Monitor fill:#009688,color:#fff +``` + +## 주요 기능 + +### 1. 시스템 헬스 체크 + +```typescript +checkSystemHealth(): HealthStatus +monitorApiConnections(): ConnectionStatus[] +``` + +### 2. 이상 거래 탐지 + +```typescript +detectAnomalies(containerId: string): Anomaly[] +checkMarketConditions(): MarketAlert[] +``` + +### 3. 알림 관리 + +```typescript +sendAlert(alert: Alert): void +configureAlertRules(rules: AlertRule[]): void +getAlertHistory(from: Date, severity?: AlertSeverity): Alert[] +``` + +### 4. 대시보드 데이터 + +```typescript +getDashboardData(): DashboardSnapshot +getRealtimeMetrics(containerId: string): RealtimeMetrics +``` + +### 5. 성능 모니터링 + +```typescript +trackLatency(operation: string, duration: number): void +logError(error: Error, context: any): void +``` + +## 데이터 모델 + +```typescript +interface HealthStatus { + overall: 'HEALTHY' | 'DEGRADED' | 'DOWN' + components: { + name: string + status: 'UP' | 'DOWN' | 'SLOW' + responseTime?: number + lastCheck: Date + message?: string + }[] + connections: { + broker: 'CONNECTED' | 'DISCONNECTED' | 'ERROR' + database: 'CONNECTED' | 'DISCONNECTED' + dataProviders: Record + } + resources: { + cpuUsage: number + memoryUsage: number + diskUsage: number + } + checkedAt: Date +} + +interface Anomaly { + type: 'POSITION_SPIKE' | 'UNUSUAL_ORDER' | 'UNEXPECTED_FILL' | 'HIGH_IMPACT' + severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' + containerId: string + description: string + details: { + expected?: any + actual: any + threshold?: any + } + detectedAt: Date + resolved: boolean +} + +interface Alert { + id: string + type: 'SYSTEM' | 'RISK' | 'EXECUTION' | 'PERFORMANCE' | 'ANOMALY' + severity: 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL' + title: string + message: string + source: string + containerId?: string + channels: ('EMAIL' | 'SMS' | 'PUSH' | 'SLACK')[] + sentAt?: Date + acknowledged: boolean + acknowledgedAt?: Date + acknowledgedBy?: string + createdAt: Date +} + +interface AlertRule { + id: string + name: string + description: string + condition: { + metric: string + operator: '>' | '<' | '=' | '>=' | '<=' + threshold: number + } + severity: AlertSeverity + channels: AlertChannel[] + throttle: { + enabled: boolean + minIntervalMinutes: number + } + isActive: boolean +} + +interface DashboardSnapshot { + accounts: { + accountId: string + totalEquity: number + cashBalance: number + todayPnL: number + todayReturn: number + }[] + containers: { + containerId: string + name: string + status: 'ACTIVE' | 'PAUSED' + equity: number + todayReturn: number + activeStrategy: string + lastRebalanced: Date + }[] + recentExecutions: { + executionId: string + containerId: string + status: string + completedAt: Date + }[] + activeAlerts: Alert[] + systemHealth: 'HEALTHY' | 'DEGRADED' | 'DOWN' + timestamp: Date +} + +interface RealtimeMetrics { + containerId: string + current: { + equity: number + cash: number + positionsCount: number + } + today: { + pnl: number + return: number + tradesCount: number + } + risk: { + currentDrawdown: number + VaR95: number + leverage: number + } + updatedAt: Date +} +``` + +## API 명세 + +### GET /api/monitor/health +헬스 체크 상태 조회 + +### GET /api/monitor/alerts +알림 이력 조회 + +## 구현 고려사항 + +- 알림 폭주를 방지하기 위해 스로틀 정책을 필수로 둡니다. +- 심각도 기준을 명확히 정의하고 대시보드에 반영합니다. + +## 관련 문서 + +- [주요 워크플로우](../../docs/04-workflows.md) +- [구현 로드맵](../../docs/05-roadmap.md) + +### 관련 컴포넌트 +- [analytics - 성과 분석](./analytics.md) +- [risk - 리스크 관리](../phase1/risk.md) +- [balance - 계좌 관리](../phase1/balance.md) diff --git a/components/phase3/audit.md b/components/phase3/audit.md new file mode 100644 index 0000000..4ee7c44 --- /dev/null +++ b/components/phase3/audit.md @@ -0,0 +1,165 @@ +# audit - 감사 및 로깅 + +## 개요 + +**audit** 컴포넌트는 불변 감사 로그와 규제 리포팅을 담당합니다. + +### 책임 + +- 중요 이벤트 불변 저장 및 해시 체인 관리 +- 변경 이력 추적 및 감사 추적 제공 +- 규제 리포트 생성 및 데이터 экспорт +- 데이터 보존 정책 적용 및 무결성 검증 + +### 의존성 + +```mermaid +graph LR + Audit[audit] --> DB[(Database)] + Audit --> Storage[(Archive Storage)] + + Balance[balance] --> Audit + Mgmt[mgmt] --> Audit + Strategy[strategy] --> Audit + Scheduler[scheduler] --> Audit + + style Audit fill:#795548,color:#fff +``` + +## 주요 기능 + +### 1. 감사 로그 기록 + +```typescript +logEvent(event: AuditEvent): void +logOrderActivity(order: Order, action: OrderAction): void +``` + +### 2. 변경 이력 추적 + +```typescript +trackConfigChange(entity: string, entityId: string, changes: any): void +getChangeHistory(entity: string, entityId: string): ChangeLog[] +``` + +### 3. 규제 리포팅 + +```typescript +generateComplianceReport(type: ComplianceReportType, period: DateRange): ComplianceReport +exportAuditTrail(from: Date, to: Date, format: 'CSV' | 'JSON'): File +``` + +### 4. 데이터 보존 정책 + +```typescript +archiveOldData(cutoffDate: Date): ArchiveResult +retainCriticalData(dataType: string, retentionYears: number): void +``` + +### 5. 무결성 검증 + +```typescript +verifyAuditIntegrity(from: Date, to: Date): IntegrityReport +``` + +## 데이터 모델 + +```typescript +interface AuditEvent { + id: string + timestamp: Date + eventType: 'ORDER' | 'CONFIG_CHANGE' | 'EXECUTION' | 'LOGIN' | 'DATA_EXPORT' + action: string + userId?: string + containerId?: string + entity: string + entityId: string + before?: any + after?: any + metadata: { + ipAddress?: string + userAgent?: string + reason?: string + } + hash: string + previousHash?: string +} + +interface ChangeLog { + timestamp: Date + changedBy: string + field: string + oldValue: any + newValue: any + reason?: string +} + +interface ComplianceReport { + type: 'TRADE_HISTORY' | 'POSITION_STATEMENT' | 'UNUSUAL_ACTIVITY' + period: DateRange + trades: { + date: Date + orderId: string + symbol: string + side: 'BUY' | 'SELL' + quantity: number + price: number + value: number + }[] + positions: { + symbol: string + quantity: number + averagePrice: number + marketValue: number + unrealizedPnL: number + }[] + unusualActivities: { + date: Date + type: string + description: string + resolution: string + }[] + generatedAt: Date + certifiedBy?: string +} + +interface IntegrityReport { + period: DateRange + totalEvents: number + verification: { + hashChainValid: boolean + noGaps: boolean + noModifications: boolean + } + issues: { + eventId: string + issue: string + severity: 'LOW' | 'HIGH' + }[] + overall: 'PASS' | 'FAIL' + verifiedAt: Date +} +``` + +## API 명세 + +### GET /api/audit/events +감사 이벤트 조회 + +### POST /api/audit/reports +규제 리포트 생성 + +## 구현 고려사항 + +- 해시 체인 단절 방지 및 재생성 불가 정책을 문서화합니다. +- 민감 데이터 마스킹 규칙을 명확히 둡니다. + +## 관련 문서 + +- [구현 로드맵](../../docs/05-roadmap.md) +- [주요 워크플로우](../../docs/04-workflows.md) + +### 관련 컴포넌트 +- [scheduler - 실행 스케줄러](../phase1/scheduler.md) +- [balance - 계좌 관리](../phase1/balance.md) +- [risk - 리스크 관리](../phase1/risk.md) diff --git a/components/phase3/simulation.md b/components/phase3/simulation.md new file mode 100644 index 0000000..75fe17c --- /dev/null +++ b/components/phase3/simulation.md @@ -0,0 +1,207 @@ +# simulation - 시뮬레이션 환경 + +## 개요 + +**simulation** 컴포넌트는 Paper Trading, 시나리오 테스트, 파라미터 최적화를 제공하여 실전 전 검증을 지원합니다. + +### 책임 + +- Paper Trading 계좌/주문 실행 +- 전략 시뮬레이션 및 비교 +- 파라미터 최적화 및 과최적화 검증 +- 몬테카를로 및 스트레스 테스트 +- 실계좌 전환 계획 생성 + +### 의존성 + +```mermaid +graph LR + Simulation[simulation] --> Strategy[strategy] + Simulation --> Risk[risk] + Simulation --> Data[data] + Simulation --> Analytics[analytics] + Simulation --> DB[(Database)] + + Audit[audit] --> Simulation + + style Simulation fill:#607D8B,color:#fff +``` + +## 주요 기능 + +### 1. Paper Trading + +```typescript +createPaperAccount(config: PaperAccountConfig): PaperAccount +executePaperTrade(order: Order): PaperOrderResult +``` + +### 2. 전략 시뮬레이션 + +```typescript +runSimulation(config: SimulationConfig): SimulationResult +compareStrategies(strategyIds: string[], config: SimulationConfig): ComparisonResult +``` + +### 3. 파라미터 최적화 + +```typescript +optimizeParameters(strategyId: string, searchSpace: ParameterSpace): OptimizationResult +validateOptimization(result: OptimizationResult, outOfSampleData: MarketData): ValidationResult +``` + +### 4. 시나리오 테스트 + +```typescript +testScenario(containerId: string, scenario: Scenario): ScenarioResult +runMonteCarloSimulation(containerId: string, iterations: number): MonteCarloResult +``` + +### 5. 전환 지원 + +```typescript +promoteToProd(paperAccountId: string, realAccountId: string): MigrationPlan +cloneContainer(sourceId: string, targetAccountId: string): Container +``` + +## 데이터 모델 + +```typescript +interface PaperAccount { + id: string + name: string + balance: { + initialCash: number + currentCash: number + positions: Position[] + totalEquity: number + } + settings: { + commissionModel: 'FIXED' | 'PERCENTAGE' + commissionRate: number + slippageModel: 'FIXED_BPS' | 'VOLUME_BASED' + slippageBps: number + } + isActive: boolean + createdAt: Date +} + +interface SimulationConfig { + strategyId: string + startDate: Date + endDate: Date + initialCapital: number + universe: string[] + costs: { + commission: number + slippage: number + tax: number + } + constraints: RiskLimits + rebalanceFrequency: string +} + +interface SimulationResult { + config: SimulationConfig + performance: PerformanceMetrics + equity: { + date: Date + value: number + }[] + trades: { + date: Date + symbol: string + action: 'BUY' | 'SELL' + quantity: number + price: number + }[] + drawdowns: { + start: Date + end: Date + depth: number + recovery: number + }[] + completedAt: Date +} + +interface ParameterSpace { + parameters: { + name: string + type: 'INTEGER' | 'FLOAT' | 'CATEGORICAL' + min?: number + max?: number + step?: number + values?: any[] + }[] +} + +interface OptimizationResult { + strategyId: string + searchSpace: ParameterSpace + bestParameters: Record + bestMetric: number + trials: { + parameters: Record + metrics: PerformanceMetrics + }[] + optimizationTime: number + warnings: { + overfitting: boolean + insufficientData: boolean + unstableParameters: string[] + } +} + +interface MonteCarloResult { + iterations: number + returns: { + mean: number + median: number + std: number + percentiles: { + p5: number + p25: number + p75: number + p95: number + } + } + drawdowns: { + mean: number + max: number + percentiles: { + p95: number + p99: number + } + } + probabilities: { + profit: number + loss10pct: number + loss20pct: number + } + distribution: number[] +} +``` + +## API 명세 + +### POST /api/simulation/run +시뮬레이션 실행 + +### POST /api/simulation/optimize +파라미터 최적화 + +## 구현 고려사항 + +- 과최적화 경고 기준을 명확히 정의합니다. +- Paper Trading과 실계좌 체결 차이를 리포트에 표시합니다. + +## 관련 문서 + +- [구현 로드맵](../../docs/05-roadmap.md) +- [주요 워크플로우](../../docs/04-workflows.md) + +### 관련 컴포넌트 +- [strategy - 전략 관리](../phase1/strategy.md) +- [risk - 리스크 관리](../phase1/risk.md) +- [analytics - 성과 분석](../phase2/analytics.md) +- [audit - 감사 및 로깅](./audit.md) diff --git a/diagram.md b/diagram.md new file mode 100644 index 0000000..775043b --- /dev/null +++ b/diagram.md @@ -0,0 +1,616 @@ +# QuantBench System Architecture - Mermaid Diagrams + +## 1. 전체 시스템 아키텍처 (All Phases) + +```mermaid +graph TB + subgraph "User Layer" + UI[User Interface
Web/Mobile/Desktop] + end + + subgraph "API Layer" + Gateway[API Gateway
Authentication & Rate Limiting] + end + + subgraph "Phase 1 - Core Components" + Balance[balance
계좌 관리] + Mgmt[mgmt
컨테이너 관리] + Strategy[strategy
전략 관리] + Scheduler[scheduler
실행 스케줄러] + Risk[risk
리스크 관리] + Data[data
데이터 관리] + end + + subgraph "Phase 2 - Production Ready" + Analytics[analytics
성과 분석] + Monitor[monitor
모니터링 & 알림] + end + + subgraph "Phase 3 - Enterprise Grade" + Audit[audit
감사 로깅] + Simulation[simulation
시뮬레이션] + end + + subgraph "Infrastructure" + MQ[Message Queue
Kafka/RabbitMQ] + DB[(Database
PostgreSQL)] + Cache[(Cache
Redis)] + Storage[(Object Storage
S3)] + end + + subgraph "External Systems" + Broker1[한국투자증권 API] + Broker2[삼성증권 API] + Broker3[키움증권 API] + DataProvider[Data Providers
Yahoo/Alpha Vantage] + end + + UI --> Gateway + Gateway --> Mgmt + Gateway --> Strategy + Gateway --> Scheduler + Gateway --> Analytics + Gateway --> Monitor + Gateway --> Simulation + + Scheduler --> Strategy + Scheduler --> Mgmt + Scheduler --> Risk + Scheduler --> Balance + + Strategy --> Data + Strategy --> Risk + + Mgmt --> Balance + Mgmt --> Risk + + Analytics --> Mgmt + Analytics --> Data + + Monitor --> Mgmt + Monitor --> Balance + Monitor --> Scheduler + + Simulation --> Strategy + Simulation --> Data + Simulation --> Risk + + Audit -.-> Mgmt + Audit -.-> Strategy + Audit -.-> Scheduler + Audit -.-> Balance + + Balance --> Broker1 + Balance --> Broker2 + Balance --> Broker3 + + Data --> DataProvider + Data --> Broker1 + + Mgmt --> DB + Strategy --> DB + Analytics --> DB + Audit --> DB + + Data --> Cache + Monitor --> Cache + + Analytics --> Storage + Audit --> Storage + + Scheduler --> MQ + Monitor --> MQ + + style Balance fill:#e1f5ff + style Mgmt fill:#e1f5ff + style Strategy fill:#e1f5ff + style Scheduler fill:#e1f5ff + style Risk fill:#e1f5ff + style Data fill:#e1f5ff + + style Analytics fill:#fff4e1 + style Monitor fill:#fff4e1 + + style Audit fill:#f0e1ff + style Simulation fill:#f0e1ff +``` + +## 2. Phase 1 컴포넌트 관계도 + +```mermaid +graph LR + subgraph "Phase 1: MVP" + subgraph "Core Trading" + Mgmt[mgmt
컨테이너 관리] + Strategy[strategy
전략 엔진] + Scheduler[scheduler
스케줄러] + end + + subgraph "Safety & Control" + Risk[risk
리스크 관리] + Data[data
데이터 수집] + end + + subgraph "Broker Integration" + Balance[balance
계좌 연동] + end + end + + Scheduler -->|1. 트리거| Strategy + Strategy -->|2. 신호 생성| Risk + Risk -->|3. 검증 통과| Scheduler + Scheduler -->|4. 주문 생성| Balance + Balance -->|5. 체결 결과| Mgmt + + Strategy -->|시세 조회| Data + Risk -->|리스크 데이터| Data + Mgmt -->|자산 할당| Balance + + style Mgmt fill:#4CAF50,color:#fff + style Strategy fill:#2196F3,color:#fff + style Scheduler fill:#FF9800,color:#fff + style Risk fill:#F44336,color:#fff + style Data fill:#9C27B0,color:#fff + style Balance fill:#00BCD4,color:#fff +``` + +## 3. 전체 Phase별 구성 + +```mermaid +graph TB + subgraph "Phase 3: Enterprise Grade" + P3_1[audit
감사 추적] + P3_2[simulation
Paper Trading] + end + + subgraph "Phase 2: Production Ready" + P2_1[analytics
성과 분석] + P2_2[monitor
모니터링] + end + + subgraph "Phase 1: MVP" + P1_1[balance
계좌 관리] + P1_2[mgmt
컨테이너] + P1_3[strategy
전략] + P1_4[scheduler
스케줄러] + P1_5[risk
리스크] + P1_6[data
데이터] + end + + P1_1 --> P2_1 + P1_2 --> P2_1 + P1_3 --> P2_1 + P1_6 --> P2_1 + + P1_1 --> P2_2 + P1_2 --> P2_2 + P1_4 --> P2_2 + + P2_1 --> P3_1 + P1_4 --> P3_1 + P1_1 --> P3_1 + + P1_3 --> P3_2 + P1_6 --> P3_2 + P1_5 --> P3_2 + + style P1_1 fill:#e3f2fd + style P1_2 fill:#e3f2fd + style P1_3 fill:#e3f2fd + style P1_4 fill:#e3f2fd + style P1_5 fill:#e3f2fd + style P1_6 fill:#e3f2fd + + style P2_1 fill:#fff9c4 + style P2_2 fill:#fff9c4 + + style P3_1 fill:#f3e5f5 + style P3_2 fill:#f3e5f5 +``` + +## 4. 전략 실행 워크플로우 (Sequence Diagram) + +```mermaid +sequenceDiagram + participant S as Scheduler + participant M as Mgmt + participant ST as Strategy + participant D as Data + participant R as Risk + participant B as Balance + participant A as Analytics + participant MO as Monitor + + Note over S: 스케줄 트리거 발생 + + S->>M: 1. 컨테이너 정보 조회 + M-->>S: 컨테이너 설정 & 현재 포지션 + + S->>ST: 2. 전략 실행 요청 + ST->>D: 2.1 시장 데이터 조회 + D-->>ST: 최신 시세 데이터 + ST->>ST: 2.2 신호 생성 + ST-->>S: 매매 신호 반환 + + S->>R: 3. 리스크 체크 + R->>R: 3.1 포지션 사이즈 검증 + R->>R: 3.2 VaR 계산 + R->>R: 3.3 한도 확인 + + alt 리스크 체크 실패 + R-->>S: 검증 실패 + S->>MO: 알림 발송 + MO-->>S: 알림 완료 + Note over S: 실행 중단 + else 리스크 체크 통과 + R-->>S: 검증 통과 + + alt 승인 필요 모드 + S->>S: 승인 요청 생성 + S->>MO: 사용자에게 알림 + Note over S: 사용자 승인 대기 + S->>S: 승인 완료 + end + + S->>B: 4. 주문 제출 + B->>B: 4.1 증권사 API 호출 + B-->>S: 주문 접수 완료 + + Note over B: 체결 대기... + + B->>B: 4.2 체결 확인 + B->>M: 5. 포지션 업데이트 + M->>M: 5.1 컨테이너 밸런스 갱신 + + M->>A: 6. 성과 계산 트리거 + A->>A: 6.1 수익률 계산 + A->>A: 6.2 리스크 지표 갱신 + + A->>MO: 7. 메트릭 업데이트 + MO->>MO: 7.1 대시보드 갱신 + MO->>MO: 7.2 이상 탐지 + + alt 이상 탐지 시 + MO->>MO: 알림 발송 + end + + S->>S: 8. 실행 완료 기록 + end +``` + +## 5. 리스크 관리 플로우 + +```mermaid +graph TB + Start([주문 요청]) --> GetPosition[현재 포지션 조회] + GetPosition --> CalcNewPosition[신규 포지션 계산] + + CalcNewPosition --> CheckBalance{잔고 충분?} + CheckBalance -->|No| Reject1[주문 거부:
잔고 부족] + CheckBalance -->|Yes| CheckSize + + CheckSize{포지션 사이즈
한도 내?} + CheckSize -->|No| Reject2[주문 거부:
사이즈 초과] + CheckSize -->|Yes| CheckConcentration + + CheckConcentration{집중도
한도 내?} + CheckConcentration -->|No| Reject3[주문 거부:
집중도 초과] + CheckConcentration -->|Yes| CalcVaR + + CalcVaR[VaR 계산] + CalcVaR --> CheckVaR{VaR
한도 내?} + CheckVaR -->|No| Warning1[경고 발생
계속 진행] + CheckVaR -->|Yes| CheckDrawdown + + Warning1 --> CheckDrawdown + + CheckDrawdown{최대 낙폭
한도 내?} + CheckDrawdown -->|No| Reject4[주문 거부:
MDD 초과] + CheckDrawdown -->|Yes| CheckLeverage + + CheckLeverage{레버리지
한도 내?} + CheckLeverage -->|No| Reject5[주문 거부:
레버리지 초과] + CheckLeverage -->|Yes| Approve + + Approve([검증 통과:
주문 실행]) + + Reject1 --> Log[리스크 로그 기록] + Reject2 --> Log + Reject3 --> Log + Reject4 --> Log + Reject5 --> Log + + Approve --> ExecuteOrder[주문 제출] + ExecuteOrder --> Monitor[실시간 모니터링] + + Monitor --> CheckStop{손절/익절
조건 충족?} + CheckStop -->|Yes| AutoClose[자동 청산] + CheckStop -->|No| Monitor + + style Start fill:#4CAF50,color:#fff + style Approve fill:#4CAF50,color:#fff + style Reject1 fill:#F44336,color:#fff + style Reject2 fill:#F44336,color:#fff + style Reject3 fill:#F44336,color:#fff + style Reject4 fill:#F44336,color:#fff + style Reject5 fill:#F44336,color:#fff + style Warning1 fill:#FF9800,color:#fff +``` + +## 6. 데이터 흐름도 + +```mermaid +graph LR + subgraph "External Sources" + Broker[증권사 API] + YahooAPI[Yahoo Finance] + AlphaAPI[Alpha Vantage] + end + + subgraph "Data Collection" + Collector[Data Collector] + RealTime[Real-time Stream] + Historical[Historical Fetch] + end + + subgraph "Data Processing" + Validator[Data Validator] + Adjuster[Corporate Action Adjuster] + QualityCheck[Quality Check] + end + + subgraph "Storage" + Cache[(Redis Cache
실시간 시세)] + TimeSeries[(Time Series DB
과거 데이터)] + Metadata[(Metadata DB
종목 정보)] + end + + subgraph "Consumers" + Strategy[Strategy Engine] + Backtest[Backtest Engine] + Analytics[Analytics] + Monitor[Monitor] + end + + Broker --> RealTime + YahooAPI --> Historical + AlphaAPI --> Historical + + RealTime --> Collector + Historical --> Collector + + Collector --> Validator + Validator --> QualityCheck + QualityCheck -->|Pass| Adjuster + QualityCheck -->|Fail| Alert[Quality Alert] + + Adjuster --> Cache + Adjuster --> TimeSeries + Adjuster --> Metadata + + Cache --> Strategy + Cache --> Monitor + + TimeSeries --> Backtest + TimeSeries --> Analytics + + Metadata --> Strategy + + style Cache fill:#FF6B6B,color:#fff + style TimeSeries fill:#4ECDC4,color:#fff + style Metadata fill:#45B7D1,color:#fff +``` + +## 7. 컨테이너 생명주기 + +```mermaid +stateDiagram-v2 + [*] --> Created: createContainer() + + Created --> Active: activate() + Created --> [*]: delete() + + Active --> Running: scheduler trigger + Active --> Paused: pause() + Active --> [*]: delete() + + Running --> Active: execution complete + Running --> Error: execution failed + Running --> Paused: emergency stop + + Paused --> Active: resume() + Paused --> [*]: delete() + + Error --> Active: resolve & restart + Error --> Paused: manual intervention + Error --> [*]: delete() + + state Running { + [*] --> GenerateSignals + GenerateSignals --> RiskCheck + RiskCheck --> PlaceOrders: pass + RiskCheck --> [*]: fail + PlaceOrders --> AwaitFill + AwaitFill --> UpdatePosition + UpdatePosition --> [*] + } +``` + +## 8. 승인 워크플로우 + +```mermaid +graph TB + Trigger[스케줄 트리거] --> GenerateSignals[신호 생성] + GenerateSignals --> RiskCheck[리스크 체크] + + RiskCheck --> CheckMode{실행 모드} + + CheckMode -->|AUTO| AutoExecute[자동 실행] + CheckMode -->|APPROVAL| CreateRequest + + CreateRequest[승인 요청 생성] + CreateRequest --> SendNotification[알림 발송] + SendNotification --> WaitApproval[승인 대기] + + WaitApproval --> CheckTimeout{타임아웃?} + CheckTimeout -->|Yes| Expired[요청 만료] + CheckTimeout -->|No| WaitApproval + + WaitApproval --> UserDecision{사용자 결정} + + UserDecision -->|승인| Execute[주문 실행] + UserDecision -->|거부| Rejected[실행 거부] + + AutoExecute --> Execute + + Execute --> PlaceOrders[주문 제출] + PlaceOrders --> Success{성공?} + + Success -->|Yes| NotifySuccess[성공 알림] + Success -->|No| NotifyFail[실패 알림] + + Rejected --> LogRejection[거부 로그] + Expired --> LogExpired[만료 로그] + + NotifySuccess --> End([완료]) + NotifyFail --> End + LogRejection --> End + LogExpired --> End + + style Execute fill:#4CAF50,color:#fff + style Rejected fill:#F44336,color:#fff + style Expired fill:#FF9800,color:#fff + style AutoExecute fill:#2196F3,color:#fff +``` + +## 9. 모니터링 & 알림 시스템 + +```mermaid +graph TB + subgraph "Data Sources" + Positions[포지션 데이터] + Orders[주문 데이터] + PnL[손익 데이터] + System[시스템 메트릭] + end + + subgraph "Monitoring Engine" + Collector[Metrics Collector] + Anomaly[Anomaly Detector] + Health[Health Checker] + Rules[Alert Rules Engine] + end + + subgraph "Alert Processing" + Evaluator[Alert Evaluator] + Throttle[Throttle Manager] + Router[Channel Router] + end + + subgraph "Notification Channels" + Email[Email] + SMS[SMS] + Push[Push Notification] + Slack[Slack] + end + + subgraph "Storage & Dashboard" + Metrics[(Metrics DB)] + Dashboard[Real-time Dashboard] + History[Alert History] + end + + Positions --> Collector + Orders --> Collector + PnL --> Collector + System --> Collector + + Collector --> Anomaly + Collector --> Health + Collector --> Rules + Collector --> Metrics + + Anomaly --> Evaluator + Health --> Evaluator + Rules --> Evaluator + + Evaluator --> Throttle + Throttle --> Router + + Router --> Email + Router --> SMS + Router --> Push + Router --> Slack + + Evaluator --> History + Metrics --> Dashboard + + style Anomaly fill:#F44336,color:#fff + style Health fill:#4CAF50,color:#fff + style Rules fill:#FF9800,color:#fff +``` + +## 10. Simulation 환경 구조 + +```mermaid +graph TB + subgraph "Real Environment" + RealAccount[실제 계좌] + RealBroker[증권사 API] + RealData[실시간 시세] + end + + subgraph "Simulation Environment" + PaperAccount[가상 계좌] + + subgraph "Simulation Engine" + OrderSim[주문 시뮬레이터] + FillSim[체결 시뮬레이터] + Slippage[슬리피지 모델] + Commission[수수료 계산] + end + + subgraph "Test Scenarios" + Historical[과거 데이터 리플레이] + MonteCarlo[몬테카를로 시뮬레이션] + Stress[스트레스 테스트] + end + end + + subgraph "Shared Components" + Strategy[전략 엔진] + Risk[리스크 관리] + Analytics[성과 분석] + end + + RealData --> Historical + RealData --> OrderSim + + Strategy --> OrderSim + Strategy --> RealBroker + + OrderSim --> FillSim + FillSim --> Slippage + Slippage --> Commission + Commission --> PaperAccount + + Historical --> MonteCarlo + Historical --> Stress + + PaperAccount --> Analytics + RealAccount --> Analytics + + Risk --> OrderSim + Risk --> RealBroker + + Analytics --> Validation{검증 통과?} + Validation -->|Yes| Promote[실계좌 전환] + Validation -->|No| Refine[전략 개선] + + Promote --> RealAccount + Refine --> Strategy + + style PaperAccount fill:#FFF9C4 + style RealAccount fill:#C8E6C9 + style Validation fill:#FF9800,color:#fff +``` diff --git a/docs/01-overview.md b/docs/01-overview.md new file mode 100644 index 0000000..f64f33f --- /dev/null +++ b/docs/01-overview.md @@ -0,0 +1,279 @@ +# QuantBench 시스템 개요 + +## 1. 프로젝트 소개 + +**QuantBench**는 개인 투자자를 위한 퀀트 트레이딩 플랫폼으로, 다중 계좌 관리, 전략 기반 자동매매, 리스크 관리, 성과 분석을 통합 제공합니다. + +### 핵심 가치 제안 + +- **다중 계좌 통합 관리**: 한국투자증권, 삼성증권, 키움증권 등 여러 증권사 계좌를 하나의 플랫폼에서 관리 +- **컨테이너 기반 자산 격리**: 하나의 계좌에서 여러 전략을 안전하게 병렬 운영 +- **전략 자동화**: 백테스트부터 실전 운영까지 일관된 전략 실행 환경 +- **리스크 우선 설계**: 사전 주문 검증 및 실시간 리스크 모니터링 +- **투명한 성과 분석**: 실시간 성과 추적 및 귀속 분석 + +## 2. 주요 기능 + +### 2.1 계좌 및 자산 관리 + +```mermaid +graph LR + A[투자자] --> B[QuantBench] + B --> C[한국투자증권] + B --> D[삼성증권] + B --> E[키움증권] + + B --> F[컨테이너 1
성장주 전략] + B --> G[컨테이너 2
배당주 전략] + B --> H[컨테이너 3
ETF 전략] + + style F fill:#e3f2fd + style G fill:#e3f2fd + style H fill:#e3f2fd +``` + +- 여러 증권사 계좌 통합 관리 +- 계좌 내 가상 컨테이너 생성으로 전략별 자산 격리 +- 실시간 잔고 조회 및 포지션 추적 +- 컨테이너 간 자산 이동 및 재배분 + +### 2.2 전략 실행 + +- **전략 등록 및 버전 관리**: 전략 코드 및 파라미터의 버전별 관리 +- **백테스트**: 과거 데이터 기반 전략 검증 및 성과 분석 +- **자동 실행**: 스케줄 기반 자동 매매 신호 생성 및 주문 실행 +- **승인 워크플로우**: 자동 실행 또는 사용자 승인 후 실행 선택 + +### 2.3 리스크 관리 + +- **사전 주문 검증**: 모든 주문의 리스크 사전 체크 +- **포지션 한도 관리**: 단일 종목, 섹터, 총 익스포저 제한 +- **손절/익절 자동화**: 조건 기반 자동 청산 +- **VaR 계산**: 포트폴리오 리스크 정량화 +- **스트레스 테스트**: 극단 시나리오 대비 + +### 2.4 성과 분석 및 모니터링 + +- **실시간 성과 추적**: 수익률, 리스크 지표 실시간 업데이트 +- **귀속 분석**: 수익 원천 분해 (자산 배분, 종목 선택, 타이밍) +- **벤치마크 비교**: 시장 지수 대비 성과 분석 +- **이상 탐지**: 비정상 거래 및 리스크 이벤트 자동 감지 +- **다채널 알림**: 이메일, SMS, 푸시, Slack 알림 + +## 3. 핵심 개념 + +### 3.1 컨테이너 (Container) + +컨테이너는 **하나의 실제 계좌 내에서 가상으로 분리된 자산 공간**입니다. + +```mermaid +graph TB + subgraph "실제 계좌 (1억원)" + subgraph "컨테이너 A (3천만원)" + A1[현금: 500만원] + A2[삼성전자: 2500만원] + end + + subgraph "컨테이너 B (5천만원)" + B1[현금: 1000만원] + B2[KODEX 200: 4000만원] + end + + subgraph "컨테이너 C (2천만원)" + C1[현금: 2000만원] + end + end + + style A1 fill:#fff9c4 + style A2 fill:#c8e6c9 + style B1 fill:#fff9c4 + style B2 fill:#c8e6c9 + style C1 fill:#fff9c4 +``` + +**특징**: +- 각 컨테이너는 독립적인 가상 잔고를 유지 +- 하나의 컨테이너에 하나의 전략 할당 +- 컨테이너별 독립적인 리스크 한도 설정 +- 실제 계좌 잔고 = 모든 컨테이너 잔고의 합 + +**장점**: +- 전략 간 간섭 없이 병렬 운영 +- 전략별 성과를 명확히 추적 +- 리스크를 전략 단위로 통제 + +### 3.2 전략 (Strategy) + +전략은 **매매 신호를 생성하는 알고리즘**입니다. + +```mermaid +graph LR + A[시장 데이터] --> B[전략 엔진] + B --> C[매매 신호] + C --> D{리스크 체크} + D -->|통과| E[주문 실행] + D -->|실패| F[실행 중단] + + style B fill:#2196f3,color:#fff + style D fill:#f44336,color:#fff + style E fill:#4caf50,color:#fff +``` + +**구성 요소**: +- **전략 코드**: 신호 생성 로직 구현 +- **파라미터**: 전략 동작을 조정하는 변수들 +- **버전**: 전략 수정 이력 관리 +- **백테스트 결과**: 과거 성과 검증 데이터 + +**내장 전략 예시**: +- Bold Asset Allocation: 주식/채권 고정 비중 전략 +- Momentum: 모멘텀 기반 종목 선택 +- Value: 가치 지표 기반 매매 + +### 3.3 워크플로우 (Workflow) + +```mermaid +sequenceDiagram + participant 스케줄러 + participant 전략 + participant 리스크 + participant 증권사 + participant 사용자 + + 스케줄러->>전략: 신호 생성 요청 + 전략-->>스케줄러: 매매 신호 + 스케줄러->>리스크: 리스크 검증 + + alt 리스크 통과 + 리스크-->>스케줄러: 승인 + + alt 자동 실행 모드 + 스케줄러->>증권사: 주문 제출 + else 승인 필요 모드 + 스케줄러->>사용자: 승인 요청 + 사용자-->>스케줄러: 승인 + 스케줄러->>증권사: 주문 제출 + end + + 증권사-->>스케줄러: 체결 완료 + else 리스크 실패 + 리스크-->>스케줄러: 거부 + 스케줄러->>사용자: 실패 알림 + end +``` + +## 4. 개발 단계 + +### Phase 1: MVP (3-4개월) + +**목표**: 안전하게 전략을 실행하고 리스크를 통제할 수 있는 기본 시스템 구축 + +**핵심 컴포넌트**: +- `balance`: 증권사 API 연동 및 계좌 관리 +- `mgmt`: 컨테이너 생명주기 관리 +- `strategy`: 전략 실행 및 백테스트 +- `scheduler`: 자동 실행 스케줄링 +- `risk`: 사전 주문 검증 +- `data`: 시장 데이터 수집 및 관리 + +**핵심 기능**: +- 1개 증권사 연동 (한국투자증권 우선) +- 기본 전략 실행 (Bold Asset Allocation) +- 주문 전 리스크 체크 +- 수동 승인 워크플로우 + +### Phase 2: Production Ready (2-3개월) + +**목표**: 실전 운영을 위한 모니터링, 분석, 알림 체계 구축 + +**추가 컴포넌트**: +- `analytics`: 성과 분석 및 리포팅 +- `monitor`: 시스템 모니터링 및 알림 + +**핵심 기능**: +- 실시간 성과 대시보드 +- 자동 리포트 생성 (일/주/월) +- 이상 거래 탐지 +- 다채널 알림 시스템 + +### Phase 3: Enterprise Grade (2-3개월) + +**목표**: 규제 대응, 감사 추적, 고급 시뮬레이션 + +**추가 컴포넌트**: +- `audit`: 불변 감사 로그 +- `simulation`: Paper Trading 및 시뮬레이션 + +**핵심 기능**: +- 모든 거래의 감사 추적 +- Paper Trading 환경 +- 파라미터 최적화 +- 스트레스 테스트 + +## 5. 기술 스택 + +### 백엔드 +- **언어**: TypeScript/Node.js 또는 Python +- **데이터베이스**: PostgreSQL (관계형), TimescaleDB (시계열) +- **캐시**: Redis +- **메시지 큐**: Kafka 또는 RabbitMQ +- **스토리지**: AWS S3 또는 MinIO + +### 프론트엔드 +- **프레임워크**: React 또는 Next.js +- **차트**: TradingView, Chart.js +- **상태 관리**: Redux 또는 Zustand + +### 인프라 +- **컨테이너**: Docker +- **오케스트레이션**: Kubernetes (선택) +- **모니터링**: Prometheus + Grafana +- **로깅**: ELK Stack (Elasticsearch, Logstash, Kibana) + +## 6. 비기능 요구사항 + +### 6.1 성능 +- 주문 처리 지연시간: < 1초 +- 백테스트 속도: 1년 데이터 < 10초 +- 실시간 데이터 업데이트: < 5초 + +### 6.2 안정성 +- 시스템 가용성: 99.9% (장중 시간 기준) +- 데이터 정합성: 100% (계좌 잔고 일치) +- 주문 실패 복구: 자동 재시도 및 알림 + +### 6.3 보안 +- API 키 암호화 저장 +- 통신 TLS 암호화 +- 역할 기반 접근 제어 (RBAC) +- 감사 로그 불변성 보장 + +### 6.4 확장성 +- 다중 증권사 지원 (플러그인 아키텍처) +- 수평 확장 가능한 데이터 처리 +- 무제한 컨테이너/전략 생성 + +## 7. 관련 문서 + +- [전체 아키텍처](./02-architecture.md) +- [공통 데이터 모델](./03-data-models.md) +- [주요 워크플로우](./04-workflows.md) +- [구현 로드맵](./05-roadmap.md) + +### 구성요소 상세 문서 + +**Phase 1**: +- [balance - 계좌 관리](../components/phase1/balance.md) +- [mgmt - 컨테이너 관리](../components/phase1/mgmt.md) +- [strategy - 전략 관리](../components/phase1/strategy.md) +- [scheduler - 실행 스케줄러](../components/phase1/scheduler.md) +- [risk - 리스크 관리](../components/phase1/risk.md) +- [data - 데이터 관리](../components/phase1/data.md) + +**Phase 2**: +- [analytics - 성과 분석](../components/phase2/analytics.md) +- [monitor - 모니터링](../components/phase2/monitor.md) + +**Phase 3**: +- [audit - 감사 로깅](../components/phase3/audit.md) +- [simulation - 시뮬레이션](../components/phase3/simulation.md) diff --git a/docs/02-architecture.md b/docs/02-architecture.md new file mode 100644 index 0000000..e67a19d --- /dev/null +++ b/docs/02-architecture.md @@ -0,0 +1,592 @@ +# QuantBench 시스템 아키텍처 + +## 1. 전체 시스템 구조 + +```mermaid +graph TB + subgraph "사용자 레이어" + UI[사용자 인터페이스
Web/Mobile/Desktop] + end + + subgraph "API 레이어" + Gateway[API Gateway
인증 & Rate Limiting] + end + + subgraph "Phase 1: 핵심 컴포넌트" + Balance[balance
계좌 관리] + Mgmt[mgmt
컨테이너 관리] + Strategy[strategy
전략 관리] + Scheduler[scheduler
실행 스케줄러] + Risk[risk
리스크 관리] + Data[data
데이터 관리] + end + + subgraph "Phase 2: 프로덕션" + Analytics[analytics
성과 분석] + Monitor[monitor
모니터링 & 알림] + end + + subgraph "Phase 3: 엔터프라이즈" + Audit[audit
감사 로깅] + Simulation[simulation
시뮬레이션] + end + + subgraph "인프라" + MQ[Message Queue
Kafka/RabbitMQ] + DB[(Database
PostgreSQL)] + Cache[(Cache
Redis)] + Storage[(Object Storage
S3)] + end + + subgraph "외부 시스템" + Broker1[한국투자증권 API] + Broker2[삼성증권 API] + Broker3[키움증권 API] + DataProvider[데이터 제공자
Yahoo/Alpha Vantage] + end + + UI --> Gateway + Gateway --> Mgmt + Gateway --> Strategy + Gateway --> Scheduler + Gateway --> Analytics + Gateway --> Monitor + Gateway --> Simulation + + Scheduler --> Strategy + Scheduler --> Mgmt + Scheduler --> Risk + Scheduler --> Balance + + Strategy --> Data + Strategy --> Risk + + Mgmt --> Balance + Mgmt --> Risk + + Analytics --> Mgmt + Analytics --> Data + + Monitor --> Mgmt + Monitor --> Balance + Monitor --> Scheduler + + Simulation --> Strategy + Simulation --> Data + Simulation --> Risk + + Audit -.-> Mgmt + Audit -.-> Strategy + Audit -.-> Scheduler + Audit -.-> Balance + + Balance --> Broker1 + Balance --> Broker2 + Balance --> Broker3 + + Data --> DataProvider + Data --> Broker1 + + Mgmt --> DB + Strategy --> DB + Analytics --> DB + Audit --> DB + + Data --> Cache + Monitor --> Cache + + Analytics --> Storage + Audit --> Storage + + Scheduler --> MQ + Monitor --> MQ + + style Balance fill:#e1f5ff + style Mgmt fill:#e1f5ff + style Strategy fill:#e1f5ff + style Scheduler fill:#e1f5ff + style Risk fill:#e1f5ff + style Data fill:#e1f5ff + + style Analytics fill:#fff4e1 + style Monitor fill:#fff4e1 + + style Audit fill:#f0e1ff + style Simulation fill:#f0e1ff +``` + +## 2. 컴포넌트 개요 + +### 2.1 Phase 1: 핵심 컴포넌트 + +| 컴포넌트 | 책임 | 주요 기능 | +|---------|------|----------| +| **balance** | 증권사 API 통합 및 계좌 자산 관리 | 계좌 연동, 잔고 조회, 시세 조회, 주문 처리 | +| **mgmt** | 가상 자산 컨테이너 생성 및 운영 관리 | 컨테이너 생명주기, 자산 격리, 밸런스 조정 | +| **strategy** | 투자 전략 구현, 백테스트, 버전 관리 | 전략 등록, 신호 생성, 백테스트, 파라미터 관리 | +| **scheduler** | 전략 실행 자동화 및 리밸런싱 관리 | 스케줄 관리, 실행 트리거, 승인 워크플로우 | +| **risk** | 포지션 리스크 통제 및 사전 주문 검증 | 주문 검증, 리스크 모니터링, 손절/익절 | +| **data** | 시계열 데이터 수집, 저장, 제공 | 데이터 수집, 품질 관리, 데이터 제공 | + +### 2.2 Phase 2: 프로덕션 컴포넌트 + +| 컴포넌트 | 책임 | 주요 기능 | +|---------|------|----------| +| **analytics** | 실거래 성과 측정 및 리포팅 | 성과 측정, 귀속 분석, 거래 분석, 리포트 생성 | +| **monitor** | 시스템 상태 감시 및 이상 탐지 | 헬스 체크, 이상 탐지, 알림 관리, 대시보드 | + +### 2.3 Phase 3: 엔터프라이즈 컴포넌트 + +| 컴포넌트 | 책임 | 주요 기능 | +|---------|------|----------| +| **audit** | 불변 감사 로그 및 규제 리포팅 | 감사 로그, 변경 추적, 규제 리포팅, 무결성 검증 | +| **simulation** | 실전 배포 전 안전한 테스트 환경 제공 | Paper Trading, 시뮬레이션, 파라미터 최적화 | + +## 3. 컴포넌트 상호작용 + +### 3.1 Phase 1 컴포넌트 관계도 + +```mermaid +graph LR + subgraph "Phase 1: MVP" + subgraph "핵심 거래" + Mgmt[mgmt
컨테이너 관리] + Strategy[strategy
전략 엔진] + Scheduler[scheduler
스케줄러] + end + + subgraph "안전성 & 통제" + Risk[risk
리스크 관리] + Data[data
데이터 수집] + end + + subgraph "증권사 연동" + Balance[balance
계좌 연동] + end + end + + Scheduler -->|1. 트리거| Strategy + Strategy -->|2. 신호 생성| Risk + Risk -->|3. 검증 통과| Scheduler + Scheduler -->|4. 주문 생성| Balance + Balance -->|5. 체결 결과| Mgmt + + Strategy -->|시세 조회| Data + Risk -->|리스크 데이터| Data + Mgmt -->|자산 할당| Balance + + style Mgmt fill:#4CAF50,color:#fff + style Strategy fill:#2196F3,color:#fff + style Scheduler fill:#FF9800,color:#fff + style Risk fill:#F44336,color:#fff + style Data fill:#9C27B0,color:#fff + style Balance fill:#00BCD4,color:#fff +``` + +### 3.2 Phase별 의존성 + +```mermaid +graph TB + subgraph "Phase 3: Enterprise" + P3_1[audit
감사] + P3_2[simulation
시뮬레이션] + end + + subgraph "Phase 2: Production" + P2_1[analytics
분석] + P2_2[monitor
모니터링] + end + + subgraph "Phase 1: MVP" + P1_1[balance
계좌] + P1_2[mgmt
컨테이너] + P1_3[strategy
전략] + P1_4[scheduler
스케줄러] + P1_5[risk
리스크] + P1_6[data
데이터] + end + + P1_1 --> P2_1 + P1_2 --> P2_1 + P1_3 --> P2_1 + P1_6 --> P2_1 + + P1_1 --> P2_2 + P1_2 --> P2_2 + P1_4 --> P2_2 + + P2_1 --> P3_1 + P1_4 --> P3_1 + P1_1 --> P3_1 + + P1_3 --> P3_2 + P1_6 --> P3_2 + P1_5 --> P3_2 + + style P1_1 fill:#e3f2fd + style P1_2 fill:#e3f2fd + style P1_3 fill:#e3f2fd + style P1_4 fill:#e3f2fd + style P1_5 fill:#e3f2fd + style P1_6 fill:#e3f2fd + + style P2_1 fill:#fff9c4 + style P2_2 fill:#fff9c4 + + style P3_1 fill:#f3e5f5 + style P3_2 fill:#f3e5f5 +``` + +## 4. 데이터 흐름 + +### 4.1 시장 데이터 흐름 + +```mermaid +graph LR + subgraph "외부 소스" + Broker[증권사 API] + Yahoo[Yahoo Finance] + Alpha[Alpha Vantage] + end + + subgraph "데이터 수집" + Collector[Data Collector] + RealTime[실시간 스트림] + Historical[과거 데이터 수집] + end + + subgraph "데이터 처리" + Validator[데이터 검증] + Adjuster[조정 처리] + QualityCheck[품질 체크] + end + + subgraph "저장소" + Cache[(Redis
실시간)] + TimeSeries[(TimescaleDB
과거)] + Metadata[(Metadata
종목 정보)] + end + + subgraph "소비자" + Strategy[전략 엔진] + Backtest[백테스트] + Analytics[분석] + Monitor[모니터] + end + + Broker --> RealTime + Yahoo --> Historical + Alpha --> Historical + + RealTime --> Collector + Historical --> Collector + + Collector --> Validator + Validator --> QualityCheck + QualityCheck -->|통과| Adjuster + QualityCheck -->|실패| Alert[품질 알림] + + Adjuster --> Cache + Adjuster --> TimeSeries + Adjuster --> Metadata + + Cache --> Strategy + Cache --> Monitor + + TimeSeries --> Backtest + TimeSeries --> Analytics + + Metadata --> Strategy + + style Cache fill:#FF6B6B,color:#fff + style TimeSeries fill:#4ECDC4,color:#fff + style Metadata fill:#45B7D1,color:#fff +``` + +### 4.2 주문 실행 흐름 + +```mermaid +graph TB + Start([스케줄 트리거]) --> GetContainer[컨테이너 정보 조회] + GetContainer --> GenerateSignals[신호 생성] + GenerateSignals --> GetMarketData[시장 데이터 조회] + GetMarketData --> Calculate[매매 신호 계산] + + Calculate --> RiskCheck[리스크 검증] + + RiskCheck --> CheckResult{검증 결과} + CheckResult -->|실패| SendAlert[실패 알림] + CheckResult -->|통과| CheckMode{실행 모드} + + CheckMode -->|AUTO| ExecuteOrder + CheckMode -->|APPROVAL| RequestApproval[승인 요청] + RequestApproval --> WaitApproval[승인 대기] + WaitApproval --> ExecuteOrder[주문 실행] + + ExecuteOrder --> SubmitToBroker[증권사에 주문 제출] + SubmitToBroker --> WaitFill[체결 대기] + WaitFill --> UpdatePosition[포지션 업데이트] + UpdatePosition --> Reconcile[밸런스 조정] + Reconcile --> CalcPerformance[성과 계산] + CalcPerformance --> CheckAnomaly[이상 탐지] + CheckAnomaly --> End([완료]) + + SendAlert --> End + + style RiskCheck fill:#f44336,color:#fff + style ExecuteOrder fill:#4caf50,color:#fff + style CheckAnomaly fill:#ff9800,color:#fff +``` + +## 5. 인프라 아키텍처 + +### 5.1 배포 구조 + +```mermaid +graph TB + subgraph "로드 밸런서" + LB[Load Balancer
Nginx/ALB] + end + + subgraph "애플리케이션 레이어" + API1[API Gateway 1] + API2[API Gateway 2] + + Worker1[Worker 1
scheduler/strategy] + Worker2[Worker 2
analytics] + end + + subgraph "데이터 레이어" + PG_Master[(PostgreSQL
Primary)] + PG_Replica[(PostgreSQL
Replica)] + + Redis_Master[(Redis
Primary)] + Redis_Replica[(Redis
Replica)] + + TS[(TimescaleDB
시계열)] + end + + subgraph "메시지 큐" + Kafka[Kafka Cluster] + end + + subgraph "스토리지" + S3[(S3
리포트/백업)] + end + + subgraph "모니터링" + Prometheus[Prometheus] + Grafana[Grafana] + ELK[ELK Stack] + end + + LB --> API1 + LB --> API2 + + API1 --> Worker1 + API2 --> Worker2 + + Worker1 --> PG_Master + Worker2 --> PG_Replica + + Worker1 --> Redis_Master + Worker2 --> Redis_Replica + + Worker1 --> TS + Worker2 --> TS + + Worker1 --> Kafka + Worker2 --> Kafka + + Worker1 --> S3 + Worker2 --> S3 + + PG_Master -.->|복제| PG_Replica + Redis_Master -.->|복제| Redis_Replica + + API1 --> Prometheus + Worker1 --> Prometheus + Prometheus --> Grafana + + API1 --> ELK + Worker1 --> ELK + + style PG_Master fill:#4CAF50,color:#fff + style Redis_Master fill:#FF6B6B,color:#fff + style Kafka fill:#FF9800,color:#fff +``` + +### 5.2 데이터베이스 스키마 분리 + +```mermaid +graph TB + subgraph "PostgreSQL" + subgraph "Core Schema" + Accounts[accounts
계좌 정보] + Containers[containers
컨테이너] + Strategies[strategies
전략] + Orders[orders
주문] + Positions[positions
포지션] + end + + subgraph "Config Schema" + RiskLimits[risk_limits
리스크 한도] + Schedules[schedules
스케줄] + AlertRules[alert_rules
알림 규칙] + end + + subgraph "Analytics Schema" + Performance[performance
성과 데이터] + Reports[reports
리포트] + end + + subgraph "Audit Schema" + AuditLogs[audit_logs
감사 로그] + ChangeLogs[change_logs
변경 이력] + end + end + + subgraph "TimescaleDB" + PriceBars[price_bars
가격 데이터] + Metrics[metrics
메트릭] + Trades[trades
거래 이력] + end + + subgraph "Redis" + RealtimePrices[실시간 시세] + SessionCache[세션 캐시] + RateLimits[Rate Limit] + end + + Containers --> Accounts + Strategies --> Containers + Orders --> Containers + Positions --> Containers + + RiskLimits --> Containers + Schedules --> Containers + + Performance --> Containers + Reports --> Performance + + AuditLogs --> Containers + ChangeLogs --> Containers + + style Accounts fill:#e3f2fd + style Containers fill:#e3f2fd + style AuditLogs fill:#f3e5f5 + style PriceBars fill:#fff9c4 +``` + +## 6. 보안 아키텍처 + +### 6.1 인증 및 권한 + +```mermaid +graph LR + User[사용자] --> Auth[인증 서비스] + Auth --> JWT[JWT 토큰 발급] + JWT --> Gateway[API Gateway] + + Gateway --> RBAC[권한 체크] + RBAC -->|관리자| AdminAPI[관리 API] + RBAC -->|일반 사용자| UserAPI[사용자 API] + RBAC -->|읽기 전용| ReadOnlyAPI[조회 API] + + AdminAPI --> Services[백엔드 서비스] + UserAPI --> Services + ReadOnlyAPI --> Services + + Services --> AuditLog[감사 로그] + + style Auth fill:#4CAF50,color:#fff + style RBAC fill:#FF9800,color:#fff + style AuditLog fill:#F44336,color:#fff +``` + +### 6.2 API 키 관리 + +```mermaid +graph TB + User[사용자] -->|API 키 입력| Encrypt[암호화] + Encrypt -->|AES-256| Store[(암호화 저장소)] + + Scheduler[스케줄러] -->|필요 시| Decrypt[복호화] + Store -->|암호화된 데이터| Decrypt + Decrypt -->|평문 키| BrokerAPI[증권사 API] + + BrokerAPI -->|응답| Scheduler + + Note1[메모리에만 평문 존재] + Note2[로그에 절대 기록 안함] + + style Encrypt fill:#4CAF50,color:#fff + style Store fill:#F44336,color:#fff + style Decrypt fill:#FF9800,color:#fff +``` + +## 7. 확장성 고려사항 + +### 7.1 수평 확장 + +- **API Gateway**: 로드 밸런서를 통한 다중 인스턴스 +- **Worker 프로세스**: 메시지 큐 기반 작업 분산 +- **데이터베이스**: Read Replica를 통한 읽기 부하 분산 +- **캐시**: Redis Cluster를 통한 분산 캐싱 + +### 7.2 증권사 플러그인 아키텍처 + +```mermaid +graph TB + subgraph "Core" + BrokerInterface[BrokerAdapter
인터페이스] + end + + subgraph "플러그인" + KoreaInvestment[한국투자증권
Adapter] + Samsung[삼성증권
Adapter] + Kiwoom[키움증권
Adapter] + Future[미래 증권사
Adapter] + end + + BrokerInterface -.->|구현| KoreaInvestment + BrokerInterface -.->|구현| Samsung + BrokerInterface -.->|구현| Kiwoom + BrokerInterface -.->|구현| Future + + Balance[balance 컴포넌트] --> BrokerInterface + + style BrokerInterface fill:#2196F3,color:#fff + style Future fill:#ddd +``` + +## 8. 장애 복구 + +### 8.1 장애 시나리오 및 대응 + +| 시나리오 | 영향 | 복구 방안 | +|---------|------|----------| +| 증권사 API 장애 | 주문 실행 불가 | 자동 재시도 (지수 백오프), 수동 개입 알림 | +| 데이터베이스 장애 | 시스템 전체 중단 | Replica로 자동 Failover | +| 시장 데이터 지연 | 신호 생성 지연 | 캐시 데이터 활용, 타임아웃 처리 | +| Worker 프로세스 다운 | 특정 작업 중단 | 헬스 체크 실패 시 자동 재시작 | +| 메시지 큐 장애 | 비동기 작업 중단 | 메시지 영속화, 큐 복구 후 재처리 | + +### 8.2 백업 전략 + +- **데이터베이스**: 일일 전체 백업 + 트랜잭션 로그 백업 (Point-in-Time Recovery) +- **설정**: Git 기반 버전 관리 +- **감사 로그**: S3에 불변 저장 (법적 보존 기간 준수) +- **백테스트 결과**: 주요 결과만 장기 보관 + +## 9. 관련 문서 + +- [시스템 개요](./01-overview.md) +- [공통 데이터 모델](./03-data-models.md) +- [주요 워크플로우](./04-workflows.md) +- [구현 로드맵](./05-roadmap.md) + +### 구성요소 상세 문서 +- [Phase 1 컴포넌트](../components/phase1/) +- [Phase 2 컴포넌트](../components/phase2/) +- [Phase 3 컴포넌트](../components/phase3/) diff --git a/docs/03-data-models.md b/docs/03-data-models.md new file mode 100644 index 0000000..0fb4a5e --- /dev/null +++ b/docs/03-data-models.md @@ -0,0 +1,656 @@ +# QuantBench 공통 데이터 모델 + +이 문서는 시스템 전반에서 사용되는 핵심 데이터 모델을 정의합니다. + +## 1. 계좌 및 자산 관련 + +### 1.1 Account (계좌) + +```typescript +interface Account { + id: string // 계좌 고유 ID + brokerId: string // 증권사 식별자 + accountNumber: string // 계좌 번호 + accountName: string // 계좌 별칭 + accountType: AccountType // 계좌 유형 + credentials: EncryptedCredentials // 암호화된 인증 정보 + isActive: boolean // 활성 상태 + createdAt: Date // 생성 일시 + updatedAt: Date // 수정 일시 +} + +type AccountType = 'STOCK' | 'FUTURES' | 'FOREX' + +interface EncryptedCredentials { + encryptedData: string // AES-256 암호화된 데이터 + iv: string // 초기화 벡터 + algorithm: string // 암호화 알고리즘 +} +``` + +### 1.2 Balance (잔고) + +```typescript +interface Balance { + accountId: string // 계좌 ID + cash: CashBalance // 현금 잔고 + positions: Position[] // 보유 포지션 + totalEquity: number // 총 자산 평가액 + buyingPower: number // 매수 가능 금액 + withdrawableCash: number // 출금 가능 금액 + timestamp: Date // 조회 시점 +} + +interface CashBalance { + krw: number // 원화 + usd: number // 달러 + [currency: string]: number // 기타 통화 +} +``` + +### 1.3 Position (포지션) + +```typescript +interface Position { + symbol: string // 종목 코드 + symbolName?: string // 종목명 + quantity: number // 보유 수량 + averagePrice: number // 평균 매입가 + currentPrice: number // 현재가 + marketValue: number // 평가 금액 + unrealizedPnL: number // 평가 손익 + unrealizedPnLPct: number // 평가 손익률 (%) + realizedPnL?: number // 실현 손익 + updatedAt: Date // 업데이트 시점 +} +``` + +## 2. 컨테이너 관련 + +### 2.1 Container (컨테이너) + +```typescript +interface Container { + id: string // 컨테이너 ID + accountId: string // 소속 계좌 ID + name: string // 컨테이너 이름 + description?: string // 설명 + strategyId?: string // 연결된 전략 ID + + allocation: Allocation // 자산 할당 + constraints: Constraints // 제약 조건 + rebalancing: RebalancingConfig // 리밸런싱 설정 + + status: ContainerStatus // 상태 + createdAt: Date // 생성 일시 + updatedAt: Date // 수정 일시 + lastRebalancedAt?: Date // 마지막 리밸런싱 일시 +} + +interface Allocation { + initialAmount: number // 초기 할당 금액 + currentEquity: number // 현재 총 자산 + cashReserve: number // 최소 현금 보유량 +} + +interface Constraints { + maxSinglePositionPct: number // 단일 종목 최대 비중 (%) + maxDrawdown: number // 최대 허용 낙폭 (%) + allowedAssetClasses: string[] // 투자 가능 자산군 + maxLeverage?: number // 최대 레버리지 배수 +} + +interface RebalancingConfig { + frequency: RebalancingFrequency + dayOfWeek?: number // WEEKLY인 경우 (1=월, 7=일) + dayOfMonth?: number // MONTHLY인 경우 (1-31) + autoExecute: boolean // 자동 실행 여부 +} + +type RebalancingFrequency = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'QUARTERLY' | 'MANUAL' +type ContainerStatus = 'ACTIVE' | 'PAUSED' | 'ARCHIVED' +``` + +### 2.2 VirtualBalance (가상 잔고) + +```typescript +interface VirtualBalance { + containerId: string // 컨테이너 ID + cash: number // 현금 + positions: Position[] // 보유 종목 + totalValue: number // 총 가치 + availableCash: number // 주문 가능 현금 + allocatedValue: number // 할당받은 금액 + timestamp: Date // 조회 시점 +} +``` + +## 3. 전략 관련 + +### 3.1 Strategy (전략) + +```typescript +interface Strategy { + id: string // 전략 ID + name: string // 전략 이름 + description: string // 설명 + category: StrategyCategory // 카테고리 + + versions: StrategyVersion[] // 버전 목록 + currentVersion: string // 현재 버전 + + parameters: Parameter[] // 파라미터 정의 + requiredData: string[] // 필요한 데이터 종류 + + createdBy: string // 작성자 + createdAt: Date // 생성 일시 + updatedAt: Date // 수정 일시 + isPublic: boolean // 공개 여부 +} + +type StrategyCategory = + | 'ASSET_ALLOCATION' // 자산 배분 + | 'MOMENTUM' // 모멘텀 + | 'VALUE' // 가치 투자 + | 'MEAN_REVERSION' // 평균 회귀 + | 'ARBITRAGE' // 차익 거래 + | 'CUSTOM' // 사용자 정의 + +interface StrategyVersion { + version: string // 버전 번호 (예: "1.0.0") + code: string // 전략 구현 코드 + changelog?: string // 변경 사항 + createdAt: Date // 생성 일시 + backtestResults?: BacktestResult[] // 백테스트 결과 +} + +interface Parameter { + name: string // 파라미터 이름 + type: ParameterType // 데이터 타입 + defaultValue: any // 기본값 + description?: string // 설명 + min?: number // 최소값 (숫자형) + max?: number // 최대값 (숫자형) + options?: string[] // 선택 옵션 (카테고리형) + required: boolean // 필수 여부 +} + +type ParameterType = 'INTEGER' | 'FLOAT' | 'BOOLEAN' | 'STRING' | 'CATEGORICAL' +``` + +### 3.2 Signal (매매 신호) + +```typescript +interface Signal { + symbol: string // 종목 코드 + action: SignalAction // 행동 + targetWeight?: number // 목표 비중 (0-1) + targetQuantity?: number // 목표 수량 + reason?: string // 신호 발생 이유 + confidence?: number // 신호 신뢰도 (0-1) + generatedAt: Date // 생성 시점 + metadata?: Record // 추가 메타데이터 +} + +type SignalAction = 'BUY' | 'SELL' | 'HOLD' +``` + +### 3.3 BacktestResult (백테스트 결과) + +```typescript +interface BacktestResult { + id: string // 결과 ID + strategyId: string // 전략 ID + strategyVersion: string // 전략 버전 + config: BacktestConfig // 설정 + + equity: EquityPoint[] // 자산 변화 시계열 + trades: Trade[] // 거래 내역 + metrics: PerformanceMetrics // 성과 지표 + + runAt: Date // 실행 일시 + duration: number // 실행 시간 (초) +} + +interface BacktestConfig { + startDate: Date // 시작일 + endDate: Date // 종료일 + initialCapital: number // 초기 자본 + universe: string[] // 투자 대상 종목 + benchmark?: string // 벤치마크 (예: 'KOSPI') + costs: TradingCosts // 거래 비용 +} + +interface TradingCosts { + commission: number // 거래 수수료 (%) + slippage: number // 슬리피지 (bps) + tax?: number // 세금 (%) +} + +interface EquityPoint { + date: Date // 날짜 + value: number // 자산 가치 + cash: number // 현금 + positions: Record // 보유 종목 (종목코드: 수량) +} + +interface Trade { + date: Date // 거래 일시 + symbol: string // 종목 코드 + action: 'BUY' | 'SELL' // 매수/매도 + quantity: number // 수량 + price: number // 체결 가격 + commission: number // 수수료 + slippage: number // 슬리피지 +} +``` + +## 4. 주문 관련 + +### 4.1 Order (주문) + +```typescript +interface Order { + orderId?: string // 주문 ID + accountId: string // 계좌 ID + containerId?: string // 컨테이너 ID (있는 경우) + symbol: string // 종목 코드 + side: OrderSide // 매수/매도 + orderType: OrderType // 주문 유형 + quantity: number // 주문 수량 + price?: number // 지정가 (LIMIT인 경우) + stopPrice?: number // 스톱 가격 (STOP인 경우) + + status: OrderStatus // 주문 상태 + filledQuantity?: number // 체결 수량 + averageFillPrice?: number // 평균 체결가 + commission?: number // 수수료 + + submittedAt?: Date // 제출 일시 + executedAt?: Date // 체결 일시 + cancelledAt?: Date // 취소 일시 + + metadata?: Record // 추가 메타데이터 +} + +type OrderSide = 'BUY' | 'SELL' +type OrderType = 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_LIMIT' +type OrderStatus = + | 'PENDING' // 대기 중 + | 'SUBMITTED' // 제출됨 + | 'PARTIALLY_FILLED' // 부분 체결 + | 'FILLED' // 완전 체결 + | 'CANCELLED' // 취소됨 + | 'REJECTED' // 거부됨 + | 'EXPIRED' // 만료됨 +``` + +## 5. 시장 데이터 관련 + +### 5.1 PriceBar (가격 바) + +```typescript +interface PriceBar { + symbol: string // 종목 코드 + timestamp: Date // 시간 + interval: Interval // 주기 + open: number // 시가 + high: number // 고가 + low: number // 저가 + close: number // 종가 + volume: number // 거래량 + adjustedClose?: number // 조정 종가 +} + +type Interval = '1m' | '5m' | '15m' | '1h' | '4h' | '1d' | '1w' | '1M' +``` + +### 5.2 Quote (현재가) + +```typescript +interface Quote { + symbol: string // 종목 코드 + price: number // 현재가 + change: number // 전일 대비 변동 + changePct: number // 변동률 (%) + volume: number // 거래량 + bidPrice: number // 매수 호가 + askPrice: number // 매도 호가 + bidSize: number // 매수 호가 수량 + askSize: number // 매도 호가 수량 + timestamp: Date // 시세 시간 +} +``` + +## 6. 리스크 관련 + +### 6.1 RiskLimits (리스크 한도) + +```typescript +interface RiskLimits { + containerId: string // 컨테이너 ID + + position: PositionLimits // 포지션 한도 + loss: LossLimits // 손실 한도 + exposure: ExposureLimits // 익스포저 한도 +} + +interface PositionLimits { + maxSinglePositionPct: number // 단일 종목 최대 비중 (%) + maxSectorPct: number // 단일 섹터 최대 비중 (%) + maxTotalLeverage: number // 최대 레버리지 배수 + minPositionSize?: number // 최소 포지션 크기 +} + +interface LossLimits { + maxDailyLossPct: number // 일일 최대 손실 (%) + maxDrawdownPct: number // 최대 낙폭 (%) + stopLossEnabled: boolean // 손절 활성화 + takeProfitEnabled?: boolean // 익절 활성화 +} + +interface ExposureLimits { + maxLongExposure: number // 최대 롱 익스포저 + maxShortExposure: number // 최대 숏 익스포저 + maxGrossExposure: number // 최대 총 익스포저 + maxNetExposure?: number // 최대 순 익스포저 +} +``` + +### 6.2 RiskCheckResult (리스크 검증 결과) + +```typescript +interface RiskCheckResult { + passed: boolean // 통과 여부 + violations: RiskViolation[] // 위반 항목 + recommendations?: string[] // 권장 사항 + timestamp: Date // 검증 시점 +} + +interface RiskViolation { + rule: string // 규칙 이름 + severity: ViolationSeverity // 심각도 + message: string // 메시지 + currentValue: number // 현재 값 + limitValue: number // 한도 값 +} + +type ViolationSeverity = 'BLOCKING' | 'WARNING' | 'INFO' +``` + +## 7. 스케줄 및 실행 관련 + +### 7.1 Schedule (스케줄) + +```typescript +interface Schedule { + id: string // 스케줄 ID + containerId: string // 컨테이너 ID + name: string // 스케줄 이름 + + trigger: ScheduleTrigger // 트리거 설정 + executionMode: ExecutionMode // 실행 모드 + constraints: ScheduleConstraints // 제약 조건 + + isActive: boolean // 활성 상태 + nextRun?: Date // 다음 실행 시간 + lastRun?: Date // 마지막 실행 시간 + createdAt: Date // 생성 일시 +} + +interface ScheduleTrigger { + type: TriggerType // 트리거 유형 + expression?: string // Cron 표현식 (CRON인 경우) + intervalMinutes?: number // 주기 (INTERVAL인 경우) + event?: TriggerEvent // 이벤트 (EVENT인 경우) +} + +type TriggerType = 'CRON' | 'INTERVAL' | 'EVENT' +type TriggerEvent = 'MARKET_OPEN' | 'MARKET_CLOSE' | 'CUSTOM' +type ExecutionMode = 'AUTO' | 'APPROVAL_REQUIRED' + +interface ScheduleConstraints { + marketHoursOnly: boolean // 장 시간만 + skipHolidays: boolean // 휴일 건너뛰기 + minIntervalHours?: number // 최소 실행 간격 (시간) +} +``` + +### 7.2 Execution (실행) + +```typescript +interface Execution { + id: string // 실행 ID + containerId: string // 컨테이너 ID + strategyId: string // 전략 ID + scheduleId?: string // 스케줄 ID (자동 실행인 경우) + + status: ExecutionStatus // 상태 + signals: Signal[] // 생성된 신호 + plannedOrders: Order[] // 계획된 주문 + executedOrders: Order[] // 실행된 주문 + + estimatedCost: EstimatedCost // 예상 비용 + approvalRequest?: ApprovalRequest // 승인 요청 (있는 경우) + + startedAt?: Date // 시작 일시 + completedAt?: Date // 완료 일시 + error?: string // 에러 메시지 +} + +type ExecutionStatus = + | 'PENDING' // 대기 + | 'APPROVED' // 승인됨 + | 'REJECTED' // 거부됨 + | 'RUNNING' // 실행 중 + | 'COMPLETED' // 완료 + | 'FAILED' // 실패 + +interface EstimatedCost { + commission: number // 예상 수수료 + slippage: number // 예상 슬리피지 + totalValue: number // 총 거래 금액 +} + +interface ApprovalRequest { + id: string // 요청 ID + executionId: string // 실행 ID + summary: ApprovalSummary // 요약 + orders: Order[] // 주문 목록 + requestedAt: Date // 요청 일시 + expiresAt: Date // 만료 일시 + approvedAt?: Date // 승인 일시 + approvedBy?: string // 승인자 + decision?: ApprovalDecision // 결정 +} + +interface ApprovalSummary { + numOrders: number // 주문 건수 + buyValue: number // 매수 금액 + sellValue: number // 매도 금액 + estimatedCommission: number // 예상 수수료 +} + +type ApprovalDecision = 'APPROVED' | 'REJECTED' +``` + +## 8. 성과 분석 관련 + +### 8.1 PerformanceMetrics (성과 지표) + +```typescript +interface PerformanceMetrics { + // 수익률 + totalReturn: number // 총 수익률 (%) + cagr: number // 연평균 성장률 (%) + annualizedReturn: number // 연율화 수익률 (%) + + // 리스크 + volatility: number // 변동성 (%, 연율화) + maxDrawdown: number // 최대 낙폭 (%) + downsideDeviation: number // 하방 편차 (%) + + // 리스크 조정 수익률 + sharpeRatio: number // 샤프 비율 + sortinoRatio: number // 소르티노 비율 + calmarRatio: number // 칼마 비율 + + // 거래 지표 + winRate: number // 승률 (%) + avgWin: number // 평균 수익 (%) + avgLoss: number // 평균 손실 (%) + profitFactor: number // 손익비 + + // 기타 + tradingDays: number // 거래 일수 + totalTrades: number // 총 거래 건수 + turnover: number // 회전율 (연율화) +} +``` + +## 9. 모니터링 및 알림 관련 + +### 9.1 Alert (알림) + +```typescript +interface Alert { + id: string // 알림 ID + type: AlertType // 알림 유형 + severity: AlertSeverity // 심각도 + + title: string // 제목 + message: string // 내용 + + source: string // 발생 컴포넌트 + containerId?: string // 컨테이너 ID (있는 경우) + accountId?: string // 계좌 ID (있는 경우) + + channels: AlertChannel[] // 발송 채널 + sentAt?: Date // 발송 일시 + + acknowledged: boolean // 확인 여부 + acknowledgedAt?: Date // 확인 일시 + acknowledgedBy?: string // 확인자 + + createdAt: Date // 생성 일시 + metadata?: Record // 추가 메타데이터 +} + +type AlertType = + | 'SYSTEM' // 시스템 + | 'RISK' // 리스크 + | 'EXECUTION' // 실행 + | 'PERFORMANCE' // 성과 + | 'ANOMALY' // 이상 + +type AlertSeverity = 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL' +type AlertChannel = 'EMAIL' | 'SMS' | 'PUSH' | 'SLACK' | 'WEBHOOK' +``` + +## 10. 감사 관련 + +### 10.1 AuditEvent (감사 이벤트) + +```typescript +interface AuditEvent { + id: string // 이벤트 ID + timestamp: Date // 발생 시간 + + eventType: AuditEventType // 이벤트 유형 + action: string // 행동 (CREATE, UPDATE, DELETE 등) + + userId?: string // 사용자 ID + accountId?: string // 계좌 ID + containerId?: string // 컨테이너 ID + + entity: string // 엔티티 타입 + entityId: string // 엔티티 ID + + before?: any // 변경 전 상태 + after?: any // 변경 후 상태 + + metadata: AuditMetadata // 메타데이터 + + hash: string // 무결성 검증용 해시 + previousHash?: string // 이전 이벤트 해시 (체인) +} + +type AuditEventType = + | 'ORDER' // 주문 + | 'CONFIG_CHANGE' // 설정 변경 + | 'EXECUTION' // 실행 + | 'LOGIN' // 로그인 + | 'DATA_EXPORT' // 데이터 내보내기 + | 'APPROVAL' // 승인 + +interface AuditMetadata { + ipAddress?: string // IP 주소 + userAgent?: string // User Agent + reason?: string // 사유 + source?: string // 출처 +} +``` + +## 11. 데이터 관계도 + +```mermaid +erDiagram + Account ||--o{ Container : has + Account ||--o{ Balance : has + Container ||--o{ VirtualBalance : has + Container ||--o| Strategy : uses + Container ||--o{ Schedule : has + Container ||--o{ RiskLimits : has + Container ||--o{ Execution : has + + Strategy ||--o{ StrategyVersion : has + Strategy ||--o{ BacktestResult : generates + + Execution ||--o{ Signal : generates + Execution ||--o{ Order : creates + Execution ||--o| ApprovalRequest : requires + + Order }o--|| Account : belongs_to + Order }o--o| Container : belongs_to + + Balance ||--o{ Position : contains + VirtualBalance ||--o{ Position : contains + + Container ||--o{ Alert : triggers + Execution ||--o{ AuditEvent : generates + Order ||--o{ AuditEvent : generates + + Account { + string id PK + string brokerId + string accountNumber + AccountType accountType + } + + Container { + string id PK + string accountId FK + string strategyId FK + ContainerStatus status + } + + Strategy { + string id PK + string name + StrategyCategory category + } + + Order { + string orderId PK + string accountId FK + string containerId FK + OrderStatus status + } +``` + +## 12. 관련 문서 + +- [시스템 개요](./01-overview.md) +- [전체 아키텍처](./02-architecture.md) +- [주요 워크플로우](./04-workflows.md) +- [구현 로드맵](./05-roadmap.md) diff --git a/docs/04-workflows.md b/docs/04-workflows.md new file mode 100644 index 0000000..9257bbd --- /dev/null +++ b/docs/04-workflows.md @@ -0,0 +1,695 @@ +# QuantBench 주요 워크플로우 + +이 문서는 시스템의 핵심 워크플로우를 상세히 설명합니다. + +## 1. 전략 실행 워크플로우 + +### 1.1 전체 흐름 + +```mermaid +sequenceDiagram + participant S as Scheduler + participant M as Mgmt + participant ST as Strategy + participant D as Data + participant R as Risk + participant B as Balance + participant A as Analytics + participant MO as Monitor + + Note over S: 스케줄 트리거 발생 + + S->>M: 1. 컨테이너 정보 조회 + M-->>S: 컨테이너 설정 & 현재 포지션 + + S->>ST: 2. 전략 실행 요청 + ST->>D: 2.1 시장 데이터 조회 + D-->>ST: 최신 시세 데이터 + ST->>ST: 2.2 신호 생성 + ST-->>S: 매매 신호 반환 + + S->>R: 3. 리스크 체크 + R->>R: 3.1 포지션 사이즈 검증 + R->>R: 3.2 VaR 계산 + R->>R: 3.3 한도 확인 + + alt 리스크 체크 실패 + R-->>S: 검증 실패 + S->>MO: 알림 발송 + MO-->>S: 알림 완료 + Note over S: 실행 중단 + else 리스크 체크 통과 + R-->>S: 검증 통과 + + alt 승인 필요 모드 + S->>S: 승인 요청 생성 + S->>MO: 사용자에게 알림 + Note over S: 사용자 승인 대기 + S->>S: 승인 완료 + end + + S->>B: 4. 주문 제출 + B->>B: 4.1 증권사 API 호출 + B-->>S: 주문 접수 완료 + + Note over B: 체결 대기... + + B->>B: 4.2 체결 확인 + B->>M: 5. 포지션 업데이트 + M->>M: 5.1 컨테이너 밸런스 갱신 + + M->>A: 6. 성과 계산 트리거 + A->>A: 6.1 수익률 계산 + A->>A: 6.2 리스크 지표 갱신 + + A->>MO: 7. 메트릭 업데이트 + MO->>MO: 7.1 대시보드 갱신 + MO->>MO: 7.2 이상 탐지 + + alt 이상 탐지 시 + MO->>MO: 알림 발송 + end + + S->>S: 8. 실행 완료 기록 + end +``` + +### 1.2 상세 단계 + +#### 1단계: 스케줄 트리거 +```typescript +// 스케줄러가 설정된 시간에 실행을 트리거 +scheduler.onTrigger(schedule => { + const container = mgmt.getContainer(schedule.containerId) + const execution = scheduler.createExecution(container, schedule) + scheduler.executeStrategy(execution) +}) +``` + +#### 2단계: 신호 생성 +```typescript +// 전략이 시장 데이터를 기반으로 신호 생성 +const marketData = await data.getMarketData(container.strategyUniverse) +const signals = await strategy.generateSignals(marketData, container.parameters) + +// 생성된 신호 예시 +// [ +// { symbol: 'AAPL', action: 'BUY', targetWeight: 0.3 }, +// { symbol: 'GOOGL', action: 'SELL', targetWeight: 0 } +// ] +``` + +#### 3단계: 리스크 검증 +```typescript +// 신호를 주문으로 변환 +const plannedOrders = strategy.signalsToOrders(signals, container) + +// 리스크 검증 +const riskResult = await risk.validateOrders(plannedOrders, container) + +if (!riskResult.passed) { + // 리스크 위반 시 실행 중단 + await monitor.sendAlert({ + type: 'RISK', + severity: 'ERROR', + message: `리스크 검증 실패: ${riskResult.violations}`, + containerId: container.id + }) + return +} +``` + +#### 4단계: 주문 실행 +```typescript +// 승인 필요 모드인 경우 +if (schedule.executionMode === 'APPROVAL_REQUIRED') { + const approvalRequest = await scheduler.requestApproval(execution) + await monitor.sendNotification(approvalRequest) + + // 승인 대기 + const approved = await scheduler.waitForApproval(approvalRequest) + if (!approved) return +} + +// 주문 제출 +const executedOrders = [] +for (const order of plannedOrders) { + const result = await balance.placeOrder(order) + executedOrders.push(result) +} +``` + +#### 5단계: 포지션 업데이트 +```typescript +// 체결 완료 후 컨테이너 밸런스 업데이트 +for (const order of executedOrders) { + if (order.status === 'FILLED') { + await mgmt.updatePosition(container.id, { + symbol: order.symbol, + quantity: order.side === 'BUY' ? order.filledQuantity : -order.filledQuantity, + price: order.averageFillPrice + }) + } +} + +// 밸런스 조정 (reconciliation) +await mgmt.reconcileContainer(container.id) +``` + +## 2. 리스크 관리 워크플로우 + +### 2.1 사전 주문 검증 + +```mermaid +graph TB + Start([주문 요청]) --> GetPosition[현재 포지션 조회] + GetPosition --> CalcNewPosition[신규 포지션 계산] + + CalcNewPosition --> CheckBalance{잔고 충분?} + CheckBalance -->|No| Reject1[주문 거부:
잔고 부족] + CheckBalance -->|Yes| CheckSize + + CheckSize{포지션 사이즈
한도 내?} + CheckSize -->|No| Reject2[주문 거부:
사이즈 초과] + CheckSize -->|Yes| CheckConcentration + + CheckConcentration{집중도
한도 내?} + CheckConcentration -->|No| Reject3[주문 거부:
집중도 초과] + CheckConcentration -->|Yes| CalcVaR + + CalcVaR[VaR 계산] + CalcVaR --> CheckVaR{VaR
한도 내?} + CheckVaR -->|No| Warning1[경고 발생
계속 진행] + CheckVaR -->|Yes| CheckDrawdown + + Warning1 --> CheckDrawdown + + CheckDrawdown{최대 낙폭
한도 내?} + CheckDrawdown -->|No| Reject4[주문 거부:
MDD 초과] + CheckDrawdown -->|Yes| CheckLeverage + + CheckLeverage{레버리지
한도 내?} + CheckLeverage -->|No| Reject5[주문 거부:
레버리지 초과] + CheckLeverage -->|Yes| Approve + + Approve([검증 통과:
주문 실행]) + + Reject1 --> Log[리스크 로그 기록] + Reject2 --> Log + Reject3 --> Log + Reject4 --> Log + Reject5 --> Log + + Approve --> ExecuteOrder[주문 제출] + ExecuteOrder --> Monitor[실시간 모니터링] + + Monitor --> CheckStop{손절/익절
조건 충족?} + CheckStop -->|Yes| AutoClose[자동 청산] + CheckStop -->|No| Monitor + + style Start fill:#4CAF50,color:#fff + style Approve fill:#4CAF50,color:#fff + style Reject1 fill:#F44336,color:#fff + style Reject2 fill:#F44336,color:#fff + style Reject3 fill:#F44336,color:#fff + style Reject4 fill:#F44336,color:#fff + style Reject5 fill:#F44336,color:#fff + style Warning1 fill:#FF9800,color:#fff +``` + +### 2.2 실시간 리스크 모니터링 + +```typescript +// 실시간 포지션 모니터링 +monitor.watchContainer(container.id, async (positions, marketData) => { + // 손절 조건 체크 + for (const position of positions) { + const stopLoss = risk.getStopLoss(container.id, position.symbol) + if (stopLoss && position.unrealizedPnLPct <= -stopLoss.pct) { + // 손절 트리거 + await scheduler.executeEmergencyClose(container.id, position.symbol) + await monitor.sendAlert({ + type: 'RISK', + severity: 'WARNING', + message: `손절 실행: ${position.symbol} ${position.unrealizedPnLPct}%` + }) + } + } + + // MDD 체크 + const performance = await analytics.getCurrentPerformance(container.id) + const limits = await risk.getRiskLimits(container.id) + + if (performance.currentDrawdown >= limits.loss.maxDrawdownPct) { + // 컨테이너 일시 정지 + await mgmt.pauseContainer(container.id) + await monitor.sendAlert({ + type: 'RISK', + severity: 'CRITICAL', + message: `최대 낙폭 초과: ${performance.currentDrawdown}%` + }) + } +}) +``` + +## 3. 승인 워크플로우 + +### 3.1 승인 요청 및 처리 + +```mermaid +graph TB + Trigger[스케줄 트리거] --> GenerateSignals[신호 생성] + GenerateSignals --> RiskCheck[리스크 체크] + + RiskCheck --> CheckMode{실행 모드} + + CheckMode -->|AUTO| AutoExecute[자동 실행] + CheckMode -->|APPROVAL| CreateRequest + + CreateRequest[승인 요청 생성] + CreateRequest --> SendNotification[알림 발송] + SendNotification --> WaitApproval[승인 대기] + + WaitApproval --> CheckTimeout{타임아웃?} + CheckTimeout -->|Yes| Expired[요청 만료] + CheckTimeout -->|No| WaitApproval + + WaitApproval --> UserDecision{사용자 결정} + + UserDecision -->|승인| Execute[주문 실행] + UserDecision -->|거부| Rejected[실행 거부] + + AutoExecute --> Execute + + Execute --> PlaceOrders[주문 제출] + PlaceOrders --> Success{성공?} + + Success -->|Yes| NotifySuccess[성공 알림] + Success -->|No| NotifyFail[실패 알림] + + Rejected --> LogRejection[거부 로그] + Expired --> LogExpired[만료 로그] + + NotifySuccess --> End([완료]) + NotifyFail --> End + LogRejection --> End + LogExpired --> End + + style Execute fill:#4CAF50,color:#fff + style Rejected fill:#F44336,color:#fff + style Expired fill:#FF9800,color:#fff + style AutoExecute fill:#2196F3,color:#fff +``` + +### 3.2 승인 요청 생성 + +```typescript +async function createApprovalRequest(execution: Execution): Promise { + // 주문 요약 생성 + const summary = { + numOrders: execution.plannedOrders.length, + buyValue: execution.plannedOrders + .filter(o => o.side === 'BUY') + .reduce((sum, o) => sum + o.quantity * o.price!, 0), + sellValue: execution.plannedOrders + .filter(o => o.side === 'SELL') + .reduce((sum, o) => sum + o.quantity * o.price!, 0), + estimatedCommission: execution.estimatedCost.commission + } + + // 승인 요청 생성 + const request = await scheduler.createApprovalRequest({ + executionId: execution.id, + summary, + orders: execution.plannedOrders, + expiresAt: new Date(Date.now() + 30 * 60 * 1000) // 30분 후 만료 + }) + + // 알림 발송 + await monitor.sendNotification({ + type: 'EXECUTION', + severity: 'INFO', + title: '주문 승인 요청', + message: ` + ${summary.numOrders}건의 주문이 대기 중입니다. + 매수: ${summary.buyValue.toLocaleString()}원 + 매도: ${summary.sellValue.toLocaleString()}원 + 예상 수수료: ${summary.estimatedCommission.toLocaleString()}원 + `, + channels: ['EMAIL', 'PUSH'] + }) + + return request +} +``` + +## 4. 컨테이너 생명주기 + +### 4.1 상태 전이도 + +```mermaid +stateDiagram-v2 + [*] --> Created: createContainer() + + Created --> Active: activate() + Created --> [*]: delete() + + Active --> Running: scheduler trigger + Active --> Paused: pause() + Active --> [*]: delete() + + Running --> Active: execution complete + Running --> Error: execution failed + Running --> Paused: emergency stop + + Paused --> Active: resume() + Paused --> [*]: delete() + + Error --> Active: resolve & restart + Error --> Paused: manual intervention + Error --> [*]: delete() + + state Running { + [*] --> GenerateSignals + GenerateSignals --> RiskCheck + RiskCheck --> PlaceOrders: pass + RiskCheck --> [*]: fail + PlaceOrders --> AwaitFill + AwaitFill --> UpdatePosition + UpdatePosition --> [*] + } +``` + +### 4.2 컨테이너 생성 및 활성화 + +```typescript +// 1. 컨테이너 생성 +const container = await mgmt.createContainer({ + accountId: 'account-123', + name: '성장주 전략', + allocation: { + initialAmount: 10000000, // 1천만원 + cashReserve: 1000000 // 최소 100만원 현금 보유 + }, + constraints: { + maxSinglePositionPct: 20, // 단일 종목 최대 20% + maxDrawdown: 15, // 최대 낙폭 15% + allowedAssetClasses: ['STOCK'] + } +}) + +// 2. 전략 할당 +await mgmt.assignStrategy(container.id, 'strategy-momentum-v1') + +// 3. 리스크 한도 설정 +await risk.setRiskLimits(container.id, { + position: { + maxSinglePositionPct: 20, + maxSectorPct: 40, + maxTotalLeverage: 1.0 + }, + loss: { + maxDailyLossPct: 5, + maxDrawdownPct: 15, + stopLossEnabled: true + } +}) + +// 4. 스케줄 설정 +await scheduler.createSchedule({ + containerId: container.id, + trigger: { + type: 'CRON', + expression: '0 9 * * 1-5' // 평일 오전 9시 + }, + executionMode: 'APPROVAL_REQUIRED', + constraints: { + marketHoursOnly: true, + skipHolidays: true + } +}) + +// 5. 컨테이너 활성화 +await mgmt.activateContainer(container.id) +``` + +## 5. 백테스트 워크플로우 + +### 5.1 백테스트 실행 + +```mermaid +sequenceDiagram + participant U as 사용자 + participant ST as Strategy + participant D as Data + participant BE as Backtest Engine + participant A as Analytics + + U->>ST: 백테스트 요청 + ST->>D: 과거 데이터 조회 + D-->>ST: 시계열 데이터 + + ST->>BE: 백테스트 시작 + + loop 각 날짜마다 + BE->>ST: 신호 생성 + ST-->>BE: 매매 신호 + BE->>BE: 가상 주문 체결 + BE->>BE: 포트폴리오 업데이트 + end + + BE->>A: 성과 계산 + A-->>BE: 성과 지표 + + BE-->>U: 백테스트 결과 +``` + +### 5.2 백테스트 구현 + +```typescript +async function runBacktest(config: BacktestConfig): Promise { + // 1. 데이터 로드 + const marketData = await data.getHistoricalPrices( + config.universe, + config.startDate, + config.endDate + ) + + // 2. 초기 상태 설정 + let portfolio = { + cash: config.initialCapital, + positions: {} as Record, + equity: [{ date: config.startDate, value: config.initialCapital }] + } + + const trades: Trade[] = [] + + // 3. 시뮬레이션 실행 + for (const date of marketData.dates) { + // 신호 생성 + const signals = await strategy.generateSignals( + marketData.getDataAsOf(date) + ) + + // 주문 생성 및 체결 + for (const signal of signals) { + if (signal.action === 'HOLD') continue + + const price = marketData.getPrice(signal.symbol, date) + const quantity = calculateQuantity(signal, portfolio, price) + + // 슬리피지 및 수수료 적용 + const executionPrice = applySlippage(price, signal.action, config.costs.slippage) + const commission = executionPrice * quantity * config.costs.commission + + // 포트폴리오 업데이트 + if (signal.action === 'BUY') { + portfolio.cash -= executionPrice * quantity + commission + portfolio.positions[signal.symbol] = (portfolio.positions[signal.symbol] || 0) + quantity + } else { + portfolio.cash += executionPrice * quantity - commission + portfolio.positions[signal.symbol] -= quantity + } + + // 거래 기록 + trades.push({ + date, + symbol: signal.symbol, + action: signal.action, + quantity, + price: executionPrice, + commission + }) + } + + // 일일 자산 가치 계산 + const positionsValue = Object.entries(portfolio.positions) + .reduce((sum, [symbol, qty]) => { + return sum + qty * marketData.getPrice(symbol, date) + }, 0) + + portfolio.equity.push({ + date, + value: portfolio.cash + positionsValue, + cash: portfolio.cash, + positions: { ...portfolio.positions } + }) + } + + // 4. 성과 지표 계산 + const metrics = await analytics.calculateMetrics({ + equity: portfolio.equity, + trades, + benchmark: config.benchmark + }) + + return { + id: generateId(), + strategyId: config.strategyId, + config, + equity: portfolio.equity, + trades, + metrics, + runAt: new Date(), + duration: Date.now() - startTime + } +} +``` + +## 6. 데이터 수집 워크플로우 + +### 6.1 데이터 수집 파이프라인 + +```mermaid +graph LR + subgraph "외부 소스" + Broker[증권사 API] + Yahoo[Yahoo Finance] + Alpha[Alpha Vantage] + end + + subgraph "데이터 수집" + Collector[Data Collector] + RealTime[실시간 스트림] + Historical[과거 데이터 수집] + end + + subgraph "데이터 처리" + Validator[데이터 검증] + Adjuster[조정 처리] + QualityCheck[품질 체크] + end + + subgraph "저장소" + Cache[(Redis
실시간)] + TimeSeries[(TimescaleDB
과거)] + Metadata[(Metadata
종목 정보)] + end + + Broker --> RealTime + Yahoo --> Historical + Alpha --> Historical + + RealTime --> Collector + Historical --> Collector + + Collector --> Validator + Validator --> QualityCheck + QualityCheck -->|통과| Adjuster + QualityCheck -->|실패| Alert[품질 알림] + + Adjuster --> Cache + Adjuster --> TimeSeries + Adjuster --> Metadata + + style Cache fill:#FF6B6B,color:#fff + style TimeSeries fill:#4ECDC4,color:#fff + style Metadata fill:#45B7D1,color:#fff +``` + +### 6.2 데이터 품질 관리 + +```typescript +// 데이터 수집 및 검증 +async function collectAndValidateData(symbols: string[], date: Date) { + for (const symbol of symbols) { + // 1. 데이터 수집 + const rawData = await dataProvider.fetchPriceData(symbol, date) + + // 2. 데이터 검증 + const validationResult = await data.validateData(rawData) + + if (!validationResult.isValid) { + // 품질 문제 감지 + await monitor.sendAlert({ + type: 'SYSTEM', + severity: 'WARNING', + message: `데이터 품질 문제: ${symbol} - ${validationResult.issues.join(', ')}` + }) + + // 결측치 보정 시도 + if (validationResult.canFill) { + rawData = await data.fillMissingData(rawData, 'FORWARD_FILL') + } else { + continue // 보정 불가능하면 skip + } + } + + // 3. 기업 행동 조정 (배당, 액면분할 등) + const adjustedData = await data.adjustForCorporateActions(rawData, symbol) + + // 4. 저장 + await data.storePriceData(adjustedData) + } +} +``` + +## 7. 성과 분석 워크플로우 + +### 7.1 일일 성과 계산 + +```typescript +// 매일 장 마감 후 실행 +scheduler.scheduleDaily('MARKET_CLOSE', async () => { + const containers = await mgmt.getActiveContainers() + + for (const container of containers) { + // 1. 현재 포지션 평가 + const positions = await mgmt.getPositions(container.id) + const marketData = await data.getLatestPrices(positions.map(p => p.symbol)) + + // 2. 일일 수익률 계산 + const dailyReturn = await analytics.calculateDailyReturn( + container.id, + positions, + marketData + ) + + // 3. 누적 성과 업데이트 + await analytics.updatePerformance(container.id, { + date: new Date(), + return: dailyReturn, + equity: positions.reduce((sum, p) => sum + p.marketValue, 0) + }) + + // 4. 리스크 지표 재계산 + const riskMetrics = await analytics.calculateRiskMetrics(container.id) + + // 5. 이상 탐지 + if (dailyReturn < -5) { // 일일 손실 5% 초과 + await monitor.sendAlert({ + type: 'PERFORMANCE', + severity: 'WARNING', + message: `일일 손실 초과: ${container.name} ${dailyReturn.toFixed(2)}%` + }) + } + } +}) +``` + +## 8. 관련 문서 + +- [시스템 개요](./01-overview.md) +- [전체 아키텍처](./02-architecture.md) +- [공통 데이터 모델](./03-data-models.md) +- [구현 로드맵](./05-roadmap.md) diff --git a/docs/05-roadmap.md b/docs/05-roadmap.md new file mode 100644 index 0000000..88ec80f --- /dev/null +++ b/docs/05-roadmap.md @@ -0,0 +1,513 @@ +# QuantBench 구현 로드맵 + +## 1. 전체 일정 개요 + +```mermaid +gantt + title QuantBench 개발 일정 + dateFormat YYYY-MM-DD + section Phase 1: MVP + 프로젝트 설정 :p1_1, 2024-01-01, 2w + balance 구현 :p1_2, after p1_1, 4w + data 구현 :p1_3, after p1_1, 4w + mgmt 구현 :p1_4, after p1_2, 3w + strategy 구현 :p1_5, after p1_3, 4w + scheduler 구현 :p1_6, after p1_4, 3w + risk 구현 :p1_7, after p1_5, 3w + 통합 테스트 :p1_8, after p1_6, 2w + + section Phase 2: Production + analytics 구현 :p2_1, after p1_8, 4w + monitor 구현 :p2_2, after p1_8, 4w + 대시보드 개발 :p2_3, after p2_1, 3w + 통합 및 테스트 :p2_4, after p2_2, 2w + + section Phase 3: Enterprise + audit 구현 :p3_1, after p2_4, 4w + simulation 구현 :p3_2, after p2_4, 4w + 최종 통합 및 배포 :p3_3, after p3_1, 3w +``` + +### 전체 일정 요약 + +| Phase | 기간 | 주요 산출물 | +|-------|------|------------| +| **Phase 1: MVP** | 3-4개월 | 기본 거래 시스템 | +| **Phase 2: Production** | 2-3개월 | 모니터링 & 분석 | +| **Phase 3: Enterprise** | 2-3개월 | 감사 & 시뮬레이션 | +| **총 기간** | 7-10개월 | 완전한 퀀트 시스템 | + +## 2. Phase 1: MVP (3-4개월) + +### 목표 +안전하게 전략을 실행하고 리스크를 통제할 수 있는 기본 시스템 구축 + +### 2.1 프로젝트 설정 (1-2주) + +**작업 항목**: +- [ ] 레포지토리 구조 설정 +- [ ] 개발 환경 구축 (Docker, Docker Compose) +- [ ] CI/CD 파이프라인 설정 +- [ ] 코드 스타일 가이드 및 린팅 설정 +- [ ] 데이터베이스 스키마 초기 설계 +- [ ] API 인증/인가 구조 설계 + +**기술 스택 결정**: +- 백엔드: TypeScript + Node.js (또는 Python + FastAPI) +- 데이터베이스: PostgreSQL + TimescaleDB +- 캐시: Redis +- 메시지 큐: RabbitMQ (또는 Kafka) + +### 2.2 Week 1-4: balance + data 기본 구현 + +#### balance 컴포넌트 (2-3주) + +**우선순위 1: 한국투자증권 API 연동** +- [ ] BrokerAdapter 인터페이스 정의 +- [ ] 한국투자증권 Adapter 구현 + - [ ] 인증 및 세션 관리 + - [ ] 계좌 잔고 조회 + - [ ] 현재가 조회 + - [ ] 주문 제출 (시장가, 지정가) + - [ ] 주문 상태 조회 + - [ ] 주문 취소 +- [ ] API 키 암호화 저장 +- [ ] 에러 처리 및 재시도 로직 +- [ ] 단위 테스트 작성 + +**우선순위 2: 계좌 관리 기능** +- [ ] 계좌 등록/수정/삭제 API +- [ ] 계좌 목록 조회 +- [ ] 계좌 상태 관리 + +#### data 컴포넌트 (2-3주) + +**우선순위 1: 데이터 수집** +- [ ] 데이터 소스 추상화 인터페이스 +- [ ] Yahoo Finance 연동 (과거 데이터) +- [ ] 한국투자증권 API를 통한 실시간 시세 조회 +- [ ] 데이터 검증 로직 + - [ ] 결측치 탐지 + - [ ] 이상치 탐지 + - [ ] 데이터 연속성 체크 + +**우선순위 2: 데이터 저장** +- [ ] TimescaleDB 스키마 설계 +- [ ] 가격 데이터 저장 (PriceBar) +- [ ] Redis 캐시 연동 (실시간 시세) +- [ ] 데이터 조회 API + - [ ] 과거 데이터 조회 + - [ ] 최신 시세 조회 + - [ ] 다중 종목 배치 조회 + +### 2.3 Week 5-8: mgmt + strategy 핵심 기능 + +#### mgmt 컴포넌트 (3주) + +**우선순위 1: 컨테이너 생명주기** +- [ ] 컨테이너 생성/수정/삭제 API +- [ ] 가상 잔고 관리 + - [ ] 초기 자산 할당 + - [ ] 현금 및 포지션 추적 + - [ ] 밸런스 조정 (reconciliation) +- [ ] 컨테이너 상태 관리 (ACTIVE/PAUSED/ARCHIVED) + +**우선순위 2: 자산 관리** +- [ ] 컨테이너 간 자산 이동 +- [ ] 실제 계좌 vs 가상 컨테이너 일치성 검증 +- [ ] 컨테이너 조회 API + +#### strategy 컴포넌트 (4주) + +**우선순위 1: 전략 인터페이스** +- [ ] StrategyInterface 정의 +- [ ] 전략 등록 및 관리 API +- [ ] 전략 버전 관리 +- [ ] 파라미터 관리 + +**우선순위 2: 신호 생성** +- [ ] 신호 생성 엔진 +- [ ] 신호를 주문으로 변환 +- [ ] 내장 전략 구현: Bold Asset Allocation + - [ ] 고정 비중 자산 배분 + - [ ] 리밸런싱 로직 + +**우선순위 3: 백테스트** +- [ ] 백테스트 엔진 구현 +- [ ] 과거 데이터 기반 시뮬레이션 +- [ ] 거래 비용 및 슬리피지 모델링 +- [ ] 성과 지표 계산 (수익률, 샤프 비율, MDD 등) + +### 2.4 Week 9-12: scheduler + risk + +#### scheduler 컴포넌트 (3주) + +**우선순위 1: 스케줄 관리** +- [ ] 스케줄 생성/수정/삭제 API +- [ ] Cron 기반 트리거 +- [ ] 시장 시간 체크 (개장/마감) +- [ ] 휴일 감지 및 자동 스킵 + +**우선순위 2: 실행 관리** +- [ ] 실행 트리거 로직 +- [ ] 전략 실행 오케스트레이션 + - [ ] 컨테이너 정보 조회 + - [ ] 신호 생성 요청 + - [ ] 리스크 검증 + - [ ] 주문 제출 +- [ ] 실행 이력 관리 + +**우선순위 3: 승인 워크플로우** +- [ ] 승인 요청 생성 +- [ ] 승인 대기 및 타임아웃 처리 +- [ ] 승인/거부 처리 +- [ ] 자동 실행 모드 + +#### risk 컴포넌트 (3주) + +**우선순위 1: 사전 주문 검증** +- [ ] 잔고 충분성 체크 +- [ ] 포지션 사이즈 한도 검증 +- [ ] 집중도 리스크 체크 (단일 종목, 섹터) +- [ ] 레버리지 한도 검증 + +**우선순위 2: 리스크 한도 관리** +- [ ] 리스크 한도 설정 API +- [ ] 컨테이너별 한도 조회 + +**우선순위 3: 손절/익절** +- [ ] 손절 조건 설정 +- [ ] 익절 조건 설정 +- [ ] 자동 청산 트리거 + +### 2.5 Week 13-16: 통합 테스트 및 버그 수정 + +**통합 테스트**: +- [ ] 전체 워크플로우 End-to-End 테스트 + - [ ] 컨테이너 생성 → 전략 할당 → 스케줄 설정 → 자동 실행 +- [ ] 리스크 시나리오 테스트 + - [ ] 잔고 부족 시나리오 + - [ ] 리스크 한도 초과 시나리오 + - [ ] 손절 트리거 시나리오 +- [ ] 증권사 API 연동 테스트 (Paper Trading 계좌) + +**버그 수정 및 개선**: +- [ ] 발견된 버그 수정 +- [ ] 성능 최적화 +- [ ] 에러 처리 개선 +- [ ] 로깅 강화 + +**문서화**: +- [ ] API 문서 (Swagger/OpenAPI) +- [ ] 사용자 가이드 +- [ ] 운영 매뉴얼 + +### Phase 1 완료 기준 + +- [ ] 한국투자증권 계좌 연동 완료 +- [ ] 1개 이상의 전략 백테스트 성공 +- [ ] Paper Trading 환경에서 자동 매매 성공 +- [ ] 모든 리스크 체크 통과 +- [ ] 전체 시스템 안정성 검증 + +## 3. Phase 2: Production Ready (2-3개월) + +### 목표 +실전 운영을 위한 모니터링, 분석, 알림 체계 구축 + +### 3.1 Week 1-4: analytics 구현 + +#### analytics 컴포넌트 (4주) + +**우선순위 1: 성과 측정** +- [ ] 일일 수익률 계산 +- [ ] 누적 수익률 추적 +- [ ] 리스크 지표 계산 + - [ ] 변동성 (Volatility) + - [ ] 샤프 비율 (Sharpe Ratio) + - [ ] 소르티노 비율 (Sortino Ratio) + - [ ] 최대 낙폭 (MDD) + +**우선순위 2: 귀속 분석** +- [ ] 수익 원천 분해 + - [ ] 자산 배분 효과 + - [ ] 종목 선택 효과 + - [ ] 타이밍 효과 +- [ ] 섹터별 기여도 분석 +- [ ] 종목별 기여도 분석 + +**우선순위 3: 거래 분석** +- [ ] 거래 통계 (승률, 손익비 등) +- [ ] 거래 비용 분석 +- [ ] 회전율 계산 + +**우선순위 4: 리포트 생성** +- [ ] 일일/주간/월간 리포트 템플릿 +- [ ] PDF 리포트 생성 +- [ ] HTML 리포트 생성 +- [ ] 이메일 자동 발송 + +### 3.2 Week 5-8: monitor 구현 + +#### monitor 컴포넌트 (4주) + +**우선순위 1: 시스템 헬스 체크** +- [ ] 컴포넌트별 헬스 체크 +- [ ] API 연결 상태 모니터링 +- [ ] 데이터베이스 응답 시간 추적 +- [ ] 리소스 사용률 모니터링 (CPU, 메모리) + +**우선순위 2: 이상 탐지** +- [ ] 급격한 포지션 변화 감지 +- [ ] 비정상 주문 탐지 +- [ ] 시장 이상 조건 감지 (극심한 변동성, 유동성 부족) + +**우선순위 3: 알림 시스템** +- [ ] 알림 규칙 엔진 +- [ ] 다채널 알림 발송 + - [ ] 이메일 (SendGrid/AWS SES) + - [ ] SMS (Twilio) + - [ ] 푸시 알림 (Firebase) + - [ ] Slack 웹훅 +- [ ] 알림 이력 관리 +- [ ] 알림 빈도 제한 (Throttling) + +**우선순위 4: 대시보드 데이터** +- [ ] 실시간 메트릭 수집 +- [ ] 대시보드 API +- [ ] WebSocket을 통한 실시간 업데이트 + +### 3.3 Week 9-12: 대시보드 개발 및 통합 + +**프론트엔드 개발** (3주): +- [ ] 프로젝트 설정 (React + TypeScript) +- [ ] 주요 화면 개발 + - [ ] 대시보드 홈 (전체 계좌 요약) + - [ ] 컨테이너 상세 (포지션, 성과, 차트) + - [ ] 전략 관리 (등록, 수정, 백테스트 실행) + - [ ] 주문 승인 화면 + - [ ] 알림 센터 + - [ ] 설정 화면 +- [ ] 차트 컴포넌트 (TradingView, Chart.js) +- [ ] 실시간 업데이트 (WebSocket) + +**통합 및 테스트** (2주): +- [ ] 프론트엔드-백엔드 통합 +- [ ] E2E 테스트 +- [ ] 성능 테스트 +- [ ] 사용자 시나리오 테스트 + +### Phase 2 완료 기준 + +- [ ] 실시간 대시보드 동작 +- [ ] 자동 리포트 생성 및 발송 +- [ ] 알림 시스템 정상 작동 +- [ ] 이상 탐지 시나리오 검증 +- [ ] 사용자 인수 테스트 통과 + +## 4. Phase 3: Enterprise Grade (2-3개월) + +### 목표 +규제 대응, 감사 추적, 고급 시뮬레이션 + +### 4.1 Week 1-4: audit 구현 + +#### audit 컴포넌트 (4주) + +**우선순위 1: 감사 로그** +- [ ] 감사 이벤트 정의 +- [ ] 불변 로그 저장 (Append-Only) +- [ ] 해시 체인 구현 (무결성 보장) +- [ ] 주요 이벤트 자동 기록 + - [ ] 주문 생성/취소/체결 + - [ ] 설정 변경 + - [ ] 승인/거부 + - [ ] 로그인 + +**우선순위 2: 변경 추적** +- [ ] 엔티티별 변경 이력 +- [ ] Before/After 스냅샷 +- [ ] 변경 사유 기록 + +**우선순위 3: 규제 리포팅** +- [ ] 거래 내역 보고서 +- [ ] 포지션 명세서 +- [ ] 이상 거래 보고서 +- [ ] CSV/JSON 내보내기 + +**우선순위 4: 무결성 검증** +- [ ] 감사 로그 무결성 체크 +- [ ] 해시 체인 검증 +- [ ] 주기적 무결성 검사 스케줄 + +### 4.2 Week 5-8: simulation 구현 + +#### simulation 컴포넌트 (4주) + +**우선순위 1: Paper Trading** +- [ ] 가상 계좌 생성 +- [ ] 가상 주문 체결 엔진 + - [ ] 실시간 호가 기반 체결 시뮬레이션 + - [ ] 슬리피지 모델링 + - [ ] 수수료 계산 +- [ ] 가상 포트폴리오 관리 + +**우선순위 2: 시뮬레이션 환경** +- [ ] 과거 데이터 리플레이 +- [ ] 다중 시나리오 테스트 +- [ ] 스트레스 테스트 + - [ ] 극단 변동성 시나리오 + - [ ] 유동성 부족 시나리오 + - [ ] 블랙스완 이벤트 + +**우선순위 3: 파라미터 최적화** +- [ ] 그리드 서치 +- [ ] 랜덤 서치 +- [ ] 베이지안 최적화 (선택) +- [ ] Walk-Forward 분석 +- [ ] 과최적화 검증 + +**우선순위 4: 실계좌 전환** +- [ ] Paper → Real 전환 검증 +- [ ] 설정 복제 및 검증 +- [ ] 점진적 자산 이전 + +### 4.3 Week 9-12: 최종 통합 및 배포 + +**보안 강화** (2주): +- [ ] 침투 테스트 (Penetration Testing) +- [ ] API 키 관리 강화 +- [ ] 역할 기반 접근 제어 (RBAC) 세밀화 +- [ ] 감사 로그 접근 제어 + +**성능 최적화** (1주): +- [ ] 데이터베이스 쿼리 최적화 +- [ ] 캐싱 전략 개선 +- [ ] API 응답 시간 최적화 +- [ ] 부하 테스트 + +**배포 준비** (2주): +- [ ] 프로덕션 환경 설정 +- [ ] 데이터베이스 마이그레이션 스크립트 +- [ ] 백업 및 복구 절차 수립 +- [ ] 모니터링 및 알림 설정 (Prometheus, Grafana) +- [ ] 장애 복구 계획 (DR Plan) +- [ ] 운영 문서 작성 + +**최종 검증** (1주): +- [ ] 전체 시스템 통합 테스트 +- [ ] 보안 검증 +- [ ] 성능 검증 +- [ ] 사용자 인수 테스트 (UAT) + +### Phase 3 완료 기준 + +- [ ] 모든 거래가 감사 로그에 기록됨 +- [ ] Paper Trading 환경 정상 작동 +- [ ] 파라미터 최적화 기능 검증 +- [ ] 보안 감사 통과 +- [ ] 프로덕션 배포 완료 + +## 5. 마일스톤 + +```mermaid +timeline + title QuantBench 주요 마일스톤 + section Phase 1 + M1.1 : 증권사 API 연동 완료 + M1.2 : 첫 백테스트 성공 + M1.3 : Paper Trading 자동매매 성공 + M1.4 : Phase 1 완료 + section Phase 2 + M2.1 : 실시간 대시보드 런칭 + M2.2 : 자동 리포트 시스템 가동 + M2.3 : Phase 2 완료 + section Phase 3 + M3.1 : 감사 시스템 가동 + M3.2 : Paper Trading 환경 오픈 + M3.3 : 프로덕션 배포 +``` + +| 마일스톤 | 예상 일정 | 주요 산출물 | +|---------|----------|------------| +| **M1.1** | 1개월차 | 한국투자증권 API 연동, 데이터 수집 | +| **M1.2** | 2개월차 | Bold Asset Allocation 전략 백테스트 성공 | +| **M1.3** | 3개월차 | Paper Trading 환경에서 자동매매 | +| **M1.4** | 4개월차 | Phase 1 완료 (MVP) | +| **M2.1** | 5개월차 | 실시간 대시보드 | +| **M2.2** | 6개월차 | 자동 리포트 시스템 | +| **M2.3** | 7개월차 | Phase 2 완료 (Production Ready) | +| **M3.1** | 8개월차 | 감사 시스템 | +| **M3.2** | 9개월차 | Paper Trading 플랫폼 | +| **M3.3** | 10개월차 | 프로덕션 배포 완료 | + +## 6. 리스크 및 대응 방안 + +| 리스크 | 영향 | 확률 | 대응 방안 | +|-------|------|------|----------| +| 증권사 API 변경 | 높음 | 중간 | 추상화 레이어 강화, 다중 증권사 지원 | +| 데이터 품질 문제 | 중간 | 높음 | 데이터 검증 강화, 다중 데이터 소스 | +| 성능 병목 | 중간 | 중간 | 초기부터 부하 테스트, 확장 가능 아키텍처 | +| 보안 취약점 | 높음 | 낮음 | 정기 보안 감사, 침투 테스트 | +| 일정 지연 | 중간 | 높음 | 애자일 방식, 2주 단위 스프린트, 우선순위 조정 | +| 규제 변경 | 중간 | 낮음 | 감사 로그 강화, 유연한 설계 | + +## 7. 추가 고려사항 + +### 7.1 다중 증권사 지원 계획 + +**Phase 1.5 (선택)**: 삼성증권 또는 키움증권 추가 연동 +- 예상 기간: 2-3주 +- BrokerAdapter 패턴 검증 +- 다중 계좌 통합 관리 테스트 + +### 7.2 고급 전략 추가 + +**Phase 2.5 (선택)**: 추가 전략 구현 +- Momentum 전략 +- Value 전략 +- Mean Reversion 전략 +- 각 전략당 2-3주 소요 + +### 7.3 글로벌 시장 지원 + +**Phase 4 (선택)**: 미국 주식 시장 지원 +- Interactive Brokers API 연동 +- 시간대 처리 (타임존) +- 환율 처리 +- 예상 기간: 2-3개월 + +## 8. 성공 지표 (KPI) + +### Phase 1 완료 시 + +- [ ] 시스템 가동률: 95% 이상 +- [ ] API 응답 시간: 평균 < 500ms +- [ ] 주문 처리 성공률: 99% 이상 +- [ ] 백테스트 정확도: 실제 거래 대비 ±1% 이내 + +### Phase 2 완료 시 + +- [ ] 시스템 가동률: 99% 이상 +- [ ] 알림 발송 성공률: 99.5% 이상 +- [ ] 리포트 생성 시간: < 10초 +- [ ] 대시보드 로딩 시간: < 2초 + +### Phase 3 완료 시 + +- [ ] 시스템 가동률: 99.9% 이상 +- [ ] 감사 로그 무결성: 100% +- [ ] Paper Trading 정확도: 실거래 대비 ±0.5% 이내 +- [ ] 보안 취약점: 0건 (Critical/High) + +## 9. 관련 문서 + +- [시스템 개요](./01-overview.md) +- [전체 아키텍처](./02-architecture.md) +- [공통 데이터 모델](./03-data-models.md) +- [주요 워크플로우](./04-workflows.md) + +### 구성요소 상세 문서 +- [Phase 1 컴포넌트](../components/phase1/) +- [Phase 2 컴포넌트](../components/phase2/) +- [Phase 3 컴포넌트](../components/phase3/) diff --git a/specification.md b/specification.md new file mode 100644 index 0000000..efc3a31 --- /dev/null +++ b/specification.md @@ -0,0 +1,1855 @@ +# QuantBench System Specification + +## System Overview + +QuantBench는 개인 투자자를 위한 퀀트 트레이딩 플랫폼으로, 다중 계좌 관리, 전략 기반 자동매매, 리스크 관리, 성과 분석을 통합 제공합니다. 컨테이너 기반 자산 격리를 통해 하나의 계좌에서 여러 전략을 안전하게 병렬 운영할 수 있습니다. + +--- + +## Phase 1: MVP (Minimum Viable Product) + +**목표**: 안전하게 전략을 실행하고 리스크를 통제할 수 있는 기본 시스템 구축 + +### System Architecture + +``` +┌─────────────────────────────────────────────────────┐ +│ User Interface │ +└──────────────────┬──────────────────────────────────┘ + │ +┌──────────────────┴──────────────────────────────────┐ +│ API Gateway │ +└─┬────────┬────────┬────────┬────────┬──────────────┘ + │ │ │ │ │ + ▼ ▼ ▼ ▼ ▼ +┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ +│mgmt│ │stgy│ │schd│ │risk│ │data│ +└─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘ + │ │ │ │ │ + └───────┴───────┴───────┴───────┘ + │ + ▼ + ┌──────────┐ + │ balance │ + └────┬─────┘ + │ + ┌────────────┼────────────┐ + ▼ ▼ ▼ + [API] [API] [API] + 한국투자증권 삼성증권 키움증권 +``` + +--- + +## 📦 Component Specifications - Phase 1 + +### 1. balance (계좌 관리) + +**책임**: 증권사 API 통합 및 계좌 자산 관리 + +#### 주요 기능 + +**1.1 계좌 연동 관리** +- 증권사 API 인증 및 세션 관리 +- 다중 계좌 등록/수정/삭제 +- API 키 암호화 저장 및 갱신 + +**1.2 자산 조회** +``` +getCurrentBalance(accountId: string): Balance + - 원화/외화 현금 잔고 + - 보유 종목별 수량/평가액 + - 매수 가능 금액 + - 출금 가능 금액 + +getPortfolioSnapshot(accountId: string): Portfolio + - 자산 클래스별 비중 (주식/채권/현금 등) + - 종목별 손익률 + - 총 자산 평가액 +``` + +**1.3 시세 조회** +``` +getCurrentPrice(symbol: string): Price + - 현재가, 시가, 고가, 저가 + - 거래량 + - 호가 정보 (매수/매도 5호가) + +getHistoricalPrices(symbol: string, from: Date, to: Date): Price[] + - 일/주/월봉 데이터 + - 조정 가격 (배당, 액면분할 반영) +``` + +**1.4 주문 처리** +``` +placeOrder(order: Order): OrderResult + - 시장가/지정가/조건부 주문 + - 주문 검증 (잔고 확인, 호가 단위 등) + - 주문 번호 반환 + +cancelOrder(orderId: string): boolean + - 미체결 주문 취소 + +getOrderStatus(orderId: string): OrderStatus + - 주문 상태 조회 (접수/체결/취소) + - 부분 체결 정보 +``` + +**1.5 증권사 추상화 인터페이스** +```typescript +interface BrokerAdapter { + connect(credentials: Credentials): Promise + getBalance(accountId: string): Promise + getQuote(symbol: string): Promise + submitOrder(order: Order): Promise + cancelOrder(orderId: string): Promise + getOrderHistory(accountId: string, from: Date): Promise +} + +// 구현체 예시 +class KoreaInvestmentAdapter implements BrokerAdapter { ... } +class SamsungAdapter implements BrokerAdapter { ... } +class KiwoomAdapter implements BrokerAdapter { ... } +``` + +**데이터 모델** +```typescript +interface Account { + id: string + brokerId: string // 증권사 식별자 + accountNumber: string + accountName: string + accountType: 'STOCK' | 'FUTURES' | 'FOREX' + credentials: EncryptedCredentials + isActive: boolean + createdAt: Date +} + +interface Balance { + accountId: string + cash: { + krw: number + usd: number + // ... 기타 통화 + } + positions: Position[] + totalEquity: number + buyingPower: number + timestamp: Date +} + +interface Position { + symbol: string + quantity: number + averagePrice: number + currentPrice: number + marketValue: number + unrealizedPnL: number + realizedPnL: number +} + +interface Order { + orderId?: string + accountId: string + symbol: string + side: 'BUY' | 'SELL' + orderType: 'MARKET' | 'LIMIT' | 'STOP' + quantity: number + price?: number + status: 'PENDING' | 'FILLED' | 'PARTIALLY_FILLED' | 'CANCELLED' | 'REJECTED' + filledQuantity?: number + averageFillPrice?: number + submittedAt?: Date + executedAt?: Date +} +``` + +--- + +### 2. mgmt (컨테이너 관리) + +**책임**: 가상 자산 컨테이너 생성 및 운영 관리 + +#### 주요 기능 + +**2.1 컨테이너 생명주기 관리** +``` +createContainer(config: ContainerConfig): Container + - 계좌 내 자산 할당 + - 컨테이너 설정 (이름, 목표, 제약조건) + - 초기 자산 스냅샷 생성 + +updateContainer(id: string, config: Partial): Container + - 설정 변경 (전략, 리밸런싱 주기 등) + - 변경 이력 기록 + +deleteContainer(id: string): boolean + - 컨테이너 비활성화 + - 자산 원 계좌로 회수 +``` + +**2.2 가상 자산 격리** +``` +allocateAssets(containerId: string, allocation: AssetAllocation): boolean + - 실제 계좌 잔고에서 가상 할당 + - 총 할당 금액 검증 (계좌 잔고 초과 방지) + +getContainerBalance(containerId: string): VirtualBalance + - 컨테이너별 독립 잔고 조회 + - 현금 + 보유 종목 평가 + +reconcileAssets(accountId: string): ReconciliationReport + - 실제 계좌 vs 컨테이너 총합 일치 확인 + - 불일치 시 경고 및 조정 +``` + +**2.3 컨테이너 간 자산 이동** +``` +transferAssets(from: string, to: string, amount: number): Transfer + - 컨테이너 간 현금/종목 이전 + - 거래 기록 생성 + - 양쪽 컨테이너 밸런스 업데이트 +``` + +**2.4 컨테이너 상태 모니터링** +``` +getContainerStatus(containerId: string): ContainerStatus + - 현재 실행 중인 전략 + - 마지막 리밸런싱 일시 + - 활성/비활성 상태 + - 에러/경고 메시지 +``` + +**데이터 모델** +```typescript +interface Container { + id: string + accountId: string + name: string + description?: string + strategyId?: string // 연결된 전략 + + allocation: { + initialAmount: number + currentEquity: number + cashReserve: number // 최소 현금 보유량 + } + + constraints: { + maxSinglePositionPct: number // 단일 종목 최대 비중 + maxDrawdown: number // 최대 허용 낙폭 + allowedAssetClasses: string[] // 투자 가능 자산군 + } + + rebalancing: { + frequency: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'QUARTERLY' + dayOfWeek?: number // WEEKLY인 경우 + dayOfMonth?: number // MONTHLY인 경우 + autoExecute: boolean // 자동 실행 여부 + } + + status: 'ACTIVE' | 'PAUSED' | 'ARCHIVED' + createdAt: Date + lastRebalancedAt?: Date +} + +interface VirtualBalance { + containerId: string + cash: number + positions: Position[] + totalValue: number + availableCash: number // 주문 가능 현금 + allocatedValue: number // 실제 배정받은 금액 +} +``` + +--- + +### 3. strategy (전략 관리) + +**책임**: 투자 전략 구현, 백테스트, 버전 관리 + +#### 주요 기능 + +**3.1 전략 등록 및 관리** +``` +registerStrategy(strategy: StrategyDefinition): Strategy + - 전략 코드/설정 등록 + - 메타데이터 저장 (작성자, 설명, 파라미터) + - 초기 검증 (구문 오류, 필수 메서드 존재) + +updateStrategy(id: string, version: StrategyVersion): Strategy + - 새 버전 생성 + - 이전 버전 보존 (불변성) + - 변경 사항 추적 + +getStrategy(id: string, version?: string): Strategy + - 특정 버전 조회 (미지정 시 최신) +``` + +**3.2 전략 실행 엔진** +``` +calculateSignals(strategyId: string, marketData: MarketData): Signal[] + - 현재 시장 상황 기반 매매 신호 생성 + - 매수/매도/보유 결정 + - 목표 비중 계산 + +generateOrders(containerId: string, signals: Signal[]): Order[] + - 신호를 실제 주문으로 변환 + - 현재 포지션과 목표 포지션 차이 계산 + - 주문 수량/가격 결정 +``` + +**3.3 백테스트** +``` +runBacktest(config: BacktestConfig): BacktestResult + - 과거 데이터 기반 전략 시뮬레이션 + - 거래 비용, 슬리피지 반영 + - 일별 포트폴리오 가치 계산 + +calculateMetrics(backtestResult: BacktestResult): PerformanceMetrics + - 총 수익률, CAGR + - 샤프 비율, 소르티노 비율 + - 최대 낙폭 (MDD) + - 승률, 평균 수익/손실 + - 변동성 (연율화) +``` + +**3.4 전략 파라미터 관리** +``` +getParameters(strategyId: string): Parameter[] + - 전략에서 사용하는 파라미터 목록 + - 파라미터 타입, 기본값, 범위 + +setParameters(strategyId: string, params: Record): void + - 파라미터 값 설정 + - 유효성 검증 +``` + +**전략 인터페이스** +```typescript +interface StrategyInterface { + // 필수 구현 메서드 + initialize(context: StrategyContext): void + generateSignals(data: MarketData): Signal[] + + // 선택적 메서드 + onMarketOpen?(): void + onMarketClose?(): void + onOrderFilled?(order: Order): void +} + +// 내장 전략 예시 +class BoldAssetAllocation implements StrategyInterface { + private params: { + stockAllocation: number // 주식 비중 (0-1) + bondAllocation: number // 채권 비중 (0-1) + rebalanceThreshold: number // 리밸런싱 임계값 + } + + initialize(context: StrategyContext) { + this.params = context.parameters + } + + generateSignals(data: MarketData): Signal[] { + // 현재 포트폴리오와 목표 비중 비교 + // 임계값 초과 시 리밸런싱 신호 생성 + // ... + } +} +``` + +**데이터 모델** +```typescript +interface Strategy { + id: string + name: string + description: string + category: 'ASSET_ALLOCATION' | 'MOMENTUM' | 'VALUE' | 'ARBITRAGE' | 'CUSTOM' + + versions: StrategyVersion[] + currentVersion: string + + parameters: Parameter[] + requiredData: string[] // 필요한 데이터 종류 + + createdBy: string + createdAt: Date + isPublic: boolean +} + +interface StrategyVersion { + version: string // "1.0.0" + code: string // 전략 구현 코드 + changelog?: string + createdAt: Date + backtestResults?: BacktestResult[] +} + +interface Signal { + symbol: string + action: 'BUY' | 'SELL' | 'HOLD' + targetWeight?: number // 목표 비중 (0-1) + targetQuantity?: number // 목표 수량 + reason?: string // 신호 발생 이유 + confidence?: number // 신호 신뢰도 (0-1) + generatedAt: Date +} + +interface BacktestConfig { + strategyId: string + strategyVersion: string + startDate: Date + endDate: Date + initialCapital: number + universe: string[] // 투자 대상 종목 + benchmark?: string // 벤치마크 (예: 'SPY') + + costs: { + commission: number // 거래 수수료 + slippage: number // 슬리피지 (bps) + } +} + +interface BacktestResult { + strategyId: string + config: BacktestConfig + + equity: { + date: Date + value: number + cash: number + positions: Record + }[] + + trades: { + date: Date + symbol: string + action: 'BUY' | 'SELL' + quantity: number + price: number + commission: number + }[] + + metrics: PerformanceMetrics + runAt: Date +} + +interface PerformanceMetrics { + totalReturn: number // % + cagr: number // % + sharpeRatio: number + sortinoRatio: number + maxDrawdown: number // % + volatility: number // % (annualized) + winRate: number // % + avgWin: number // % + avgLoss: number // % + profitFactor: number +} +``` + +--- + +### 4. scheduler (실행 스케줄러) + +**책임**: 전략 실행 자동화 및 리밸런싱 관리 + +#### 주요 기능 + +**4.1 스케줄 관리** +``` +createSchedule(containerId: string, schedule: ScheduleConfig): Schedule + - 컨테이너별 실행 계획 생성 + - Cron 표현식 지원 + - 시장 시간 고려 (장 전/후, 장 중) + +updateSchedule(scheduleId: string, config: Partial): Schedule + - 스케줄 수정 + +pauseSchedule(scheduleId: string): boolean +resumeSchedule(scheduleId: string): boolean + - 일시 정지/재개 +``` + +**4.2 실행 트리거** +``` +executeStrategy(containerId: string, mode: 'AUTO' | 'MANUAL'): Execution + - 전략 실행 시작 + - 신호 생성 → 리스크 체크 → 주문 생성 → 승인 처리 + +scheduleRebalancing(containerId: string): void + - 다음 리밸런싱 일정 등록 + - 시장 휴일 자동 회피 +``` + +**4.3 승인 워크플로우** +``` +requestApproval(execution: Execution): ApprovalRequest + - 사용자 승인 요청 생성 + - 예상 주문 내역, 비용 계산 + - 알림 발송 (이메일/푸시) + +approveExecution(requestId: string, approved: boolean): boolean + - 승인/거부 처리 + - 승인 시 주문 실행 + - 거부 시 로그 기록 + +autoExecuteWithNotification(execution: Execution): ExecutionResult + - 자동 실행 모드 + - 실행 후 결과 알림 +``` + +**4.4 실행 이력 관리** +``` +getExecutionHistory(containerId: string, from: Date): Execution[] + - 과거 실행 기록 조회 + +getExecutionDetail(executionId: string): ExecutionDetail + - 실행 상세 정보 (생성된 주문, 체결 내역) +``` + +**데이터 모델** +```typescript +interface Schedule { + id: string + containerId: string + + trigger: { + type: 'CRON' | 'INTERVAL' | 'EVENT' + expression?: string // Cron: "0 9 * * 1-5" + intervalMinutes?: number + event?: 'MARKET_OPEN' | 'MARKET_CLOSE' + } + + executionMode: 'AUTO' | 'APPROVAL_REQUIRED' + + constraints: { + marketHoursOnly: boolean + skipHolidays: boolean + minIntervalHours?: number // 최소 실행 간격 + } + + isActive: boolean + nextRun?: Date + lastRun?: Date +} + +interface Execution { + id: string + containerId: string + strategyId: string + + status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'RUNNING' | 'COMPLETED' | 'FAILED' + + signals: Signal[] + plannedOrders: Order[] + executedOrders: Order[] + + estimatedCost: { + commission: number + totalValue: number + } + + approvalRequest?: ApprovalRequest + + startedAt?: Date + completedAt?: Date + error?: string +} + +interface ApprovalRequest { + id: string + executionId: string + + summary: { + numOrders: number + buyValue: number + sellValue: number + estimatedCommission: number + } + + orders: Order[] + + requestedAt: Date + expiresAt: Date + approvedAt?: Date + approvedBy?: string + decision?: 'APPROVED' | 'REJECTED' +} +``` + +--- + +### 5. data (데이터 관리) ⭐ NEW + +**책임**: 시계열 데이터 수집, 저장, 제공 + +#### 주요 기능 + +**5.1 데이터 수집** +``` +collectMarketData(symbols: string[], from: Date, to: Date): void + - 외부 데이터 소스에서 시세 수집 + - 일/분봉 데이터 저장 + - 증분 업데이트 (새로운 데이터만) + +updateRealTimeData(symbols: string[]): void + - 실시간 시세 스트리밍 + - 인메모리 캐시 업데이트 +``` + +**5.2 데이터 제공** +``` +getPriceHistory(symbol: string, from: Date, to: Date, interval: Interval): PriceBar[] + - 과거 가격 데이터 조회 + - interval: '1m', '5m', '1h', '1d', '1w', '1M' + +getLatestPrice(symbol: string): Price + - 최신 시세 (캐시 우선) + +getMultipleSymbols(symbols: string[], date: Date): Record + - 특정 일자 여러 종목 시세 + - 백테스트 최적화 +``` + +**5.3 데이터 품질 관리** +``` +validateData(symbol: string, from: Date, to: Date): ValidationReport + - 결측치 검사 + - 이상치 탐지 (급등락, 거래량 0 등) + - 데이터 연속성 확인 + +adjustForCorporateActions(symbol: string): void + - 배당, 액면분할, 병합 반영 + - 조정 가격 계산 + +fillMissingData(symbol: string, method: 'FORWARD_FILL' | 'INTERPOLATE'): void + - 결측치 보정 +``` + +**5.4 데이터 소스 관리** +``` +addDataSource(source: DataSourceConfig): DataSource + - 외부 데이터 제공자 연동 (Yahoo Finance, Alpha Vantage 등) + +syncDataSource(sourceId: string): SyncResult + - 데이터 동기화 + - 충돌 해결 전략 +``` + +**데이터 모델** +```typescript +interface PriceBar { + symbol: string + timestamp: Date + open: number + high: number + low: number + close: number + volume: number + adjustedClose?: number // 조정 종가 +} + +interface DataSource { + id: string + name: string + provider: 'BROKER' | 'YAHOO' | 'ALPHA_VANTAGE' | 'CUSTOM' + + config: { + apiKey?: string + endpoint?: string + rateLimit?: number // requests per minute + } + + coverage: { + symbols: string[] // 지원 종목 + intervals: string[] // 지원 주기 + delay: number // 데이터 지연 시간 (분) + } + + priority: number // 다중 소스 시 우선순위 + isActive: boolean +} + +interface ValidationReport { + symbol: string + period: { from: Date, to: Date } + + issues: { + type: 'MISSING_DATA' | 'OUTLIER' | 'ZERO_VOLUME' | 'PRICE_GAP' + date: Date + description: string + severity: 'LOW' | 'MEDIUM' | 'HIGH' + }[] + + completeness: number // 0-1 + quality: 'EXCELLENT' | 'GOOD' | 'FAIR' | 'POOR' +} +``` + +--- + +### 6. risk (리스크 관리) ⭐ NEW + +**책임**: 포지션 리스크 통제 및 사전 주문 검증 + +#### 주요 기능 + +**6.1 사전 주문 검증 (Pre-Trade Risk Check)** +``` +validateOrder(order: Order, container: Container): RiskCheckResult + - 잔고 충분성 확인 + - 포지션 사이즈 한도 검증 + - 집중도 리스크 평가 + - 레버리지 제한 확인 + +validateOrderBatch(orders: Order[], container: Container): RiskCheckResult[] + - 여러 주문의 통합 리스크 평가 + - 주문 간 상호작용 고려 +``` + +**6.2 포지션 리스크 모니터링** +``` +calculatePositionRisk(containerId: string): PositionRisk + - 포지션별 VaR (Value at Risk) + - 포트폴리오 베타 + - 섹터/산업 집중도 + +checkRiskLimits(containerId: string): LimitViolation[] + - 설정된 리스크 한도 위반 검사 + - 위반 항목 및 심각도 반환 +``` + +**6.3 손절/익절 관리** +``` +setStopLoss(containerId: string, symbol: string, config: StopLossConfig): void + - 종목별 손절 설정 + - 트레일링 스톱 지원 + +setTakeProfit(containerId: string, symbol: string, level: number): void + - 익절 목표 설정 + +checkStopConditions(containerId: string): StopTrigger[] + - 손절/익절 조건 충족 확인 + - 자동 청산 주문 생성 준비 +``` + +**6.4 리스크 한도 설정** +``` +setRiskLimits(containerId: string, limits: RiskLimits): void + - 컨테이너별 리스크 한도 지정 + - 글로벌 한도 vs 개별 한도 + +getRiskProfile(containerId: string): RiskProfile + - 현재 리스크 프로필 조회 + - 한도 대비 현황 +``` + +**6.5 포트폴리오 리스크 분석** +``` +calculatePortfolioVaR(containerId: string, confidence: number, horizon: number): VaRResult + - 포트폴리오 VaR 계산 (역사적 방법, 파라메트릭 방법) + - confidence: 신뢰수준 (예: 0.95, 0.99) + - horizon: 기간 (일) + +calculateCorrelationMatrix(containerId: string): CorrelationMatrix + - 보유 종목 간 상관관계 + - 분산 효과 분석 + +stressTest(containerId: string, scenarios: Scenario[]): StressTestResult[] + - 시나리오별 손실 추정 + - 극단 상황 대비 +``` + +**데이터 모델** +```typescript +interface RiskLimits { + containerId: string + + position: { + maxSinglePositionPct: number // 단일 종목 최대 비중 (%) + maxSectorPct: number // 단일 섹터 최대 비중 (%) + maxTotalLeverage: number // 최대 레버리지 배수 + } + + loss: { + maxDailyLossPct: number // 일일 최대 손실 (%) + maxDrawdownPct: number // 최대 낙폭 (%) + stopLossEnabled: boolean + } + + exposure: { + maxLongExposure: number // 최대 롱 익스포저 + maxShortExposure: number // 최대 숏 익스포저 + maxGrossExposure: number // 최대 총 익스포저 + } +} + +interface RiskCheckResult { + passed: boolean + violations: { + rule: string + severity: 'BLOCKING' | 'WARNING' + message: string + currentValue: number + limitValue: number + }[] + recommendations?: string[] +} + +interface PositionRisk { + containerId: string + + positions: { + symbol: string + marketValue: number + weightPct: number + VaR95: number // 95% 신뢰수준 VaR + beta: number + sector: string + }[] + + portfolio: { + totalValue: number + totalVaR95: number + beta: number + correlationRisk: number // 집중도 점수 + } + + limits: { + type: string + current: number + limit: number + utilizationPct: number + }[] + + calculatedAt: Date +} + +interface StopLossConfig { + type: 'FIXED' | 'TRAILING' | 'TIME_BASED' + + // FIXED: 고정 가격/비율 + fixedPrice?: number + fixedPct?: number // 매수가 대비 % + + // TRAILING: 최고가 대비 추적 + trailingPct?: number + + // TIME_BASED: 기간 경과 후 + holdingPeriodDays?: number + + autoExecute: boolean // 자동 청산 여부 +} + +interface VaRResult { + confidence: number + horizon: number + VaR: number // 금액 + VaRPct: number // 비율 + method: 'HISTORICAL' | 'PARAMETRIC' | 'MONTE_CARLO' + calculatedAt: Date +} + +interface Scenario { + name: string + description: string + changes: { + symbol: string + priceChangePct: number + }[] +} + +interface StressTestResult { + scenario: Scenario + estimatedLoss: number + estimatedLossPct: number + affectedPositions: { + symbol: string + currentValue: number + projectedValue: number + lossPct: number + }[] +} +``` + +--- + +## 🔄 Phase 1 Workflow Example + +**전략 실행 플로우**: +``` +1. [scheduler] 스케줄 트리거 발생 + ↓ +2. [scheduler] 컨테이너 정보 조회 (mgmt) + ↓ +3. [strategy] 신호 생성 (data에서 시세 조회) + ↓ +4. [risk] 사전 리스크 체크 + ├─ PASS → 주문 생성 + └─ FAIL → 실행 중단, 알림 발송 + ↓ +5. [scheduler] 승인 요청 (AUTO인 경우 skip) + ↓ +6. [balance] 주문 제출 + ↓ +7. [mgmt] 컨테이너 밸런스 업데이트 + ↓ +8. [scheduler] 실행 결과 기록 및 알림 +``` + +--- + +## Phase 2: Production Ready + +**목표**: 실전 운영을 위한 모니터링, 분석, 알림 체계 구축 + +### Additional Components + +--- + +## 📦 Component Specifications - Phase 2 + +### 7. analytics (성과 분석 및 리포팅) ⭐ NEW + +**책임**: 실거래 성과 측정 및 리포팅 + +#### 주요 기능 + +**7.1 성과 측정** +``` +calculatePerformance(containerId: string, period: DateRange): PerformanceReport + - 기간별 수익률 (일/주/월/분기/연) + - 벤치마크 대비 초과 수익 + - 리스크 조정 수익률 (샤프, 소르티노) + +getReturnsTimeseries(containerId: string, from: Date): TimeseriesData + - 일별 수익률 시계열 + - 누적 수익률 차트 데이터 +``` + +**7.2 귀속 분석 (Attribution Analysis)** +``` +analyzeReturns(containerId: string, period: DateRange): AttributionReport + - 수익 원천 분해 + - 자산 배분 효과 + - 종목 선택 효과 + - 타이밍 효과 + - 섹터/테마별 기여도 +``` + +**7.3 거래 분석** +``` +analyzeTrades(containerId: string, from: Date): TradeAnalysis + - 총 거래 건수, 거래 회전율 + - 승률, 손익비 + - 평균 보유 기간 + - 최대 연속 수익/손실 + +calculateTradingCosts(containerId: string, period: DateRange): CostAnalysis + - 총 수수료 + - 슬리피지 추정 + - 세금 (양도소득세 등) + - 순수익률 (비용 차감 후) +``` + +**7.4 리포트 생성** +``` +generateReport(containerId: string, type: ReportType, period: DateRange): Report + - type: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'QUARTERLY' | 'ANNUAL' + - PDF/HTML 형식 + - 자동 이메일 발송 옵션 + +scheduleReport(config: ReportSchedule): void + - 정기 리포트 자동 생성 +``` + +**7.5 벤치마크 비교** +``` +compareWithBenchmark(containerId: string, benchmarkSymbol: string, period: DateRange): ComparisonReport + - 누적 수익률 비교 + - 추적 오차 (Tracking Error) + - 정보 비율 (Information Ratio) + - 상승/하락 시장 성과 +``` + +**데이터 모델** +```typescript +interface PerformanceReport { + containerId: string + period: DateRange + + returns: { + total: number // % + annualized: number // CAGR + daily: number + weekly: number + monthly: number + ytd: number + } + + risk: { + volatility: number // annualized + sharpeRatio: number + sortinoRatio: number + maxDrawdown: number + calmarRatio: number + } + + benchmark?: { + symbol: string + returns: number + excessReturn: number + beta: number + alpha: number + trackingError: number + informationRatio: number + } + + generatedAt: Date +} + +interface AttributionReport { + containerId: string + period: DateRange + + totalReturn: number + + attribution: { + assetAllocation: number // 자산 배분 효과 + stockSelection: number // 종목 선택 효과 + timing: number // 타이밍 효과 + interaction: number // 상호작용 효과 + } + + sectorContribution: { + sector: string + weight: number + return: number + contribution: number + }[] + + topContributors: { + symbol: string + contribution: number + }[] + + topDetractors: { + symbol: string + contribution: number + }[] +} + +interface TradeAnalysis { + containerId: string + period: DateRange + + summary: { + totalTrades: number + winningTrades: number + losingTrades: number + winRate: number // % + + avgWin: number // % + avgLoss: number // % + profitFactor: number // avgWin / avgLoss + + avgHoldingPeriod: number // days + turnoverRate: number // annualized + } + + longestWinStreak: number + longestLossStreak: number + + largestWin: { + symbol: string + return: number + date: Date + } + + largestLoss: { + symbol: string + return: number + date: Date + } +} + +interface CostAnalysis { + period: DateRange + + costs: { + commission: number + estimatedSlippage: number + tax: number + other: number + total: number + } + + impact: { + grossReturn: number + netReturn: number + costDrag: number // bps + } + + costByType: { + buy: number + sell: number + } +} + +interface Report { + id: string + containerId: string + type: ReportType + period: DateRange + + sections: { + summary: PerformanceSummary + positions: CurrentPositions + trades: RecentTrades + performance: PerformanceCharts + attribution: AttributionAnalysis + risk: RiskMetrics + } + + format: 'PDF' | 'HTML' | 'JSON' + fileUrl?: string + generatedAt: Date +} +``` + +--- + +### 8. monitor (모니터링 및 알림) ⭐ NEW + +**책임**: 시스템 상태 감시 및 이상 탐지 + +#### 주요 기능 + +**8.1 시스템 헬스 체크** +``` +checkSystemHealth(): HealthStatus + - 각 컴포넌트 상태 확인 + - API 연결 상태 + - 데이터베이스 응답 시간 + - 메모리/CPU 사용률 + +monitorApiConnections(): ConnectionStatus[] + - 증권사 API 연결 상태 + - 데이터 소스 연결 상태 + - 마지막 성공 시간 + - 실패 시 재연결 시도 +``` + +**8.2 이상 거래 탐지** +``` +detectAnomalies(containerId: string): Anomaly[] + - 급격한 포지션 변화 (설정치 초과) + - 비정상적 주문 크기 + - 예상치 못한 체결 + - 시장 충격 (market impact) 과다 + +checkMarketConditions(): MarketAlert[] + - 극심한 변동성 + - 유동성 부족 + - 서킷브레이커 발동 + - 시장 전체 급락/급등 +``` + +**8.3 알림 관리** +``` +sendAlert(alert: Alert): void + - 채널별 알림 발송 (이메일/SMS/푸시/Slack) + - 중요도별 라우팅 + - 알림 이력 저장 + +configureAlertRules(rules: AlertRule[]): void + - 알림 조건 설정 + - 임계값, 빈도 제한 + - 수신자 그룹 관리 + +getAlertHistory(from: Date, severity?: AlertSeverity): Alert[] + - 과거 알림 조회 + - 필터링 및 검색 +``` + +**8.4 대시보드 데이터** +``` +getDashboardData(): DashboardSnapshot + - 전체 계좌 요약 + - 컨테이너별 상태 + - 최근 실행 이력 + - 활성 알림 + +getRealtimeMetrics(containerId: string): RealtimeMetrics + - 현재 P&L + - 당일 수익률 + - 포지션 변화 + - 리스크 지표 +``` + +**8.5 성능 모니터링** +``` +trackLatency(operation: string, duration: number): void + - 주요 작업 소요 시간 추적 + - 주문 처리 지연 모니터링 + +logError(error: Error, context: any): void + - 에러 로깅 및 분류 + - 스택 트레이스 저장 + - 재발 패턴 분석 +``` + +**데이터 모델** +```typescript +interface HealthStatus { + overall: 'HEALTHY' | 'DEGRADED' | 'DOWN' + + components: { + name: string + status: 'UP' | 'DOWN' | 'SLOW' + responseTime?: number // ms + lastCheck: Date + message?: string + }[] + + connections: { + broker: 'CONNECTED' | 'DISCONNECTED' | 'ERROR' + database: 'CONNECTED' | 'DISCONNECTED' + dataProviders: Record + } + + resources: { + cpuUsage: number // % + memoryUsage: number // % + diskUsage: number // % + } + + checkedAt: Date +} + +interface Anomaly { + type: 'POSITION_SPIKE' | 'UNUSUAL_ORDER' | 'UNEXPECTED_FILL' | 'HIGH_IMPACT' + severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' + + containerId: string + description: string + + details: { + expected?: any + actual: any + threshold?: any + } + + detectedAt: Date + resolved: boolean +} + +interface Alert { + id: string + type: 'SYSTEM' | 'RISK' | 'EXECUTION' | 'PERFORMANCE' | 'ANOMALY' + severity: 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL' + + title: string + message: string + + source: string // 발생 컴포넌트 + containerId?: string + + channels: ('EMAIL' | 'SMS' | 'PUSH' | 'SLACK')[] + sentAt?: Date + + acknowledged: boolean + acknowledgedAt?: Date + acknowledgedBy?: string + + createdAt: Date +} + +interface AlertRule { + id: string + name: string + description: string + + condition: { + metric: string // 'drawdown', 'dailyLoss', 'positionSize', etc. + operator: '>' | '<' | '=' | '>=' | '<=' + threshold: number + } + + severity: AlertSeverity + channels: AlertChannel[] + + throttle: { + enabled: boolean + minIntervalMinutes: number // 최소 알림 간격 + } + + isActive: boolean +} + +interface DashboardSnapshot { + accounts: { + accountId: string + totalEquity: number + cashBalance: number + todayPnL: number + todayReturn: number + }[] + + containers: { + containerId: string + name: string + status: 'ACTIVE' | 'PAUSED' + equity: number + todayReturn: number + activeStrategy: string + lastRebalanced: Date + }[] + + recentExecutions: { + executionId: string + containerId: string + status: string + completedAt: Date + }[] + + activeAlerts: Alert[] + + systemHealth: 'HEALTHY' | 'DEGRADED' | 'DOWN' + + timestamp: Date +} + +interface RealtimeMetrics { + containerId: string + + current: { + equity: number + cash: number + positionsCount: number + } + + today: { + pnl: number + return: number + tradesCount: number + } + + risk: { + currentDrawdown: number + VaR95: number + leverage: number + } + + updatedAt: Date +} +``` + +--- + +## 🔄 Phase 2 Enhanced Workflow + +**성과 모니터링 플로우**: +``` +1. [scheduler] 전략 실행 완료 + ↓ +2. [analytics] 실시간 성과 계산 + ├─ 일일 수익률 업데이트 + ├─ 리스크 지표 재계산 + └─ 벤치마크 대비 성과 비교 + ↓ +3. [monitor] 이상 탐지 + ├─ 급격한 손실 → CRITICAL 알림 + ├─ 리스크 한도 근접 → WARNING 알림 + └─ 정상 범위 → 로그만 기록 + ↓ +4. [monitor] 대시보드 업데이트 + ↓ +5. [analytics] 정기 리포트 생성 (일정에 따라) +``` + +--- + +## Phase 3: Enterprise Grade + +**목표**: 규제 대응, 감사 추적, 고급 시뮬레이션 + +### Additional Components + +--- + +## 📦 Component Specifications - Phase 3 + +### 9. audit (감사 및 로깅) ⭐ NEW + +**책임**: 불변 감사 로그 및 규제 리포팅 + +#### 주요 기능 + +**9.1 감사 로그 기록** +``` +logEvent(event: AuditEvent): void + - 모든 중요 이벤트 불변 저장 + - 타임스탬프, 사용자, 작업 내용 + - 변경 전/후 데이터 + +logOrderActivity(order: Order, action: OrderAction): void + - 주문 생성/수정/취소/체결 + - 호가 정보 스냅샷 + - 결정 근거 (전략 신호) +``` + +**9.2 변경 이력 추적** +``` +trackConfigChange(entity: string, entityId: string, changes: any): void + - 컨테이너 설정 변경 + - 전략 파라미터 수정 + - 리스크 한도 조정 + +getChangeHistory(entity: string, entityId: string): ChangeLog[] + - 시간순 변경 이력 + - 변경자, 사유 포함 +``` + +**9.3 규제 리포팅** +``` +generateComplianceReport(type: ComplianceReportType, period: DateRange): ComplianceReport + - 거래 내역 보고서 + - 포지션 보유 명세 + - 이상 거래 탐지 결과 + +exportAuditTrail(from: Date, to: Date, format: 'CSV' | 'JSON'): File + - 감사 추적 데이터 추출 + - 외부 감사 대비 +``` + +**9.4 데이터 보존 정책** +``` +archiveOldData(cutoffDate: Date): ArchiveResult + - 오래된 데이터 아카이브 + - 빠른 조회용 DB vs 장기 보관용 스토리지 + +retainCriticalData(dataType: string, retentionYears: number): void + - 법적 보존 기간 관리 + - 자동 삭제 방지 +``` + +**9.5 무결성 검증** +``` +verifyAuditIntegrity(from: Date, to: Date): IntegrityReport + - 감사 로그 변조 검사 + - 체인 연속성 확인 + - 해시 검증 +``` + +**데이터 모델** +```typescript +interface AuditEvent { + id: string + timestamp: Date + + eventType: 'ORDER' | 'CONFIG_CHANGE' | 'EXECUTION' | 'LOGIN' | 'DATA_EXPORT' + action: string // 'CREATE', 'UPDATE', 'DELETE', 'EXECUTE' + + userId?: string + containerId?: string + + entity: string // 'Container', 'Strategy', 'Order', etc. + entityId: string + + before?: any // 변경 전 상태 + after?: any // 변경 후 상태 + + metadata: { + ipAddress?: string + userAgent?: string + reason?: string + } + + hash: string // 무결성 검증용 + previousHash?: string // 이전 이벤트 해시 (체인) +} + +interface ChangeLog { + timestamp: Date + changedBy: string + field: string + oldValue: any + newValue: any + reason?: string +} + +interface ComplianceReport { + type: 'TRADE_HISTORY' | 'POSITION_STATEMENT' | 'UNUSUAL_ACTIVITY' + period: DateRange + + trades: { + date: Date + orderId: string + symbol: string + side: 'BUY' | 'SELL' + quantity: number + price: number + value: number + }[] + + positions: { + symbol: string + quantity: number + averagePrice: number + marketValue: number + unrealizedPnL: number + }[] + + unusualActivities: { + date: Date + type: string + description: string + resolution: string + }[] + + generatedAt: Date + certifiedBy?: string +} + +interface IntegrityReport { + period: DateRange + totalEvents: number + + verification: { + hashChainValid: boolean + noGaps: boolean + noModifications: boolean + } + + issues: { + eventId: string + issue: string + severity: 'LOW' | 'HIGH' + }[] + + overall: 'PASS' | 'FAIL' + verifiedAt: Date +} +``` + +--- + +### 10. simulation (시뮬레이션 환경) ⭐ NEW + +**책임**: 실전 배포 전 안전한 테스트 환경 제공 + +#### 주요 기능 + +**10.1 Paper Trading** +``` +createPaperAccount(config: PaperAccountConfig): PaperAccount + - 가상 계좌 생성 + - 초기 자본금 설정 + - 실시간 시세 연동 + +executePaperTrade(order: Order): PaperOrderResult + - 가상 주문 실행 + - 실제 호가 기반 체결 시뮬레이션 + - 슬리피지 모델링 +``` + +**10.2 전략 시뮬레이션** +``` +runSimulation(config: SimulationConfig): SimulationResult + - 특정 기간 실전 시뮬레이션 + - 다양한 시장 시나리오 테스트 + - 컨테이너 설정 검증 + +compareStrategies(strategyIds: string[], config: SimulationConfig): ComparisonResult + - 여러 전략 동시 비교 + - 동일 조건 시뮬레이션 + - 상대 성과 분석 +``` + +**10.3 파라미터 최적화** +``` +optimizeParameters(strategyId: string, searchSpace: ParameterSpace): OptimizationResult + - 그리드 서치 + - 랜덤 서치 + - 베이지안 최적화 + - 유전 알고리즘 + +validateOptimization(result: OptimizationResult, outOfSampleData: MarketData): ValidationResult + - 과최적화 검증 + - Out-of-sample 테스트 + - 워크포워드 분석 +``` + +**10.4 시나리오 테스트** +``` +testScenario(containerId: string, scenario: Scenario): ScenarioResult + - 특정 시장 상황 시뮬레이션 + - 블랙스완 이벤트 대비 + - 극단 변동성 테스트 + +runMonteCarloSimulation(containerId: string, iterations: number): MonteCarloResult + - 확률적 시뮬레이션 + - 수익률 분포 추정 + - 최악 시나리오 확률 +``` + +**10.5 전환 지원** +``` +promoteToProd(paperAccountId: string, realAccountId: string): MigrationPlan + - Paper → 실계좌 전환 계획 + - 설정 검증 + - 리스크 재확인 + +cloneContainer(sourceId: string, targetAccountId: string): Container + - 검증된 설정 복제 + - 실계좌 적용 +``` + +**데이터 모델** +```typescript +interface PaperAccount { + id: string + name: string + + balance: { + initialCash: number + currentCash: number + positions: Position[] + totalEquity: number + } + + settings: { + commissionModel: 'FIXED' | 'PERCENTAGE' + commissionRate: number + slippageModel: 'FIXED_BPS' | 'VOLUME_BASED' + slippageBps: number + } + + isActive: boolean + createdAt: Date +} + +interface SimulationConfig { + strategyId: string + startDate: Date + endDate: Date + + initialCapital: number + universe: string[] + + costs: { + commission: number + slippage: number + tax: number + } + + constraints: RiskLimits + + rebalanceFrequency: string +} + +interface SimulationResult { + config: SimulationConfig + + performance: PerformanceMetrics + + equity: { + date: Date + value: number + }[] + + trades: { + date: Date + symbol: string + action: 'BUY' | 'SELL' + quantity: number + price: number + }[] + + drawdowns: { + start: Date + end: Date + depth: number // % + recovery: number // days + }[] + + completedAt: Date +} + +interface ParameterSpace { + parameters: { + name: string + type: 'INTEGER' | 'FLOAT' | 'CATEGORICAL' + min?: number + max?: number + step?: number + values?: any[] + }[] +} + +interface OptimizationResult { + strategyId: string + searchSpace: ParameterSpace + + bestParameters: Record + bestMetric: number // 최적화 목표 지표값 + + trials: { + parameters: Record + metrics: PerformanceMetrics + }[] + + optimizationTime: number // seconds + + warnings: { + overfitting: boolean + insufficientData: boolean + unstableParameters: string[] + } +} + +interface MonteCarloResult { + iterations: number + + returns: { + mean: number + median: number + std: number + percentiles: { + p5: number + p25: number + p75: number + p95: number + } + } + + drawdowns: { + mean: number + max: number + percentiles: { + p95: number + p99: number + } + } + + probabilities: { + profit: number // 수익 확률 + loss10pct: number // 10% 이상 손실 확률 + loss20pct: number + } + + distribution: number[] // 수익률 히스토그램 +} +``` + +--- + +## 🔄 Phase 3 Advanced Workflow + +**전략 검증 및 배포 플로우**: +``` +1. [simulation] Paper Trading 시작 + ├─ 가상 계좌 생성 + └─ 실시간 시세 연동 + ↓ +2. [simulation] 1개월 Paper Trading 실행 + ├─ [strategy] 신호 생성 + ├─ [risk] 리스크 체크 + └─ [simulation] 가상 주문 체결 + ↓ +3. [analytics] Paper Trading 성과 분석 + ├─ 수익률, 리스크 지표 계산 + └─ 백테스트 vs 실시간 비교 + ↓ +4. [simulation] 파라미터 최적화 (필요 시) + ├─ 그리드 서치 실행 + └─ Out-of-sample 검증 + ↓ +5. [simulation] 스트레스 테스트 + ├─ 극단 시나리오 시뮬레이션 + └─ 몬테카를로 시뮬레이션 + ↓ +6. [simulation] 실계좌 전환 계획 생성 + ├─ 설정 검증 + └─ 리스크 재확인 + ↓ +7. [audit] 전환 승인 및 기록 + ↓ +8. [mgmt] 실계좌 컨테이너 생성 + ↓ +9. [scheduler] 자동 실행 시작 + ↓ +10. [monitor] 지속적 모니터링 + └─ [audit] 모든 활동 기록 +``` + +--- + +## 📊 Final System Architecture (All Phases) + +``` +┌────────────────────────────────────────────────────────────┐ +│ User Interface │ +│ (Web/Mobile Dashboard, Reports, Alerts, Admin Panel) │ +└────────────────────────┬───────────────────────────────────┘ + │ +┌────────────────────────┴───────────────────────────────────┐ +│ API Gateway │ +│ (Authentication, Rate Limiting) │ +└─┬────┬────┬────┬────┬────┬────┬────┬────┬────┬───────────┘ + │ │ │ │ │ │ │ │ │ │ + ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ +┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐ +│mgt││stg││sch││rsk││dat││ana││mon││aud││sim││bal│ +└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘ + │ │ │ │ │ │ │ │ │ │ + └────┴────┴────┴────┴────┴────┴────┴────┴────┘ + │ + ┌────────────────┼────────────────┐ + │ │ │ + ▼ ▼ ▼ + ┌─────────┐ ┌─────────┐ ┌─────────┐ + │Message │ │Database │ │ Cache │ + │ Queue │ │ Cluster │ │ (Redis) │ + └─────────┘ └─────────┘ └─────────┘ + │ + ┌────────────┼────────────┐ + ▼ ▼ ▼ + [Broker [Broker [Broker + API 1] API 2] API 3] +``` + +**Component Legend**: +- **mgt**: Container Management +- **stg**: Strategy Management +- **sch**: Scheduler +- **rsk**: Risk Management +- **dat**: Data Management +- **ana**: Analytics +- **mon**: Monitor +- **aud**: Audit +- **sim**: Simulation +- **bal**: Balance (Broker Integration) + +--- + +## 🎯 Implementation Roadmap + +### Phase 1 Timeline (3-4 months) +- Week 1-4: balance + data 기본 구현 +- Week 5-8: mgmt + strategy 핵심 기능 +- Week 9-12: scheduler + risk +- Week 13-16: 통합 테스트 및 버그 수정 + +### Phase 2 Timeline (2-3 months) +- Week 1-4: analytics 구현 +- Week 5-8: monitor + 알림 시스템 +- Week 9-12: 대시보드 및 리포팅 + +### Phase 3 Timeline (2-3 months) +- Week 1-4: audit 시스템 +- Week 5-8: simulation 환경 +- Week 9-12: 최종 통합 및 규제 대응