using KLHZ.Trader.Core.Contracts.Declisions.Interfaces; using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces; using System.Reflection; namespace KLHZ.Trader.Core.Math.Declisions.Services { public class PriceHistoryCacheUnit2 : IPriceHistoryCacheUnit { public const int CacheMaxLength = 500; private const int _arrayMaxLength = 1500; public string Figi { get; init; } public int Length { get { lock (_locker) { return _length; } } } private readonly object _locker = new(); private readonly float[] Prices = new float[_arrayMaxLength]; private readonly DateTime[] Timestamps = new DateTime[_arrayMaxLength]; private int _length = 0; private int _pointer = -1; public ValueTask AddData(INewPrice priceChange) { lock (_locker) { _pointer++; Prices[_pointer] = (float)priceChange.Value; Timestamps[_pointer] = priceChange.Time; if (_length < CacheMaxLength) { _length++; } if (_pointer == _arrayMaxLength - 1) { Array.Copy(Prices, Prices.Length - CacheMaxLength, Prices, 0, CacheMaxLength); Array.Copy(Timestamps, Timestamps.Length - CacheMaxLength, Timestamps, 0, CacheMaxLength); _pointer = CacheMaxLength - 1; } } return ValueTask.CompletedTask; } public ValueTask<(DateTime[] timestamps, float[] prices)> GetData() { lock (_locker) { if (_pointer < 0) { return ValueTask.FromResult((Array.Empty(), Array.Empty ())); } else { var prices = new float[_length]; var timestamps = new DateTime[_length]; Array.Copy(Prices,1+ _pointer - _length, prices, 0, prices.Length); Array.Copy(Timestamps,1+ _pointer - _length, timestamps, 0, timestamps.Length); return ValueTask.FromResult((timestamps, prices)); } } } public PriceHistoryCacheUnit2(string figi, params INewPrice[] priceChanges) { Figi = figi; if (priceChanges.Length == 0) { return; } var selectedPriceChanges = priceChanges .OrderBy(pc => pc.Time) .Skip(priceChanges.Length - CacheMaxLength) .ToArray(); foreach ( var pc in selectedPriceChanges) { AddData(pc); } } } }