| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- using System.ComponentModel.DataAnnotations;
- using Domain.Entities.Stocks.ValueObject;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// 일반상품(석유·금·배출권) 일별매매 시세 (KRX OpenAPI gen 엔드포인트) — (CommodityMarket, Code, TradeDate) UNIQUE.
- /// 세 시장을 한 테이블에 담고 CommodityMarket 으로 구분한다. 시장별 응답 shape 이 다르다:
- /// - 금(Gold)/배출권(Emission): ISU_CD/ISU_NM + 주식형 OHLC(TDD_CLSPRC/OPNPRC/HGPRC/LWPRC) + 전일대비(CMPPREVDD_PRC)·등락률(FLUC_RT).
- /// - 석유(Oil): ISU_CD 없음 → OIL_NM(유종구분)을 Code·Name 으로 사용. OHLC 미제공(Open/High/Low=0), 전일대비·등락률 없음 → null.
- /// 가격은 가중평균가격_경쟁(WT_AVG_PRC)을 Close 로, 가중평균가격_협의(WT_DIS_AVG_PRC)를 WeightedDiscussionPrice(석유 전용 nullable)로 담는다.
- /// 공통 필드: Code/Name, TradeDate, Close/Open/High/Low(decimal 18,2), Volume/TradeValue(long). 등락은 금/배출권만, 협의가격은 석유만.
- /// </summary>
- public class CommodityDailyTrade
- {
- [Key]
- public long ID { get; private set; }
- /// <summary>일반상품 시장 구분 (1=석유, 2=금, 3=배출권)</summary>
- public CommodityMarket CommodityMarket { get; private set; }
- /// <summary>단축코드 (ISU_CD) — 금/배출권. 석유는 OIL_NM(유종구분)을 코드로 사용</summary>
- public string Code { get; private set; } = default!;
- /// <summary>종목명 (ISU_NM) — 석유는 OIL_NM(유종구분)</summary>
- public string Name { get; private set; } = default!;
- /// <summary>거래일 (BAS_DD)</summary>
- public DateOnly TradeDate { get; private set; }
- /// <summary>종가 (TDD_CLSPRC) — 석유는 가중평균가격_경쟁 (WT_AVG_PRC)</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) — 금/배출권만. 석유는 미제공 → null</summary>
- public decimal? ChangeAmount { get; private set; }
- /// <summary>등락률 % (FLUC_RT) — 금/배출권만. 석유는 미제공 → null</summary>
- public decimal? ChangeRate { get; private set; }
- /// <summary>가중평균가격_협의 (WT_DIS_AVG_PRC) — 석유만. 금/배출권은 null</summary>
- public decimal? WeightedDiscussionPrice { get; private set; }
- /// <summary>거래량 (ACC_TRDVOL)</summary>
- public long Volume { get; private set; }
- /// <summary>거래대금 (ACC_TRDVAL, 원)</summary>
- public long TradeValue { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- private CommodityDailyTrade() { }
- public static CommodityDailyTrade Create(
- CommodityMarket commodityMarket,
- string code,
- string name,
- DateOnly tradeDate,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal? changeAmount,
- decimal? changeRate,
- decimal? weightedDiscussionPrice,
- long volume,
- long tradeValue
- ) {
- if (!Enum.IsDefined(commodityMarket))
- {
- throw new ArgumentOutOfRangeException(nameof(commodityMarket));
- }
- if (string.IsNullOrWhiteSpace(code))
- {
- throw new ArgumentException("code required", nameof(code));
- }
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentException("name required", nameof(name));
- }
- return new CommodityDailyTrade
- {
- CommodityMarket = commodityMarket,
- Code = code.Trim(),
- Name = name.Trim(),
- TradeDate = tradeDate,
- Close = close,
- Open = open,
- High = high,
- Low = low,
- ChangeAmount = changeAmount,
- ChangeRate = changeRate,
- WeightedDiscussionPrice = weightedDiscussionPrice,
- Volume = volume,
- TradeValue = tradeValue
- };
- }
- /// <summary>동일 (CommodityMarket, Code, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
- public void Update(
- string name,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal? changeAmount,
- decimal? changeRate,
- decimal? weightedDiscussionPrice,
- long volume,
- long tradeValue
- ) {
- Name = name.Trim();
- Close = close;
- Open = open;
- High = high;
- Low = low;
- ChangeAmount = changeAmount;
- ChangeRate = changeRate;
- WeightedDiscussionPrice = weightedDiscussionPrice;
- Volume = volume;
- TradeValue = tradeValue;
- }
- }
|