feat(core): add shared DTOs, MqttTopics constants, DatabaseBootstrapper, and ManagedMqttClient extensions

This commit is contained in:
2026-08-24 21:35:24 +02:00
parent 6ab84fe1de
commit 44b161d509
39 changed files with 2545 additions and 709 deletions
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
/// <summary>
/// Fully evaluated technical trading setup output from an ITechnicalStrategy.
/// </summary>
/// <param name="UniverseSource">
/// Which FinlyticTechnicals universe-selection mechanism this ISIN was being monitored under at analysis time
/// (favorite/discovery/sentiment-spike), or <see langword="null"/> if it was analyzed ad hoc (e.g. a manual
/// "Analyze now" call for an ISIN not currently in the scan universe). Carried through unchanged onto
/// <c>EngineEvaluationSnapshotEntity</c> so the admin "why no proposals" Web UI can show not just an
/// evaluation's scores but why the asset was being watched in the first place.
/// </param>
/// <param name="UniverseEnteredAtUtc">When the ISIN above entered that scan universe, alongside <paramref name="UniverseSource"/>.</param>
/// <param name="Regime">
/// The overall market/asset technical regime (<see cref="TechnicalContext.Regime"/>) at analysis time - e.g.
/// whether this setup fired during a strong trend or a choppy/rangebound market. Forwarded onto the AI
/// validation payload (<c>AiReasoningGateService</c>) so the model has the same regime context a human trader
/// would use to judge whether a breakout is likely to follow through.
/// </param>
public record StrategyResultDto(
[property: JsonPropertyName("setupId")] Guid SetupId,
[property: JsonPropertyName("isin")] string Isin,
[property: JsonPropertyName("symbol")] string Symbol,
[property: JsonPropertyName("timeframe")] string Timeframe,
[property: JsonPropertyName("strategyKey")] string StrategyKey,
[property: JsonPropertyName("strategyName")] string StrategyName,
[property: JsonPropertyName("direction")] SignalDirection Direction,
[property: JsonPropertyName("qualityScore")] decimal QualityScore,
[property: JsonPropertyName("currentPrice")] decimal CurrentPrice,
[property: JsonPropertyName("entryPrice")] decimal EntryPrice,
[property: JsonPropertyName("invalidationPrice")] decimal InvalidationPrice,
[property: JsonPropertyName("currentAtr")] decimal CurrentAtr,
[property: JsonPropertyName("estimatedRiskRewardRatio")] decimal EstimatedRiskRewardRatio,
[property: JsonPropertyName("exitPlan")] ExitPlan ExitPlan,
[property: JsonPropertyName("technicalRationale")] string TechnicalRationale,
[property: JsonPropertyName("triggeringPatterns")] List<PatternResultDto> TriggeringPatterns,
[property: JsonPropertyName("indicatorSnapshot")] Dictionary<string, decimal> IndicatorSnapshot,
[property: JsonPropertyName("createdAt")] DateTime CreatedAt,
[property: JsonPropertyName("expiresAt")] DateTime ExpiresAt,
[property: JsonPropertyName("isTopPick")] bool IsTopPick = false,
[property: JsonPropertyName("rating")] string Rating = "B",
[property: JsonPropertyName("universeSource")] UniverseSource? UniverseSource = null,
[property: JsonPropertyName("universeEnteredAtUtc")] DateTime? UniverseEnteredAtUtc = null,
[property: JsonPropertyName("regime")] MarketRegime? Regime = null
);