ForeignSettlementSecurity.cs 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Stocks;
  3. /// <summary>
  4. /// SEIBro 종목별 외화증권 결제현황 (getSecnFrsecSetlInfo) — KSD 를 통한 특정 외화종목(ISIN)의 매수/매도 결제신청수량·금액(USD) (Wave 6). 자연키 UNIQUE (ProcDt, Isin, IntlBizCacd).
  5. /// 응답 필드는 NationCd·SecnTpcd·IntlBizCacd·SetlAskQty·SetlAmt 5종 — 배치가 PROC_DT·ISIN 을 요청값으로 스탬핑한다.
  6. /// PROC_DT = 결제처리일(한국시간) — 미국시간 T일 결제는 처리일 T+1 반영. IntlBizCacd = 1110매수/1120매도. ForeignIsins 기본 빈 리스트라 사실상 대기.
  7. /// </summary>
  8. public class ForeignSettlementSecurity
  9. {
  10. [Key]
  11. public int ID { get; private set; }
  12. /// <summary>결제처리일 (PROC_DT, 요청값 스탬핑, 한국시간)</summary>
  13. public DateOnly ProcDt { get; private set; }
  14. /// <summary>종목코드 (ISIN, 요청값 스탬핑)</summary>
  15. public string Isin { get; private set; } = default!;
  16. /// <summary>국제업무분류코드 (INTL_BIZ_CACD) — 1110매수 1120매도</summary>
  17. public string IntlBizCacd { get; private set; } = default!;
  18. /// <summary>국가코드 (NATION_CD)</summary>
  19. public string? NationCd { get; private set; }
  20. /// <summary>종목구분코드 (SECN_TPCD) — 71외화주식~78외화수익증권</summary>
  21. public string? SecnTpcd { get; private set; }
  22. /// <summary>결제신청수량 (SETL_ASK_QTY) — 주식:주, 채권:액면금액</summary>
  23. public decimal? SetlAskQty { get; private set; }
  24. /// <summary>결제금액 (SETL_AMT) — USD</summary>
  25. public decimal? SetlAmt { get; private set; }
  26. public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
  27. private ForeignSettlementSecurity() { }
  28. public static ForeignSettlementSecurity Create(DateOnly procDt, string isin, string intlBizCacd, string? nationCd, string? secnTpcd, decimal? setlAskQty, decimal? setlAmt)
  29. {
  30. if (string.IsNullOrWhiteSpace(isin))
  31. {
  32. throw new ArgumentException("isin required", nameof(isin));
  33. }
  34. if (string.IsNullOrWhiteSpace(intlBizCacd))
  35. {
  36. throw new ArgumentException("intlBizCacd required", nameof(intlBizCacd));
  37. }
  38. return new ForeignSettlementSecurity
  39. {
  40. ProcDt = procDt,
  41. Isin = isin.Trim(),
  42. IntlBizCacd = intlBizCacd.Trim(),
  43. NationCd = Trimmed(nationCd),
  44. SecnTpcd = Trimmed(secnTpcd),
  45. SetlAskQty = setlAskQty,
  46. SetlAmt = setlAmt
  47. };
  48. }
  49. /// <summary>재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키 ProcDt/Isin/IntlBizCacd 은 불변)</summary>
  50. public void Update(string? nationCd, string? secnTpcd, decimal? setlAskQty, decimal? setlAmt)
  51. {
  52. var changed = false;
  53. changed |= Set(Trimmed(nationCd), NationCd, v => NationCd = v);
  54. changed |= Set(Trimmed(secnTpcd), SecnTpcd, v => SecnTpcd = v);
  55. changed |= Set(setlAskQty, SetlAskQty, v => SetlAskQty = v);
  56. changed |= Set(setlAmt, SetlAmt, v => SetlAmt = v);
  57. if (changed)
  58. {
  59. UpdatedAt = DateTime.UtcNow;
  60. }
  61. }
  62. private static string? Trimmed(string? value)
  63. {
  64. return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
  65. }
  66. private static bool Set<T>(T incoming, T current, Action<T> assign)
  67. {
  68. if (EqualityComparer<T>.Default.Equals(incoming, current))
  69. {
  70. return false;
  71. }
  72. assign(incoming);
  73. return true;
  74. }
  75. }