| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- using System.ComponentModel.DataAnnotations;
- using Domain.Entities.Stocks.ValueObject;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// 선물(일반선물/주식선물유가/주식선물코스닥) 일별매매 시세 (KRX OpenAPI drv 엔드포인트) — (FuturesKind, Code, TradeDate) UNIQUE.
- /// 세 상품군을 한 테이블에 담고 FuturesKind 로 구분한다. 선물은 옵션과 달리 정산가(SETL_PRC)·현물가(SPOT_PRC)·미결제약정(ACC_OPNINT_QTY)을 갖는다:
- /// - 가격/전일대비: TDD_CLSPRC/OPNPRC/HGPRC/LWPRC + CMPPREVDD_PRC (주식과 동일). 미체결 시 종가/시고저는 "" → 0.
- /// - 선물 고유: ProductName(PROD_NM 상품구분 예: "10년국채 선물"), MarketName(MKT_NM 정규/야간), SpotPrice(SPOT_PRC 현물가, nullable),
- /// SettlePrice(SETL_PRC 정산가, nullable — 스프레드 종목은 미제공), OpenInterest(ACC_OPNINT_QTY 미결제약정, nullable).
- /// 종목코드(ISU_CD)는 8자리 영숫자(예: 167W3000) — 6자리 정규화 없이 원문 유지. 가격은 decimal(18,2).
- /// </summary>
- public class FuturesDailyTrade
- {
- [Key]
- public long ID { get; private set; }
- /// <summary>선물 상품군 구분 (1=일반선물, 2=주식선물유가, 3=주식선물코스닥)</summary>
- public FuturesKind FuturesKind { get; private set; }
- /// <summary>종목코드 (ISU_CD) — 8자리 영숫자(예: 167W3000)</summary>
- public string IsuCode { get; private set; } = default!;
- /// <summary>종목명 (ISU_NM)</summary>
- public string IsuName { get; private set; } = default!;
- /// <summary>거래일 (BAS_DD)</summary>
- public DateOnly TradeDate { get; private set; }
- /// <summary>종가 (TDD_CLSPRC) — 미체결 시 0</summary>
- public decimal Close { get; private set; }
- /// <summary>시가 (TDD_OPNPRC) — 미체결 시 0</summary>
- public decimal Open { get; private set; }
- /// <summary>고가 (TDD_HGPRC) — 미체결 시 0</summary>
- public decimal High { get; private set; }
- /// <summary>저가 (TDD_LWPRC) — 미체결 시 0</summary>
- public decimal Low { get; private set; }
- /// <summary>전일 대비 (CMPPREVDD_PRC) — 미제공("") 시 0</summary>
- public decimal ChangeAmount { get; private set; }
- /// <summary>현물가 (SPOT_PRC) — 미제공 시 null</summary>
- public decimal? SpotPrice { get; private set; }
- /// <summary>정산가 (SETL_PRC) — 스프레드 종목 등 미제공 시 null</summary>
- public decimal? SettlePrice { get; private set; }
- /// <summary>거래량 (ACC_TRDVOL)</summary>
- public long Volume { get; private set; }
- /// <summary>거래대금 (ACC_TRDVAL, 원)</summary>
- public long TradeValue { get; private set; }
- /// <summary>미결제약정 (ACC_OPNINT_QTY) — 미제공("") 시 null</summary>
- public long? OpenInterest { get; private set; }
- /// <summary>상품구분 (PROD_NM 예: "10년국채 선물")</summary>
- public string? ProductName { get; private set; }
- /// <summary>시장구분 (MKT_NM 정규/야간)</summary>
- public string? MarketName { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- private FuturesDailyTrade() { }
- public static FuturesDailyTrade Create(
- FuturesKind futuresKind,
- string isuCode,
- string isuName,
- DateOnly tradeDate,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal? spotPrice,
- decimal? settlePrice,
- long volume,
- long tradeValue,
- long? openInterest,
- string? productName = null,
- string? marketName = null
- ) {
- if (!Enum.IsDefined(futuresKind))
- {
- throw new ArgumentOutOfRangeException(nameof(futuresKind));
- }
- if (string.IsNullOrWhiteSpace(isuCode))
- {
- throw new ArgumentException("isuCode required", nameof(isuCode));
- }
- if (string.IsNullOrWhiteSpace(isuName))
- {
- throw new ArgumentException("isuName required", nameof(isuName));
- }
- return new FuturesDailyTrade
- {
- FuturesKind = futuresKind,
- IsuCode = isuCode.Trim(),
- IsuName = isuName.Trim(),
- TradeDate = tradeDate,
- Close = close,
- Open = open,
- High = high,
- Low = low,
- ChangeAmount = changeAmount,
- SpotPrice = spotPrice,
- SettlePrice = settlePrice,
- Volume = volume,
- TradeValue = tradeValue,
- OpenInterest = openInterest,
- ProductName = productName,
- MarketName = marketName
- };
- }
- /// <summary>동일 (FuturesKind, IsuCode, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
- public void Update(
- string isuName,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal? spotPrice,
- decimal? settlePrice,
- long volume,
- long tradeValue,
- long? openInterest,
- string? productName = null,
- string? marketName = null
- ) {
- IsuName = isuName.Trim();
- Close = close;
- Open = open;
- High = high;
- Low = low;
- ChangeAmount = changeAmount;
- SpotPrice = spotPrice;
- SettlePrice = settlePrice;
- Volume = volume;
- TradeValue = tradeValue;
- OpenInterest = openInterest;
- ProductName = productName;
- MarketName = marketName;
- }
- }
|