EsgSecurity.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// ESG 증권상품 일별시세 (KRX OpenAPI esg/esg_etp_info) — (Name, TradeDate) UNIQUE.
  5. /// ESG 관련 ETF/ETN 등 증권상품의 일별 종가·등락 정보로, EtpDailyTrade(etp)와 응답 shape 이 다르다:
  6. /// - 단축코드(ISU_CD)가 없고 종목명(ISU_ABBRV)만 제공 → 코드 대신 종목명을 UQ 키로 사용한다.
  7. /// - OHLC 중 종가(TDD_CLSPRC)만 제공(시가/고가/저가 없음). NAV·순자산총액·기초지수도 미제공.
  8. /// - 상장주식수는 상장좌수(LIST_SHRS)로 제공된다.
  9. /// 등락률(FLUC_RT)은 소수 % 그대로 저장한다 (EtpDailyTrade.ChangeRate 와 동일 스케일, Bp 아님). 가격은 decimal(18,2).
  10. /// </summary>
  11. public class EsgSecurity
  12. {
  13. [Key]
  14. public long ID { get; private set; }
  15. /// <summary>종목명 (ISU_ABBRV) — ISU_CD 미제공이라 이 값이 UQ 키의 일부</summary>
  16. public string Name { get; private set; } = default!;
  17. /// <summary>거래일 (BAS_DD)</summary>
  18. public DateOnly TradeDate { get; private set; }
  19. /// <summary>현재가/종가 (TDD_CLSPRC)</summary>
  20. public decimal Close { get; private set; }
  21. /// <summary>전일비 (CMPPREVDD_PRC)</summary>
  22. public decimal ChangeAmount { get; private set; }
  23. /// <summary>등락률 % (FLUC_RT) — 소수 % 그대로 (Bp 아님)</summary>
  24. public decimal ChangeRate { get; private set; }
  25. /// <summary>상장좌수 (LIST_SHRS)</summary>
  26. public long ListedShares { get; private set; }
  27. /// <summary>거래량(좌) (ACC_TRDVOL)</summary>
  28. public long Volume { get; private set; }
  29. /// <summary>거래대금(원) (ACC_TRDVAL)</summary>
  30. public long TradeValue { get; private set; }
  31. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  32. private EsgSecurity() { }
  33. public static EsgSecurity Create(
  34. string name,
  35. DateOnly tradeDate,
  36. decimal close,
  37. decimal changeAmount,
  38. decimal changeRate,
  39. long listedShares,
  40. long volume,
  41. long tradeValue
  42. ) {
  43. if (string.IsNullOrWhiteSpace(name))
  44. {
  45. throw new ArgumentException("name required", nameof(name));
  46. }
  47. return new EsgSecurity
  48. {
  49. Name = name.Trim(),
  50. TradeDate = tradeDate,
  51. Close = close,
  52. ChangeAmount = changeAmount,
  53. ChangeRate = changeRate,
  54. ListedShares = listedShares,
  55. Volume = volume,
  56. TradeValue = tradeValue
  57. };
  58. }
  59. /// <summary>동일 (Name, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
  60. public void Update(
  61. decimal close,
  62. decimal changeAmount,
  63. decimal changeRate,
  64. long listedShares,
  65. long volume,
  66. long tradeValue
  67. ) {
  68. Close = close;
  69. ChangeAmount = changeAmount;
  70. ChangeRate = changeRate;
  71. ListedShares = listedShares;
  72. Volume = volume;
  73. TradeValue = tradeValue;
  74. }
  75. }