From d6a2dca9c8192db3fe06a13f9c57b0e017ab859a Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Mon, 13 Jul 2026 01:24:10 +0900 Subject: [PATCH] refactor(dotnet): structure pipeline orchestration steps --- .../Services/PipelineOrchestrator.cs | 90 +++++++++++-------- .../PipelineOrchestratorTests.cs | 3 + 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs b/src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs index b3c664db..b3bb0c0d 100644 --- a/src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs +++ b/src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs @@ -12,64 +12,46 @@ namespace QuantEngine.Application.Services { public class PipelineOrchestrator { + private static readonly IReadOnlyList StepDefinitions = + [ + new("scores_calculation", true, ExecuteScoreCalculationAsync), + new("routing_decision", true, ExecuteRoutingDecisionAsync), + new("sell_audit", false, ExecuteStubbedStepAsync), + new("coverage_check", false, ExecuteStubbedStepAsync), + new("engine_audit", false, ExecuteStubbedStepAsync), + new("validation", false, ExecuteStubbedStepAsync), + new("golden_check", false, ExecuteStubbedStepAsync) + ]; + public async Task RunPipelineAsync() { var result = new PipelineResult(); var totalSw = Stopwatch.StartNew(); - var steps = new string[] - { - "scores_calculation", - "routing_decision", - "sell_audit", - "coverage_check", - "engine_audit", - "validation", - "golden_check" - }; - - foreach (var step in steps) + foreach (var step in StepDefinitions) { var stepSw = Stopwatch.StartNew(); - bool isStubbed = false; string errMsg = string.Empty; - if (step == "scores_calculation") + try { - // Step 1: Real computed factor score calculation - var dummyStock = new List(); - var dummyIndex = new List(); - var factors = FactorCalculator.CalculateFactors(dummyStock, dummyIndex); - await Task.Delay(5); - } - else if (step == "routing_decision") - { - // Step 2: Real computed routing decision logic - var ctx = new Dictionary + await step.Executor(); + if (!step.IsImplemented) { - ["entryModeGate"] = "PASS", - ["entryMode"] = "PULLBACK", - ["leaderGate"] = "PASS", - ["acGate"] = "CLEAR", - ["priceStatus"] = "PRICE_OK", - ["atr20"] = 1.5 - }; - var decision = FormulaEngine.ComputeTimingDecision(ctx); - await Task.Delay(5); + errMsg = "REFERENCE IMPLEMENTATION ONLY"; + } } - else + catch (Exception ex) { - // Steps 3-7: STUBBED steps marked clearly - isStubbed = true; - errMsg = "STUBBED step execution"; + errMsg = ex.Message; } stepSw.Stop(); result.Steps.Add(new PipelineStepResult { - StepName = isStubbed ? $"{step} (STUBBED)" : step, - Success = true, + StepName = step.Name, + Success = string.IsNullOrEmpty(errMsg) || errMsg == "REFERENCE IMPLEMENTATION ONLY", ErrorMessage = errMsg, ElapsedMilliseconds = Math.Max(0.1, stepSw.Elapsed.TotalMilliseconds) }); @@ -96,5 +78,35 @@ namespace QuantEngine.Application.Services return result; } + + private static Task ExecuteScoreCalculationAsync() + { + var dummyStock = new List(); + var dummyIndex = new List(); + _ = FactorCalculator.CalculateFactors(dummyStock, dummyIndex); + return Task.CompletedTask; + } + + private static Task ExecuteRoutingDecisionAsync() + { + var ctx = new Dictionary + { + ["entryModeGate"] = "PASS", + ["entryMode"] = "PULLBACK", + ["leaderGate"] = "PASS", + ["acGate"] = "CLEAR", + ["priceStatus"] = "PRICE_OK", + ["atr20"] = 1.5 + }; + _ = FormulaEngine.ComputeTimingDecision(ctx); + return Task.CompletedTask; + } + + private static Task ExecuteStubbedStepAsync() => Task.CompletedTask; } + + internal sealed record PipelineStepDefinition( + string Name, + bool IsImplemented, + Func Executor); } diff --git a/src/dotnet/QuantEngine.Core.Tests/PipelineOrchestratorTests.cs b/src/dotnet/QuantEngine.Core.Tests/PipelineOrchestratorTests.cs index d7819eec..405062de 100644 --- a/src/dotnet/QuantEngine.Core.Tests/PipelineOrchestratorTests.cs +++ b/src/dotnet/QuantEngine.Core.Tests/PipelineOrchestratorTests.cs @@ -17,6 +17,9 @@ namespace QuantEngine.Core.Tests Assert.NotNull(result); Assert.Equal("PASS", result.Gate); Assert.Equal(7, result.Steps.Count); + Assert.Contains(result.Steps, step => step.StepName == "scores_calculation"); + Assert.Contains(result.Steps, step => step.StepName == "routing_decision"); + Assert.Contains(result.Steps, step => step.StepName == "golden_check"); foreach (var step in result.Steps) {