MarketQuoteParserTests.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using Infrastructure.StockData;
  2. namespace Application.Tests;
  3. [TestClass]
  4. public sealed class MarketQuoteParserTests
  5. {
  6. [TestMethod]
  7. public void Parse_WithVolume_MapsFields_LowercasesSymbol()
  8. {
  9. // Stooq 라이트 배치(/q/l/?f=sd2t2ohlcv&h&e=csv) — 헤더 + 2행 (거래량 포함)
  10. const string csv = """
  11. Symbol,Date,Time,Open,High,Low,Close,Volume
  12. AAPL.US,2026-07-07,22:00:00,210.50,213.00,209.10,212.30,54812000
  13. MSFT.US,2026-07-07,22:00:00,430,435.5,428,433.2,21500000
  14. """;
  15. var rows = MarketQuoteCsvParser.Parse(csv);
  16. Assert.AreEqual(2, rows.Count);
  17. var aapl = rows[0];
  18. Assert.AreEqual("aapl.us", aapl.Symbol, "심볼은 소문자 정규화");
  19. Assert.AreEqual(new DateOnly(2026, 7, 7), aapl.TradeDate);
  20. Assert.AreEqual(210.50m, aapl.Open);
  21. Assert.AreEqual(212.30m, aapl.Close);
  22. Assert.AreEqual(54812000L, aapl.Volume);
  23. Assert.AreEqual(433.2m, rows[1].Close);
  24. Assert.AreEqual(21500000L, rows[1].Volume);
  25. }
  26. [TestMethod]
  27. public void Parse_MissingVolume_DefaultsZero_MissingClose_SkipsRow()
  28. {
  29. // 첫 행: Close 가 N/D → 버림. 둘째 행: 7컬럼(볼륨 미제공) + OHLC N/D → OHLC 는 Close 보정, Volume 0.
  30. const string csv = """
  31. Symbol,Date,Time,Open,High,Low,Close
  32. ^BAD,N/D,N/D,N/D,N/D,N/D,N/D
  33. GOLD.F,2026-07-07,20:00:00,N/D,N/D,N/D,2410.5
  34. """;
  35. var rows = MarketQuoteCsvParser.Parse(csv);
  36. Assert.AreEqual(1, rows.Count, "Close 결측(N/D) 행은 제외");
  37. var gold = rows[0];
  38. Assert.AreEqual("gold.f", gold.Symbol);
  39. Assert.AreEqual(2410.5m, gold.Close);
  40. Assert.AreEqual(2410.5m, gold.Open, "OHLC 결측은 Close 로 보정");
  41. Assert.AreEqual(0L, gold.Volume, "볼륨 미제공은 0");
  42. }
  43. [TestMethod]
  44. public void Parse_EmptyOrHeaderOnly_ReturnsEmpty()
  45. {
  46. Assert.AreEqual(0, MarketQuoteCsvParser.Parse("").Count);
  47. Assert.AreEqual(0, MarketQuoteCsvParser.Parse(" ").Count);
  48. Assert.AreEqual(0, MarketQuoteCsvParser.Parse("Symbol,Date,Time,Open,High,Low,Close,Volume").Count, "헤더만 있으면 0건");
  49. }
  50. }