From 80d23a6fee0a495437d0e4e173c039dc8c061bf1 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Fri, 14 Aug 2026 15:10:42 +0900 Subject: [PATCH] fix: KrxDataService GET method + correct endpoint (pykrx-openapi compatible) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Changed HTTP method: POST → GET - Changed base URL: https://openapi.krx.co.kr → http://data-dbg.krx.co.kr - Changed endpoint: /svc/sample/apis/idx/krx_dd_trd → /svc/apis/sto/stk_bydd_trd - Query params: basDd in URL (not JSON body) - Response parsing: OutBlock_1 field (pykrx-openapi format) - Stub fallback: Still active when KRX_OPENAPI env var empty Addresses: WBS optimization Step 4 (API reliability). Code is compatible with pykrx-openapi implementation. Co-Authored-By: Claude Haiku 4.5 --- .../ShadowRun/Services/KrxDataService.cs | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxDataService.cs b/src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxDataService.cs index 4ff30075..90db43bf 100644 --- a/src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxDataService.cs +++ b/src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxDataService.cs @@ -19,8 +19,8 @@ public sealed class KrxDataService : IKrxDataService private const int MaxRetries = 3; private const int InitialBackoffMs = 100; private const int MaxBackoffMs = 30000; - private const string KrxApiBaseUrl = "https://openapi.krx.co.kr"; // From appsettings: ExternalApis:KrxOpenApi:BaseUrl - private const string KrxApiEndpoint = "/svc/sample/apis/idx/krx_dd_trd"; + private const string KrxApiBaseUrl = "http://data-dbg.krx.co.kr"; // Stock price API (from pykrx-openapi) + private const string KrxApiEndpoint = "/svc/apis/sto/stk_bydd_trd"; // KOSPI daily trading endpoint private static readonly Action LogFetchingOhlcv = LoggerMessage.Define( @@ -180,20 +180,13 @@ public sealed class KrxDataService : IKrxDataService // Fetch each trading day in range for (var date = startDate; date <= endDate; date = date.AddDays(1)) { - // KRX API (spec): POST /svc/apis/idx/krx_dd_trd with JSON body {"basDd":"YYYYMMDD"} - var endpoint = $"{KrxApiBaseUrl}{KrxApiEndpoint}"; + // KRX API (spec): GET /svc/apis/sto/stk_bydd_trd with query param basDd=YYYYMMDD + var endpoint = $"{KrxApiBaseUrl}{KrxApiEndpoint}?basDd={date:yyyyMMdd}"; try { - var requestBody = new { basDd = date.ToString("yyyyMMdd") }; - var jsonContent = new StringContent( - System.Text.Json.JsonSerializer.Serialize(requestBody), - System.Text.Encoding.UTF8, - "application/json"); - - var request = new HttpRequestMessage(HttpMethod.Post, endpoint); + var request = new HttpRequestMessage(HttpMethod.Get, endpoint); request.Headers.Add("AUTH_KEY", apiKey); - request.Content = jsonContent; var response = await _httpClient.SendAsync(request, cancellationToken); @@ -245,9 +238,15 @@ public sealed class KrxDataService : IKrxDataService { try { - var response = JsonSerializer.Deserialize(krxResponse); - var items = response?.Response?.Body?.Items ?? new List(); - return JsonSerializer.Serialize(items); + using var doc = JsonDocument.Parse(krxResponse); + var root = doc.RootElement; + + if (root.TryGetProperty("OutBlock_1", out var outBlock)) + { + return outBlock.GetRawText(); + } + + return "[]"; } catch {