Добавлен новый вариант кеша
parent
584e378990
commit
8aac315338
|
@ -0,0 +1,150 @@
|
|||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Math.Declisions.Services.Cache
|
||||
{
|
||||
public class PriceHistoryCacheUnit3
|
||||
{
|
||||
private readonly Dictionary<string, TimeSpan> _windowSizes = new ()
|
||||
{
|
||||
{string.Empty, TimeSpan.FromDays(3)}
|
||||
};
|
||||
|
||||
public string Figi { get; init; }
|
||||
|
||||
public IOrderbook? Orderbook
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return _orderbook;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IOrderbook? _orderbook;
|
||||
|
||||
private readonly object _locker = new();
|
||||
private readonly Dictionary<string, LinkedList<ITradeDataItem>> _items = new Dictionary<string, LinkedList<ITradeDataItem>>();
|
||||
|
||||
public ValueTask<CachedValue[]> GetDataFromTimeWindowCache(string key, TimeWindowCacheType timeWindowCacheType)
|
||||
{
|
||||
return ValueTask.FromResult(Array.Empty<CachedValue>());
|
||||
}
|
||||
|
||||
public ValueTask AddData(ITradeDataItem item, string? key = null)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
key = key ?? string.Empty;
|
||||
if (key == string.Empty)
|
||||
{
|
||||
if (item.Figi != Figi)
|
||||
{
|
||||
throw new ArgumentException("Для дефолтного кеша Figi должен совпадать с figi элемента.");
|
||||
}
|
||||
}
|
||||
var windowSize = _windowSizes.TryGetValue(key, out var size) ? size : TimeSpan.FromMinutes(60);
|
||||
if (!_items.TryGetValue(key, out var list))
|
||||
{
|
||||
list = new LinkedList<ITradeDataItem>();
|
||||
_items[key] = list;
|
||||
}
|
||||
list.AddFirst(item);
|
||||
while (list.Last != null && list.First != null
|
||||
&& list.First.Value.Time - list.Last.Value.Time > windowSize)
|
||||
{
|
||||
list.RemoveLast();
|
||||
}
|
||||
}
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask AddOrderbook(IOrderbook orderbook)
|
||||
{
|
||||
if (orderbook.Figi != Figi) return ValueTask.CompletedTask;
|
||||
lock (_locker)
|
||||
{
|
||||
_orderbook = orderbook;
|
||||
}
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask<ITradeDataItem[]> GetData(TimeSpan? period = null, string? key = null)
|
||||
{
|
||||
key = key ?? string.Empty;
|
||||
var res = new List<ITradeDataItem>();
|
||||
lock (_locker)
|
||||
{
|
||||
if (_items.TryGetValue(key, out var list) && list.First != null && list.Last != null)
|
||||
{
|
||||
var startTime = list.First.Value.Time;
|
||||
if (period.HasValue)
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (startTime - item.Time < period.Value)
|
||||
{
|
||||
res.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ValueTask.FromResult(list.Reverse().ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
res.Reverse();
|
||||
return ValueTask.FromResult(res.ToArray());
|
||||
}
|
||||
|
||||
public ValueTask<ITradeDataItem[]> GetData(TimeSpan shift, TimeSpan period, string? key = null)
|
||||
{
|
||||
key = key ?? string.Empty;
|
||||
var res = new List<ITradeDataItem>();
|
||||
var maxPeriod = shift + period;
|
||||
lock (_locker)
|
||||
{
|
||||
if (_items.TryGetValue(key, out var list) && list.First != null && list.Last != null)
|
||||
{
|
||||
var startTime = list.First.Value.Time;
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
var dt = startTime - item.Time;
|
||||
if (dt > shift && dt < maxPeriod)
|
||||
{
|
||||
res.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.Reverse();
|
||||
return ValueTask.FromResult(res.ToArray());
|
||||
}
|
||||
|
||||
public PriceHistoryCacheUnit3(string figi, params ITradeDataItem[] priceChanges)
|
||||
{
|
||||
Figi = figi;
|
||||
|
||||
|
||||
if (priceChanges.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedPriceChanges = priceChanges
|
||||
.OrderBy(pc => pc.Time)
|
||||
.ToArray();
|
||||
|
||||
foreach (var pc in selectedPriceChanges)
|
||||
{
|
||||
AddData(pc).AsTask().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
||||
using KLHZ.Trader.Core.Math.Declisions.Services.Cache;
|
||||
|
||||
namespace KLHZ.Trader.Core.Tests
|
||||
{
|
||||
public class HistoryCacheUnit3Tests
|
||||
{
|
||||
private static PriceChange[] GetHistory(int count, string figi)
|
||||
{
|
||||
var res = new PriceChange[count];
|
||||
if (count != 0)
|
||||
{
|
||||
var startDt = DateTime.UtcNow.AddSeconds(-count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
startDt = startDt.AddSeconds(1);
|
||||
res[i] = new PriceChange()
|
||||
{
|
||||
Figi = figi,
|
||||
Ticker = figi + "_ticker",
|
||||
Id = i,
|
||||
Time = startDt,
|
||||
Price = (decimal)(i + 0.5)
|
||||
};
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test1()
|
||||
{
|
||||
var count = 0;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi, hist);
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.Length == count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test2()
|
||||
{
|
||||
var count =1111;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi, hist);
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.Length == count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test3()
|
||||
{
|
||||
var count = 60*60*3*24;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi, hist);
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.Length == count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test4()
|
||||
{
|
||||
var count = 60 * 60 * 3 * 24;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi);
|
||||
|
||||
foreach (var item in hist)
|
||||
{
|
||||
cacheUnit.AddData(item);
|
||||
}
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.Length == count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test5()
|
||||
{
|
||||
var count = 60 * 60 * 3 * 24+10;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi);
|
||||
|
||||
for (int i = 0; i < hist.Length-1; i++)
|
||||
{
|
||||
cacheUnit.AddData(hist[i]);
|
||||
}
|
||||
cacheUnit.AddData(hist.Last());
|
||||
var data = cacheUnit.GetData().Result;
|
||||
var dt = data.Last().Time - data.First().Time;
|
||||
Assert.That(dt<=TimeSpan.FromDays(3));
|
||||
Assert.That(dt>TimeSpan.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test6()
|
||||
{
|
||||
var count = 60 * 60 * 3 * 24 + 10;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi);
|
||||
|
||||
for (int i = 0; i < hist.Length - 1; i++)
|
||||
{
|
||||
cacheUnit.AddData(hist[i],"kkk");
|
||||
}
|
||||
var data = cacheUnit.GetData(key:"kkk").Result;
|
||||
var dt = data.Last().Time - data.First().Time;
|
||||
Assert.That(dt <= TimeSpan.FromHours(1));
|
||||
Assert.That(dt > TimeSpan.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test7()
|
||||
{
|
||||
var count = 60 * 60 * 3 * 24 + 10;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi);
|
||||
|
||||
for (int i = 0; i < hist.Length - 1; i++)
|
||||
{
|
||||
cacheUnit.AddData(hist[i], "kkk");
|
||||
}
|
||||
var data = cacheUnit.GetData(TimeSpan.FromMinutes(3), key: "kkk").Result;
|
||||
var dt = data.Last().Time - data.First().Time;
|
||||
Assert.That(dt <= TimeSpan.FromMinutes(3));
|
||||
Assert.That(dt > TimeSpan.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test8()
|
||||
{
|
||||
var count = 60 * 60 * 3 * 24 + 10;
|
||||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit3(figi);
|
||||
|
||||
for (int i = 0; i < hist.Length - 1; i++)
|
||||
{
|
||||
cacheUnit.AddData(hist[i], "kkk");
|
||||
}
|
||||
var data = cacheUnit.GetData(TimeSpan.FromMinutes(4), TimeSpan.FromMinutes(3), key: "kkk").Result;
|
||||
var dt = data.Last().Time - data.First().Time;
|
||||
Assert.That(dt <= TimeSpan.FromMinutes(3));
|
||||
Assert.That(dt > TimeSpan.Zero);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue