101 lines
2.9 KiB
C#
101 lines
2.9 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using FinlyticCore.Models.Analyzer;
|
|
using FinlyticCore.Services.Yahoo;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace FinlyticAnalyzer.Services;
|
|
|
|
public class VixTrackerService : IVixTrackerService
|
|
{
|
|
private readonly YahooFinanceClient _yahooClient;
|
|
private readonly ILogger<VixTrackerService> _logger;
|
|
|
|
private decimal _currentVix = 18.5m; // Default: Normal Regime
|
|
private VixMarketRegime _currentRegime = VixMarketRegime.Normal;
|
|
private readonly object _lock = new();
|
|
|
|
public VixTrackerService(YahooFinanceClient yahooClient, ILogger<VixTrackerService> logger)
|
|
{
|
|
_yahooClient = yahooClient;
|
|
_logger = logger;
|
|
}
|
|
|
|
public decimal GetCurrentVix()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
return _currentVix;
|
|
}
|
|
}
|
|
|
|
public VixMarketRegime GetCurrentRegime()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
return _currentRegime;
|
|
}
|
|
}
|
|
|
|
public void UpdateVixFromTick(decimal vixValue)
|
|
{
|
|
if (vixValue <= 0m) return;
|
|
|
|
lock (_lock)
|
|
{
|
|
var oldRegime = _currentRegime;
|
|
var oldVix = _currentVix;
|
|
|
|
_currentVix = vixValue;
|
|
_currentRegime = CalculateRegime(vixValue);
|
|
|
|
if (oldRegime != _currentRegime)
|
|
{
|
|
_logger.LogWarning("[{Channel}] [VIX REGIME SHIFT] Markt-Regime gewechselt: {OldRegime} -> {NewRegime} (VIX: {Vix:F2})",
|
|
"AnalyzerChannel", oldRegime, _currentRegime, _currentVix);
|
|
}
|
|
else if (Math.Abs(oldVix - vixValue) >= 0.5m)
|
|
{
|
|
_logger.LogInformation("[{Channel}] VIX aktualisiert: {Vix:F2} (Regime: {Regime})",
|
|
"AnalyzerChannel", _currentVix, _currentRegime);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<decimal> PollVixAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var vix = await _yahooClient.GetLivePriceAsync("^VIX", cancellationToken);
|
|
|
|
if (vix.HasValue && vix.Value > 0m)
|
|
{
|
|
UpdateVixFromTick(vix.Value);
|
|
return vix.Value;
|
|
}
|
|
}
|
|
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
|
{
|
|
// Graceful shutdown
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "[{Channel}] Fehler beim Abfragen von ^VIX über YahooFinanceClient. Nutze gecachten Wert {Vix}.",
|
|
"AnalyzerChannel", GetCurrentVix());
|
|
}
|
|
|
|
return GetCurrentVix();
|
|
}
|
|
|
|
private static VixMarketRegime CalculateRegime(decimal vix)
|
|
{
|
|
return vix switch
|
|
{
|
|
< 15.0m => VixMarketRegime.LowVol,
|
|
>= 15.0m and < 20.0m => VixMarketRegime.Normal,
|
|
>= 20.0m and < 30.0m => VixMarketRegime.HighVol,
|
|
_ => VixMarketRegime.Panic
|
|
};
|
|
}
|
|
} |