Files
Finlytic/FinlyticAnalyzer/Services/VixTrackerService.cs
T

100 lines
3.0 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using FinlyticAnalyzer.Util;
using FinlyticCore.Models.Analyzer;
using FinlyticCore.Services;
using FinlyticCore.Services.Yahoo;
namespace FinlyticAnalyzer.Services;
public class VixTrackerService : IVixTrackerService
{
private readonly YahooFinanceClient _yahooClient;
private readonly IFinlyticLogger<VixTrackerService> _finlyticLogger;
private decimal _currentVix = 18.5m;
private VixMarketRegime _currentRegime = VixMarketRegime.Normal;
private readonly object _lock = new();
public VixTrackerService(YahooFinanceClient yahooClient, IFinlyticLogger<VixTrackerService> finlyticLogger)
{
_yahooClient = yahooClient;
_finlyticLogger = finlyticLogger;
}
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)
{
_ = _finlyticLogger.LogWarningAsync(SettingKeys.AnalyzerChannel, "[VixTrackerService] [VIX REGIME SHIFT] Markt-Regime gewechselt: {OldRegime} -> {NewRegime} (VIX: {Vix:F2})",
oldRegime, _currentRegime, _currentVix);
}
else if (Math.Abs(oldVix - vixValue) >= 0.5m)
{
_ = _finlyticLogger.LogInfoAsync(SettingKeys.AnalyzerChannel, "[VixTrackerService] VIX aktualisiert: {Vix:F2} (Regime: {Regime})",
_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)
{
}
catch (Exception ex)
{
await _finlyticLogger.LogWarningAsync(SettingKeys.AnalyzerChannel, ex, "[VixTrackerService] Fehler beim Abfragen von ^VIX über YahooFinanceClient. Nutze gecachten Wert {Vix}.", 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
};
}
}