feat(engine): add FinlyticEngine microservice with trade lifecycle, AI reasoning gate, composite scoring, and unit tests

This commit is contained in:
2026-08-24 21:37:05 +02:00
parent a4959658a2
commit 5c95dd182c
49 changed files with 7709 additions and 0 deletions
@@ -0,0 +1,53 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using FinlyticCore.Dtos.Fundamentals;
using FinlyticCore.Dtos.Sentiment;
using FinlyticCore.Dtos.TechnicalAnalysis;
using FinlyticCore.Dtos.Trading;
using FinlyticEngine.Services.Ai;
using FinlyticEngine.Services.Derivatives;
using FinlyticEngine.Services.Scoring;
namespace FinlyticEngine.Tests.TestSupport;
/// <summary>
/// Fakes for the three <see cref="FinlyticEngine.Services.Trading.TradeLifecycleService"/> dependencies
/// (scoring, AI gate, derivative resolution) that are only reachable through
/// <c>EvaluateAssetAsync</c>. The tenant-boundary tests in this suite never call that method, so these
/// fakes deliberately throw if invoked: a passing test that happened to call one of them without anyone
/// noticing would be a silent, false-positive gap.
/// </summary>
public class NeverInvokedCompositeOpportunityScorer : ICompositeOpportunityScorer
{
public Task<ScoringResult> CalculateCompositeScoreAsync(
StrategyResultDto setup,
IsinSentimentSummaryDto? sentiment,
AssetFundamentalsDto? fundamentals,
FinlyticCore.Dtos.Simulation.StrategyAssetReliabilityDto? reliability = null,
CancellationToken cancellationToken = default)
=> throw new InvalidOperationException("Not expected to be called by the tenant-boundary tests.");
}
public class NeverInvokedAiReasoningGateService : IAiReasoningGateService
{
public Task<AiValidationResultDto> ValidateOpportunityAsync(
StrategyResultDto setup,
IsinSentimentSummaryDto? sentiment,
AssetFundamentalsDto? fundamentals,
ScoringResult score,
FinlyticCore.Dtos.Simulation.StrategyAssetReliabilityDto? reliability = null,
CancellationToken cancellationToken = default)
=> throw new InvalidOperationException("Not expected to be called by the tenant-boundary tests.");
}
public class NeverInvokedKnockOutDerivativeResolver : IKnockOutDerivativeResolver
{
public Task<DerivativeSelectionDto?> ResolveOptimalTurboAsync(
string underlyingIsin,
SignalDirection direction,
decimal chartStopLoss,
decimal currentPrice,
CancellationToken cancellationToken = default)
=> throw new InvalidOperationException("Not expected to be called by the tenant-boundary tests.");
}