Files
system-specs/docs/03-data-models.md

20 KiB

QuantBench 공통 데이터 모델

이 문서는 시스템 전반에서 사용되는 핵심 데이터 모델을 정의합니다.

1. 계좌 및 자산 관련

1.1 Account (계좌)

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 (잔고)

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 (포지션)

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 (컨테이너)

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 (가상 잔고)

interface VirtualBalance {
  containerId: string          // 컨테이너 ID
  cash: number                 // 현금
  positions: Position[]        // 보유 종목
  totalValue: number           // 총 가치
  availableCash: number        // 주문 가능 현금
  allocatedValue: number       // 할당받은 금액
  timestamp: Date             // 조회 시점
}

3. 전략 관련

3.1 Strategy (전략)

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 (매매 신호)

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 (백테스트 결과)

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 (주문)

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 (가격 바)

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 (현재가)

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 (리스크 한도)

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 (리스크 검증 결과)

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 (스케줄)

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 (실행)

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 (성과 지표)

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 (알림)

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 (감사 이벤트)

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. 데이터 관계도

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. 관련 문서