feat(trades): add live execution cockpit, closing cockpit, calculation cards and precision trade settings
This commit is contained in:
@@ -329,11 +329,19 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
var settings = await settingsService.GetSettingsAsync();
|
||||
double minSignalScore = settings.MinSignalScore;
|
||||
|
||||
double confidenceScore = n8nResponse?.EvalScore > 0 ? n8nResponse.EvalScore : 0.75;
|
||||
double dynamicWinRate = _winRateCalculator.CalculateDynamicWinRate(
|
||||
manualReq.Sector,
|
||||
manualReq.Symbol,
|
||||
regime,
|
||||
n8nEvalScore: n8nResponse?.EvalScore,
|
||||
sentimentScore: manualReq.SentimentData?.CurrentSummary?.CompoundScore,
|
||||
signalType: n8nResponse?.SuggestedDirection ?? "BUY");
|
||||
|
||||
double confidenceScore = n8nResponse?.EvalScore > 0 ? n8nResponse.EvalScore : (dynamicWinRate / 100.0);
|
||||
bool shouldProceed = n8nResponse != null &&
|
||||
string.Equals(n8nResponse.AiDecision, "Proceed", StringComparison.OrdinalIgnoreCase) &&
|
||||
(confidenceScore * 100.0) >= minSignalScore &&
|
||||
winRate >= minSignalScore;
|
||||
dynamicWinRate >= minSignalScore;
|
||||
|
||||
TradeProposalDto? proposalDto = null;
|
||||
if (n8nResponse != null)
|
||||
@@ -353,7 +361,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
RiskTolerance = n8nResponse.SuggestedRisk,
|
||||
Timeframe = timeframeFormatted,
|
||||
InstrumentType = manualReq.InstrumentType,
|
||||
WinRate = winRate,
|
||||
WinRate = dynamicWinRate,
|
||||
VixRegime = regime,
|
||||
VixValue = currentVix,
|
||||
TtlMinutes = 60,
|
||||
@@ -384,7 +392,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
VixRegime = regime,
|
||||
VixValue = currentVix,
|
||||
ImpactScore = 1.0,
|
||||
WinRate = winRate,
|
||||
WinRate = dynamicWinRate,
|
||||
RawDataJson = JsonSerializer.Serialize(manualReq),
|
||||
AiOutputJson = proposalDto != null ? JsonSerializer.Serialize(proposalDto) : "{}",
|
||||
N8nResponseJson = n8nResponse != null ? JsonSerializer.Serialize(n8nResponse) : "{}",
|
||||
@@ -527,6 +535,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
FinlyticCore.Dtos.TechnicalAnalysis.TechnicalAnalysisDto? taResp = null;
|
||||
FinlyticCore.Dtos.Fundamentals.AssetFundamentalsDto? fundResp = null;
|
||||
FinlyticCore.Dtos.TechnicalAnalysis.LivePriceDto? livePriceResp = null;
|
||||
FinlyticCore.Dtos.Sentiment.IsinSentimentSummaryDto? sentResp = null;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -549,7 +558,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
livePriceResp = livePriceTask.Result;
|
||||
taResp = taTask.Result;
|
||||
fundResp = fundTask.Result;
|
||||
var sentResp = sentTask.Result;
|
||||
sentResp = sentTask.Result;
|
||||
|
||||
if (taResp?.Indicators != null)
|
||||
{
|
||||
@@ -735,10 +744,31 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
ActionRequired = isHighConviction ? "PROMPT_USER_FOR_MANUAL_TRADE" : "NO_ACTION"
|
||||
};
|
||||
|
||||
double dynamicWinRate = _winRateCalculator.CalculateDynamicWinRate(
|
||||
filterResult.Sector,
|
||||
finalSymbol,
|
||||
regime,
|
||||
n8nEvalScore: n8nResponse?.EvalScore,
|
||||
sentimentScore: sentResp?.CurrentSummary?.CompoundScore,
|
||||
signalType: n8nResponse?.SuggestedDirection ?? "BUY");
|
||||
|
||||
using (var scope = _scopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = scope.ServiceProvider.GetRequiredService<AnalyzerDbContext>();
|
||||
|
||||
bool hasRecentProposal = await dbContext.Analyses.AnyAsync(a =>
|
||||
a.Isin == filterResult.Isin &&
|
||||
a.IsTradeProposed &&
|
||||
a.CreatedAt >= DateTime.UtcNow.AddHours(-4),
|
||||
cancellationToken);
|
||||
|
||||
if (hasRecentProposal && isHighConviction)
|
||||
{
|
||||
_logger.LogInformation("[{Channel}] [AutoScreener] Asset {Symbol} ({Isin}) already has an active trade proposal in the last 4 hours. Skipping duplicate trade proposal generation.",
|
||||
"AnalyzerChannel", finalSymbol, filterResult.Isin);
|
||||
isHighConviction = false;
|
||||
}
|
||||
|
||||
var analysisEntity = new AnalysisEntity
|
||||
{
|
||||
AnalysisId = analysisId,
|
||||
@@ -749,7 +779,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
VixRegime = regime,
|
||||
VixValue = currentVix,
|
||||
ImpactScore = filterResult.ImpactScore,
|
||||
WinRate = winRate,
|
||||
WinRate = dynamicWinRate,
|
||||
RawDataJson = payloadStr,
|
||||
AiOutputJson = JsonSerializer.Serialize(recommendation),
|
||||
N8nResponseJson = n8nResponse != null ? JsonSerializer.Serialize(n8nResponse) : "{}",
|
||||
@@ -780,7 +810,7 @@ public class AnalyzerMqttClient : ManagedMqttClient, IHostedService
|
||||
RiskTolerance = n8nResponse.SuggestedRisk ?? "Balanced",
|
||||
Timeframe = $"{minTf}-{maxTf} Tage",
|
||||
InstrumentType = "KnockOut",
|
||||
WinRate = winRate,
|
||||
WinRate = dynamicWinRate,
|
||||
VixRegime = regime,
|
||||
VixValue = currentVix,
|
||||
TtlMinutes = 180,
|
||||
|
||||
Reference in New Issue
Block a user