InterestRate.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using System.ComponentModel.DataAnnotations;
  2. using Domain.Entities.Stocks.ValueObject;
  3. namespace Domain.Entities.Stocks;
  4. /// <summary>
  5. /// 일별 금리 (한국수출입은행 OpenAPI AP02 대출금리 / AP03 국제금리) — (RateType, ItemName, TradeDate) UNIQUE.
  6. /// 두 종류를 한 테이블에 담고 RateType 으로 구분한다. koreaexim 금리 응답은 { cur_nm(항목명), … } 형태로
  7. /// 항목명(예: "리보 1개월", "우대금리") 별 1행이 오며 수치 필드가 응답에 따라 다르므로 대표 수치를 Rate 로 보관한다.
  8. /// - ItemName ← cur_nm (또는 대응 항목명 필드), Rate ← 해당 금리 수치(% — 천단위 콤마/빈값 방어, 미제공 시 null).
  9. /// </summary>
  10. public class InterestRate
  11. {
  12. [Key]
  13. public long ID { get; private set; }
  14. /// <summary>금리 종류 (1=대출금리 AP02, 2=국제금리 AP03)</summary>
  15. public RateType RateType { get; private set; }
  16. /// <summary>항목명 (cur_nm 등) — 예: "리보 1개월", "우대금리"</summary>
  17. public string ItemName { get; private set; } = default!;
  18. /// <summary>거래일 (searchdate)</summary>
  19. public DateOnly TradeDate { get; private set; }
  20. /// <summary>금리 % — 미제공/미고시 시 null</summary>
  21. public decimal? Rate { get; private set; }
  22. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  23. private InterestRate() { }
  24. public static InterestRate Create(RateType rateType, string itemName, DateOnly tradeDate, decimal? rate)
  25. {
  26. if (!Enum.IsDefined(rateType))
  27. {
  28. throw new ArgumentOutOfRangeException(nameof(rateType));
  29. }
  30. if (string.IsNullOrWhiteSpace(itemName))
  31. {
  32. throw new ArgumentException("itemName required", nameof(itemName));
  33. }
  34. return new InterestRate
  35. {
  36. RateType = rateType,
  37. ItemName = itemName.Trim(),
  38. TradeDate = tradeDate,
  39. Rate = rate
  40. };
  41. }
  42. /// <summary>동일 (RateType, ItemName, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
  43. public void Update(decimal? rate)
  44. {
  45. Rate = rate;
  46. }
  47. }