| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- using System.ComponentModel.DataAnnotations;
- using Domain.Entities.Stocks.ValueObject;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// 신주인수권증권/증서 일별매매 시세 (KRX OpenAPI sto 엔드포인트) — (WarrantType, Code, TradeDate) UNIQUE.
- /// 두 상품을 한 테이블에 담고 WarrantType 으로 구분한다. 공통 컬럼(가격/거래/시총) + 대상주식 정보 + 유형별 nullable 컬럼:
- /// - 증권(SubscriptionWarrant, sw_bydd_trd): ExercisePrice(행사가 EXER_PRC), ExerciseStartDate·ExerciseEndDate(행사기간 EXST_STRT_DD/EXST_END_DD)
- /// - 증서(SubscriptionRight, sr_bydd_trd): IssuePrice(발행가 ISU_PRC), DelistDate(상장폐지일 DELIST_DD — 증서는 단기 상장)
- /// 대상주식(공통): TargetStockCode(TARSTK_ISU_SRT_CD), TargetStockName(TARSTK_ISU_NM), TargetStockPrice(TARSTK_ISU_PRSNT_PRC).
- /// 등락률(ChangeRate)은 KrxStockParser 와 동일하게 소수 % 그대로 저장(Bp 아님).
- /// 가격은 decimal(18,2) — 증권/증서 가격은 정수지만 EtpDailyTrade 와 스케일 통일.
- /// 단축코드(ISU_CD)는 8자리 영숫자(예: 1099621D / 1013601E) — 6자리 종목코드가 아니다.
- /// </summary>
- public class WarrantDailyTrade
- {
- [Key]
- public long ID { get; private set; }
- /// <summary>신주인수권 구분 (1=증권 SubscriptionWarrant, 2=증서 SubscriptionRight)</summary>
- public WarrantType WarrantType { get; private set; }
- /// <summary>단축코드 (ISU_CD) — 8자리 영숫자(예: 1099621D)</summary>
- public string Code { get; private set; } = default!;
- /// <summary>종목명 (ISU_NM)</summary>
- public string Name { get; private set; } = default!;
- /// <summary>시장 구분 (1=KOSPI, 2=KOSDAQ, 3=KONEX) — 응답 MKT_NM 기준</summary>
- public StockMarket Market { get; private set; }
- /// <summary>거래일 (BAS_DD)</summary>
- public DateOnly TradeDate { get; private set; }
- /// <summary>종가 (TDD_CLSPRC)</summary>
- public decimal Close { get; private set; }
- /// <summary>시가 (TDD_OPNPRC)</summary>
- public decimal Open { get; private set; }
- /// <summary>고가 (TDD_HGPRC)</summary>
- public decimal High { get; private set; }
- /// <summary>저가 (TDD_LWPRC)</summary>
- public decimal Low { get; private set; }
- /// <summary>전일 대비 (CMPPREVDD_PRC)</summary>
- public decimal ChangeAmount { get; private set; }
- /// <summary>등락률 % (FLUC_RT)</summary>
- public decimal ChangeRate { get; private set; }
- /// <summary>거래량 (ACC_TRDVOL)</summary>
- public long Volume { get; private set; }
- /// <summary>거래대금 (ACC_TRDVAL, 원)</summary>
- public long TradeValue { get; private set; }
- /// <summary>시가총액 (MKTCAP, 원) — 미제공 시 null</summary>
- public long? MarketCap { get; private set; }
- /// <summary>상장증권수 (LIST_SHRS) — 미제공 시 null</summary>
- public long? ListedShares { get; private set; }
- /// <summary>대상주식 단축코드 (TARSTK_ISU_SRT_CD) — 미제공 시 null</summary>
- public string? TargetStockCode { get; private set; }
- /// <summary>대상주식명 (TARSTK_ISU_NM) — 미제공 시 null</summary>
- public string? TargetStockName { get; private set; }
- /// <summary>대상주식 현재가 (TARSTK_ISU_PRSNT_PRC) — 미제공 시 null</summary>
- public decimal? TargetStockPrice { get; private set; }
- /// <summary>행사가 (EXER_PRC) — 증권만. 증서는 null</summary>
- public decimal? ExercisePrice { get; private set; }
- /// <summary>행사 시작일 (EXST_STRT_DD) — 증권만. 증서는 null</summary>
- public DateOnly? ExerciseStartDate { get; private set; }
- /// <summary>행사 종료일 (EXST_END_DD) — 증권만. 증서는 null</summary>
- public DateOnly? ExerciseEndDate { get; private set; }
- /// <summary>발행가 (ISU_PRC) — 증서만. 증권은 null</summary>
- public decimal? IssuePrice { get; private set; }
- /// <summary>상장폐지일 (DELIST_DD) — 증서만(단기 상장). 증권은 null</summary>
- public DateOnly? DelistDate { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- private WarrantDailyTrade() { }
- public static WarrantDailyTrade Create(
- WarrantType warrantType,
- string code,
- string name,
- StockMarket market,
- DateOnly tradeDate,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal changeRate,
- long volume,
- long tradeValue,
- long? marketCap = null,
- long? listedShares = null,
- string? targetStockCode = null,
- string? targetStockName = null,
- decimal? targetStockPrice = null,
- decimal? exercisePrice = null,
- DateOnly? exerciseStartDate = null,
- DateOnly? exerciseEndDate = null,
- decimal? issuePrice = null,
- DateOnly? delistDate = null
- ) {
- if (!Enum.IsDefined(warrantType))
- {
- throw new ArgumentOutOfRangeException(nameof(warrantType));
- }
- if (string.IsNullOrWhiteSpace(code))
- {
- throw new ArgumentException("code required", nameof(code));
- }
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentException("name required", nameof(name));
- }
- return new WarrantDailyTrade
- {
- WarrantType = warrantType,
- Code = code.Trim(),
- Name = name.Trim(),
- Market = market,
- TradeDate = tradeDate,
- Close = close,
- Open = open,
- High = high,
- Low = low,
- ChangeAmount = changeAmount,
- ChangeRate = changeRate,
- Volume = volume,
- TradeValue = tradeValue,
- MarketCap = marketCap,
- ListedShares = listedShares,
- TargetStockCode = targetStockCode,
- TargetStockName = targetStockName,
- TargetStockPrice = targetStockPrice,
- ExercisePrice = exercisePrice,
- ExerciseStartDate = exerciseStartDate,
- ExerciseEndDate = exerciseEndDate,
- IssuePrice = issuePrice,
- DelistDate = delistDate
- };
- }
- /// <summary>동일 (WarrantType, Code, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
- public void Update(
- string name,
- StockMarket market,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal changeRate,
- long volume,
- long tradeValue,
- long? marketCap = null,
- long? listedShares = null,
- string? targetStockCode = null,
- string? targetStockName = null,
- decimal? targetStockPrice = null,
- decimal? exercisePrice = null,
- DateOnly? exerciseStartDate = null,
- DateOnly? exerciseEndDate = null,
- decimal? issuePrice = null,
- DateOnly? delistDate = null
- ) {
- Name = name.Trim();
- Market = market;
- Close = close;
- Open = open;
- High = high;
- Low = low;
- ChangeAmount = changeAmount;
- ChangeRate = changeRate;
- Volume = volume;
- TradeValue = tradeValue;
- MarketCap = marketCap;
- ListedShares = listedShares;
- TargetStockCode = targetStockCode;
- TargetStockName = targetStockName;
- TargetStockPrice = targetStockPrice;
- ExercisePrice = exercisePrice;
- ExerciseStartDate = exerciseStartDate;
- ExerciseEndDate = exerciseEndDate;
- IssuePrice = issuePrice;
- DelistDate = delistDate;
- }
- }
|