| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- using Infrastructure.StockData;
- namespace Application.Tests;
- [TestClass]
- public sealed class MarketQuoteParserTests
- {
- [TestMethod]
- public void Parse_WithVolume_MapsFields_LowercasesSymbol()
- {
- // Stooq 라이트 배치(/q/l/?f=sd2t2ohlcv&h&e=csv) — 헤더 + 2행 (거래량 포함)
- const string csv = """
- Symbol,Date,Time,Open,High,Low,Close,Volume
- AAPL.US,2026-07-07,22:00:00,210.50,213.00,209.10,212.30,54812000
- MSFT.US,2026-07-07,22:00:00,430,435.5,428,433.2,21500000
- """;
- var rows = MarketQuoteCsvParser.Parse(csv);
- Assert.AreEqual(2, rows.Count);
- var aapl = rows[0];
- Assert.AreEqual("aapl.us", aapl.Symbol, "심볼은 소문자 정규화");
- Assert.AreEqual(new DateOnly(2026, 7, 7), aapl.TradeDate);
- Assert.AreEqual(210.50m, aapl.Open);
- Assert.AreEqual(212.30m, aapl.Close);
- Assert.AreEqual(54812000L, aapl.Volume);
- Assert.AreEqual(433.2m, rows[1].Close);
- Assert.AreEqual(21500000L, rows[1].Volume);
- }
- [TestMethod]
- public void Parse_MissingVolume_DefaultsZero_MissingClose_SkipsRow()
- {
- // 첫 행: Close 가 N/D → 버림. 둘째 행: 7컬럼(볼륨 미제공) + OHLC N/D → OHLC 는 Close 보정, Volume 0.
- const string csv = """
- Symbol,Date,Time,Open,High,Low,Close
- ^BAD,N/D,N/D,N/D,N/D,N/D,N/D
- GOLD.F,2026-07-07,20:00:00,N/D,N/D,N/D,2410.5
- """;
- var rows = MarketQuoteCsvParser.Parse(csv);
- Assert.AreEqual(1, rows.Count, "Close 결측(N/D) 행은 제외");
- var gold = rows[0];
- Assert.AreEqual("gold.f", gold.Symbol);
- Assert.AreEqual(2410.5m, gold.Close);
- Assert.AreEqual(2410.5m, gold.Open, "OHLC 결측은 Close 로 보정");
- Assert.AreEqual(0L, gold.Volume, "볼륨 미제공은 0");
- }
- [TestMethod]
- public void Parse_EmptyOrHeaderOnly_ReturnsEmpty()
- {
- Assert.AreEqual(0, MarketQuoteCsvParser.Parse("").Count);
- Assert.AreEqual(0, MarketQuoteCsvParser.Parse(" ").Count);
- Assert.AreEqual(0, MarketQuoteCsvParser.Parse("Symbol,Date,Time,Open,High,Low,Close,Volume").Count, "헤더만 있으면 0건");
- }
- }
|