ForeignSettlementNation.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// SEIBro 국가별 외화증권 결제현황 (getNationFrsecSetlInfo) — KSD 를 통한 외화증권 매수/매도 결제건수·금액(USD), 국가×매매구분×종목구분별 (Wave 6).
  5. /// 자연키 UNIQUE (SetlDt, NationCd, IntlBizCacd, SecnTpcd). 응답 필드는 IntlBizCacd·SecnTpcd·SetlCount·FrsecSetlAmt 4종 — 배치가 SETL_DT·NATION_CD 를 요청값으로 스탬핑한다.
  6. /// IntlBizCacd(국제업무분류) = 1110매수 / 1120매도. 외화 결제는 미국시간 T일 결제가 처리일 T+1 반영(getSecnFrsecSetlInfo 주석 참고)이라 결제일 스윕은 T+1 지연을 감안한다.
  7. /// </summary>
  8. public class ForeignSettlementNation
  9. {
  10. [Key]
  11. public int ID { get; private set; }
  12. /// <summary>결제일자 (SETL_DT, 요청값 스탬핑)</summary>
  13. public DateOnly SetlDt { get; private set; }
  14. /// <summary>국가코드 (NATION_CD, 요청값 스탬핑) — US/JP/HK/CN/E1 등 43종</summary>
  15. public string NationCd { get; private set; } = default!;
  16. /// <summary>국제업무분류코드 (INTL_BIZ_CACD) — 1110매수 1120매도</summary>
  17. public string IntlBizCacd { get; private set; } = default!;
  18. /// <summary>종목구분코드 (SECN_TPCD) — 71외화주식~78외화수익증권</summary>
  19. public string SecnTpcd { get; private set; } = default!;
  20. /// <summary>결제건수 (SETL_COUNT)</summary>
  21. public long? SetlCount { get; private set; }
  22. /// <summary>외화증권결제금액 (FRSEC_SETL_AMT) — USD</summary>
  23. public decimal? FrsecSetlAmt { get; private set; }
  24. public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
  25. private ForeignSettlementNation() { }
  26. public static ForeignSettlementNation Create(DateOnly setlDt, string nationCd, string intlBizCacd, string secnTpcd, long? setlCount, decimal? frsecSetlAmt)
  27. {
  28. if (string.IsNullOrWhiteSpace(nationCd))
  29. {
  30. throw new ArgumentException("nationCd required", nameof(nationCd));
  31. }
  32. if (string.IsNullOrWhiteSpace(intlBizCacd))
  33. {
  34. throw new ArgumentException("intlBizCacd required", nameof(intlBizCacd));
  35. }
  36. if (string.IsNullOrWhiteSpace(secnTpcd))
  37. {
  38. throw new ArgumentException("secnTpcd required", nameof(secnTpcd));
  39. }
  40. return new ForeignSettlementNation
  41. {
  42. SetlDt = setlDt,
  43. NationCd = nationCd.Trim(),
  44. IntlBizCacd = intlBizCacd.Trim(),
  45. SecnTpcd = secnTpcd.Trim(),
  46. SetlCount = setlCount,
  47. FrsecSetlAmt = frsecSetlAmt
  48. };
  49. }
  50. /// <summary>재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키 SetlDt/NationCd/IntlBizCacd/SecnTpcd 은 불변)</summary>
  51. public void Update(long? setlCount, decimal? frsecSetlAmt)
  52. {
  53. var changed = false;
  54. changed |= Set(setlCount, SetlCount, v => SetlCount = v);
  55. changed |= Set(frsecSetlAmt, FrsecSetlAmt, v => FrsecSetlAmt = v);
  56. if (changed)
  57. {
  58. UpdatedAt = DateTime.UtcNow;
  59. }
  60. }
  61. private static bool Set<T>(T incoming, T current, Action<T> assign)
  62. {
  63. if (EqualityComparer<T>.Default.Equals(incoming, current))
  64. {
  65. return false;
  66. }
  67. assign(incoming);
  68. return true;
  69. }
  70. }