| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- namespace Infrastructure.StockData;
- /// <summary>
- /// SEIBro getXrcStkOptionXrcInfo(주식관련사채 행사내역) 응답 파서 — 순수 C#. 공용 SeibroXml envelope 입력.
- /// ⚠️ 실샘플 fixture 가 result="0"(0행)이라 필드 매핑을 라이브로 검증하지 못했다 — 주식.md 스펙 기준으로 구현했으며
- /// 운영 첫 수집 시 로그로 필드명(대소문자 포함)을 확인해야 한다.
- /// 날짜 스윕(권리행사일 RGT_STD_DT) 결과 — BOND_ISIN·RGT_STD_DT 중 하나라도 없으면 건너뛴다.
- /// XRC_AMT/XRC_QTY/XRC_PRICE 는 소수 표기 가능 → decimal.
- /// </summary>
- public static class SeibroXrcStkOptionXrcParser
- {
- public sealed record Row(
- string BondIsin,
- string? BondKorSecnNm,
- string? BondKindNm,
- string? XrcStkIsin,
- string? StkKorSecnNm,
- DateOnly RgtStdDt,
- DateOnly? XrcPossBeginDt,
- DateOnly? XrcPossExpryDt,
- decimal? XrcAmt,
- decimal? XrcQty,
- decimal? XrcPrice,
- DateOnly? ListDt
- );
- public static IReadOnlyList<Row> Parse(SeibroXml.Envelope envelope)
- {
- var rows = new List<Row>();
- foreach (var fields in envelope.Rows)
- {
- var bondIsin = SeibroXml.GetOrNull(fields, "BOND_ISIN")?.Trim();
- var rgtStdDt = SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "RGT_STD_DT"));
- if (string.IsNullOrEmpty(bondIsin) || rgtStdDt is null)
- {
- continue;
- }
- rows.Add(new Row(
- bondIsin,
- SeibroXml.GetOrNull(fields, "BOND_KOR_SECN_NM")?.Trim(),
- SeibroXml.GetOrNull(fields, "BOND_KIND_NM")?.Trim(),
- SeibroXml.GetOrNull(fields, "XRC_STK_ISIN")?.Trim(),
- SeibroXml.GetOrNull(fields, "STK_KOR_SECN_NM")?.Trim(),
- rgtStdDt.Value,
- SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "XRC_POSS_BEGIN_DT")),
- SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "XRC_POSS_EXPRY_DT")),
- SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_AMT")),
- SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_QTY")),
- SeibroFieldParse.Decimal(SeibroXml.GetOrNull(fields, "XRC_PRICE")),
- SeibroFieldParse.Date(SeibroXml.GetOrNull(fields, "LIST_DT"))
- ));
- }
- return rows;
- }
- }
|