657 lines
20 KiB
Markdown
657 lines
20 KiB
Markdown
# 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<string, any> // 추가 메타데이터
|
|
}
|
|
|
|
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<string, number> // 보유 종목 (종목코드: 수량)
|
|
}
|
|
|
|
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<string, any> // 추가 메타데이터
|
|
}
|
|
|
|
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<string, any> // 추가 메타데이터
|
|
}
|
|
|
|
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)
|