| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- using Infrastructure.StockData;
- namespace Application.Tests;
- [TestClass]
- public sealed class BondIndexParserTests
- {
- [TestMethod]
- public void ParseBondIndexPrices_MapsFields_CommasAndEmptyToNull()
- {
- // KRX OpenAPI(idx/bon_dd_trd) 라이브 응답 샘플 — 1행은 전 지표 제공, 2행은 제로/Call재투자·시장가격 미제공("") → null.
- const string json = """
- {"OutBlock_1":[
- {"BAS_DD":"20250102","BND_IDX_GRP_NM":"KRX 채권지수","TOT_EARNG_IDX":"200.78","TOT_EARNG_IDX_CMPPREVDD":"1.12","NETPRC_IDX":"103.84","NETPRC_IDX_CMPPREVDD":"0.58","ZERO_REINVST_IDX":"193.89","ZERO_REINVST_IDX_CMPPREVDD":"1.08","CALL_REINVST_IDX":"199.47","CALL_REINVST_IDX_CMPPREVDD":"1.12","MKT_PRC_IDX":"104.55","MKT_PRC_IDX_CMPPREVDD":"0.56","AVG_DURATION":"5.646","AVG_CONVEXITY_PRC":"91.702","BND_IDX_AVG_YD":"2.886"},
- {"BAS_DD":"20250102","BND_IDX_GRP_NM":"국고채프라임지수","TOT_EARNG_IDX":"1,199.20","TOT_EARNG_IDX_CMPPREVDD":"0.72","NETPRC_IDX":"109.08","NETPRC_IDX_CMPPREVDD":"0.39","ZERO_REINVST_IDX":"","ZERO_REINVST_IDX_CMPPREVDD":"","CALL_REINVST_IDX":"-","CALL_REINVST_IDX_CMPPREVDD":"-","MKT_PRC_IDX":"","MKT_PRC_IDX_CMPPREVDD":"","AVG_DURATION":"4.105","AVG_CONVEXITY_PRC":"22.500","BND_IDX_AVG_YD":"2.700"}
- ]}
- """;
- var rows = KrxBondIndexParser.ParseBondIndexPrices(json);
- Assert.AreEqual(2, rows.Count);
- var krx = rows[0];
- Assert.AreEqual("KRX 채권지수", krx.GroupName);
- Assert.AreEqual(new DateOnly(2025, 1, 2), krx.TradeDate);
- Assert.AreEqual(200.78m, krx.TotalEarningIndex);
- Assert.AreEqual(1.12m, krx.TotalEarningChange);
- Assert.AreEqual(103.84m, krx.NetPriceIndex);
- Assert.AreEqual(0.58m, krx.NetPriceChange);
- Assert.AreEqual(193.89m, krx.ZeroReinvestIndex);
- Assert.AreEqual(1.08m, krx.ZeroReinvestChange);
- Assert.AreEqual(199.47m, krx.CallReinvestIndex);
- Assert.AreEqual(1.12m, krx.CallReinvestChange);
- Assert.AreEqual(104.55m, krx.MarketPriceIndex);
- Assert.AreEqual(0.56m, krx.MarketPriceChange);
- Assert.AreEqual(5.646m, krx.AvgDuration);
- Assert.AreEqual(91.702m, krx.AvgConvexity);
- Assert.AreEqual(2.886m, krx.AvgYield);
- var prime = rows[1];
- Assert.AreEqual("국고채프라임지수", prime.GroupName);
- Assert.AreEqual(1199.20m, prime.TotalEarningIndex, "콤마 천단위 제거");
- Assert.IsNull(prime.ZeroReinvestIndex, "\"\" 제로재투자지수는 null");
- Assert.IsNull(prime.ZeroReinvestChange);
- Assert.IsNull(prime.CallReinvestIndex, "\"-\" Call재투자지수는 null");
- Assert.IsNull(prime.MarketPriceIndex, "\"\" 시장가격지수는 null");
- Assert.AreEqual(4.105m, prime.AvgDuration);
- Assert.AreEqual(2.700m, prime.AvgYield);
- }
- [TestMethod]
- public void ParseBondIndexPrices_EmptyOrMissingBlock_ReturnsEmpty()
- {
- var empty = KrxBondIndexParser.ParseBondIndexPrices("""{"OutBlock_1":[]}""");
- Assert.AreEqual(0, empty.Count);
- var missing = KrxBondIndexParser.ParseBondIndexPrices("""{"respMsg":"Unauthorized API Call","respCode":"401"}""");
- Assert.AreEqual(0, missing.Count);
- }
- [TestMethod]
- public void ParseBondIndexPrices_SkipsRowsWithoutGroupNameOrDate()
- {
- // 그룹명 없거나 날짜 파싱 실패 행은 스킵
- const string json = """
- {"OutBlock_1":[
- {"BAS_DD":"20250102","BND_IDX_GRP_NM":"","TOT_EARNG_IDX":"100"},
- {"BAS_DD":"","BND_IDX_GRP_NM":"그룹","TOT_EARNG_IDX":"100"},
- {"BAS_DD":"20250102","BND_IDX_GRP_NM":"정상","TOT_EARNG_IDX":"100"}
- ]}
- """;
- var rows = KrxBondIndexParser.ParseBondIndexPrices(json);
- Assert.AreEqual(1, rows.Count);
- Assert.AreEqual("정상", rows[0].GroupName);
- }
- }
|