Add exception for webhook + add gracefull time before market decrease

This commit is contained in:
2025-11-05 10:54:14 +07:00
parent 43aa62fcb3
commit 1079f38ed7
3 changed files with 15 additions and 6 deletions

View File

@@ -142,3 +142,4 @@ namespace Managing.Api.HealthChecks

View File

@@ -28,6 +28,7 @@ public class TradingBotBase : ITradingBot
public readonly ILogger<TradingBotBase> Logger; public readonly ILogger<TradingBotBase> Logger;
private readonly IServiceScopeFactory _scopeFactory; private readonly IServiceScopeFactory _scopeFactory;
private const int NEW_POSITION_GRACE_SECONDS = 45; // grace window before evaluating missing orders private const int NEW_POSITION_GRACE_SECONDS = 45; // grace window before evaluating missing orders
private const int CLOSE_POSITION_GRACE_MS = 20000; // grace window before closing position to allow broker processing (20 seconds)
public TradingBotConfig Config { get; set; } public TradingBotConfig Config { get; set; }
public Account Account { get; set; } public Account Account { get; set; }
@@ -1324,6 +1325,13 @@ public class TradingBotBase : ITradingBot
isForBacktest: Config.IsForBacktest); isForBacktest: Config.IsForBacktest);
try try
{ {
// Grace period: give the broker time to process any ongoing close operations
// Using ConfigureAwait(false) to ensure non-blocking operation
if (!Config.IsForBacktest)
{
await Task.Delay(CLOSE_POSITION_GRACE_MS).ConfigureAwait(false);
}
Position closedPosition = null; Position closedPosition = null;
await ServiceScopeHelpers.WithScopedServices<IExchangeService, IAccountService, ITradingService>( await ServiceScopeHelpers.WithScopedServices<IExchangeService, IAccountService, ITradingService>(
_scopeFactory, async (exchangeService, accountService, tradingService) => _scopeFactory, async (exchangeService, accountService, tradingService) =>

View File

@@ -22,11 +22,11 @@ public class WebhookService : IWebhookService
_configuration = configuration; _configuration = configuration;
_logger = logger; _logger = logger;
_n8nWebhookUrl = _configuration["N8n:WebhookUrl"] ?? string.Empty; _n8nWebhookUrl = _configuration["N8n:WebhookUrl"] ?? string.Empty;
// Configure basic authentication if credentials are provided // Configure basic authentication if credentials are provided
var username = _configuration["N8n:Username"]; var username = _configuration["N8n:Username"];
var password = _configuration["N8n:Password"]; var password = _configuration["N8n:Password"];
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{ {
var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"));
@@ -63,12 +63,12 @@ public class WebhookService : IWebhookService
} }
else else
{ {
_logger.LogWarning($"Failed to send webhook notification. Status: {response.StatusCode}"); throw new Exception($"Failed to send webhook message. Status: {response.StatusCode}");
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error sending webhook notification"); SentrySdk.CaptureException(ex);
} }
} }
@@ -100,12 +100,12 @@ public class WebhookService : IWebhookService
} }
else else
{ {
_logger.LogWarning($"Failed to send webhook message. Status: {response.StatusCode}"); throw new Exception($"Failed to send webhook message. Status: {response.StatusCode}");
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error sending webhook message"); SentrySdk.CaptureException(ex);
} }
} }
} }