SeibroDivInfoParser.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. namespace Infrastructure.StockData;
  2. /// <summary>
  3. /// SEIBro getDivInfo(배당분배금내역) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
  4. /// ⚠️ 응답엔 ISSUCO_CUSTNO 가 없다(샘플 확인) — 종목 조인은 ISIN 으로 한다.
  5. /// 자연키(ISIN, RGT_STD_DT) 가 없거나 비형식인 행은 건너뛴다. 소수/율은 콤마 제거 후 decimal, 날짜는 YYYYMMDD→DateOnly.
  6. /// 차등배당 4필드는 대부분 빈값(무차등) → null. TH1_PAY_TERM_BEGIN_DT 는 스펙·샘플 모두 존재하나 미제공 시 null 방어.
  7. /// </summary>
  8. public static class SeibroDivInfoParser
  9. {
  10. public sealed record Row(
  11. string Isin,
  12. string KorSecnNm,
  13. string? SecnKacdNm,
  14. DateOnly RgtStdDt,
  15. decimal? Pval,
  16. decimal? StkAllocRatio,
  17. decimal? CashAllocRatio,
  18. decimal? CashAllocAmt,
  19. decimal? MartpDivRate,
  20. DateOnly? Th1PayTermBeginDt,
  21. DateOnly? DeliDt,
  22. bool? MajshrEtcDiffAllocYn,
  23. bool? TstkNoagnYn,
  24. decimal? CashDiffDiviAmt,
  25. decimal? CashDiffDiviRate,
  26. decimal? StkDiffDiviRate,
  27. decimal? MartpDiffDiviRate
  28. );
  29. public static IReadOnlyList<Row> Parse(SeibroXml.Envelope envelope)
  30. {
  31. var rows = new List<Row>();
  32. foreach (var fields in envelope.Rows)
  33. {
  34. var isin = SeibroXml.GetOrNull(fields, "ISIN")?.Trim();
  35. var korSecnNm = SeibroXml.GetOrNull(fields, "KOR_SECN_NM")?.Trim();
  36. var rgtStdDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "RGT_STD_DT"));
  37. if (string.IsNullOrEmpty(isin) || string.IsNullOrEmpty(korSecnNm) || rgtStdDt is null)
  38. {
  39. continue;
  40. }
  41. rows.Add(new Row(
  42. isin,
  43. korSecnNm,
  44. SeibroXml.GetOrNull(fields, "SECN_KACD_NM")?.Trim(),
  45. rgtStdDt.Value,
  46. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "PVAL")),
  47. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "STK_ALOC_RATIO")),
  48. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "CASH_ALOC_RATIO")),
  49. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "CASH_ALOC_AMT")),
  50. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "MARTP_DIV_RATE")),
  51. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "TH1_PAY_TERM_BEGIN_DT")),
  52. SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "DELI_DT")),
  53. SeibroFieldParse.Yn(SeibroXml.GetOrNull(fields, "MAJSHR_ETC_DIFF_ALOC_YN")),
  54. SeibroFieldParse.Yn(SeibroXml.GetOrNull(fields, "TSTK_NOAGN_YN")),
  55. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "CASH_DIFF_DIVIAMT_VAL")),
  56. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "CASH_DIFF_DIVI_RATE")),
  57. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "STK_DIFF_DIVI_RATE")),
  58. SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "MARTP_DIFF_DIVI_RATE"))
  59. ));
  60. }
  61. return rows;
  62. }
  63. }