изменена синхронизация портфеля
test / deploy_trader_prod (push) Successful in 1m39s
Details
test / deploy_trader_prod (push) Successful in 1m39s
Details
parent
80221648f7
commit
d0ec2af488
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace KLHZ.Trader.Core.Math.Declisions.Dtos
|
||||
{
|
||||
public class Harmonic
|
||||
{
|
||||
public TimeSpan Period { get; set; }
|
||||
public float Magnitude { get; set; }
|
||||
public float Real { get; set; }
|
||||
public float Imaginary { get; set; }
|
||||
public float Phase { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using MathNet.Numerics;
|
||||
using KLHZ.Trader.Core.Math.Declisions.Dtos;
|
||||
using MathNet.Numerics;
|
||||
using MathNet.Numerics.IntegralTransforms;
|
||||
|
||||
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||
|
@ -26,25 +27,81 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
|||
}
|
||||
}
|
||||
|
||||
public static void А()
|
||||
public static TimeSpan GetMainHarmonictPeriod(double[] data, TimeSpan period)
|
||||
{
|
||||
var da = new List<float>();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
da.Add((float)System.Math.Sin(0.01 * i) + (float)System.Math.Cos(0.01 * i));
|
||||
}
|
||||
|
||||
var start = da.ToArray();
|
||||
var arrv = da.Select(d => new Complex32(d, 0)).ToArray();
|
||||
var arrv = data.Select(d => new Complex32((float)d, 0)).ToArray();
|
||||
Fourier.Forward(arrv);
|
||||
|
||||
Fourier.Inverse(arrv);
|
||||
var res = arrv.Select(a => a.Real).ToArray();
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
var res = new List<Harmonic>();
|
||||
var times = new TimeSpan[arrv.Length];
|
||||
var mags = arrv.Select(a => a.Magnitude).ToArray();
|
||||
var phases = arrv.Select(a => a.Phase).ToArray();
|
||||
var max = 0f;
|
||||
var kmax = 1;
|
||||
var sum = 0f;
|
||||
for (int i=0;i< arrv.Length / 2; i++)
|
||||
{
|
||||
var d = res[i] - start[i];
|
||||
if (i == 0)
|
||||
{
|
||||
res.Add(new Harmonic()
|
||||
{
|
||||
Magnitude = arrv[i].Magnitude,
|
||||
Period = TimeSpan.MaxValue,
|
||||
Phase = arrv[i].Phase,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
times[i] = CaclHarmonycPeriod(period, data.Length, i);
|
||||
res.Add(new Harmonic()
|
||||
{
|
||||
Magnitude = arrv[i].Magnitude,
|
||||
Period = times[i],
|
||||
Phase = arrv[i].Phase,
|
||||
});
|
||||
var mag = arrv[i].Magnitude;
|
||||
sum += mag;
|
||||
if (mag > max)
|
||||
{
|
||||
max = mag;
|
||||
kmax = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CaclHarmonycPeriod(period, data.Length, kmax);
|
||||
}
|
||||
|
||||
public static Harmonic[] GetHarmonics(double[] data, TimeSpan period, int count)
|
||||
{
|
||||
var arrv = data.Select(d => new Complex32((float)d, 0)).ToArray();
|
||||
Fourier.Forward(arrv);
|
||||
var res = new List<Harmonic>();
|
||||
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
res.Add(new Harmonic()
|
||||
{
|
||||
Imaginary = arrv[i].Imaginary,
|
||||
Real = arrv[i].Real,
|
||||
Magnitude = arrv[i].Magnitude,
|
||||
Period = CaclHarmonycPeriod(period, data.Length, i),
|
||||
Phase = arrv[i].Phase,
|
||||
});
|
||||
}
|
||||
|
||||
return res.ToArray();
|
||||
}
|
||||
|
||||
public static double Calc(Harmonic[] harmonics, DateTime startTime, DateTime endTime, DateTime currentTime)
|
||||
{
|
||||
var sum = 0d;
|
||||
var timeSpan = currentTime - startTime;
|
||||
for (int i = 0; i < harmonics.Length; i++)
|
||||
{
|
||||
var currentPhase = System.Math.PI * 2 * timeSpan.TotalSeconds * (endTime - startTime).TotalSeconds / harmonics[i].Period.TotalSeconds / harmonics[i].Period.TotalSeconds + harmonics[i].Phase;
|
||||
var value = harmonics[i].Real * System.Math.Cos(currentPhase) + harmonics[i].Imaginary * System.Math.Sign(currentPhase);
|
||||
sum += value;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static TimeSpan CaclHarmonycPeriod(TimeSpan signalLength, int signalLengthItems, int harmonyNumber)
|
||||
|
|
|
@ -10,16 +10,28 @@ namespace KLHZ.Trader.Core.Tests
|
|||
[Test]
|
||||
public static void Test()
|
||||
{
|
||||
//var da = new List<float>();
|
||||
//for (int i = 0; i < 100; i++)
|
||||
//{
|
||||
// da.Add((float)System.Math.Sin(0.5 * i)+(float)System.Math.Cos(0.5 * i));
|
||||
//}
|
||||
var da = new List<float>();
|
||||
var da2 = new List<float>();
|
||||
var dates = new List<DateTime>();
|
||||
var dt = DateTime.UtcNow;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
dt = dt.AddSeconds(1);
|
||||
da.Add((float)System.Math.Sin(0.01 * i) + (float)System.Math.Cos(0.02 * i));
|
||||
dates.Add(dt);
|
||||
}
|
||||
|
||||
//var start = da.ToArray();
|
||||
//var arrv = da.Select(d => new Complex32(d, 0)).ToArray();
|
||||
//Fourier.Forward(arrv);
|
||||
//var tem = arrv.Select(a => Complex32.Abs(a)).ToArray();
|
||||
var start = da.ToArray();
|
||||
var arrv = da.Select(d => new Complex32(d, 0)).ToArray();
|
||||
Fourier.Forward(arrv);
|
||||
var harms = FFT.GetHarmonics(da.Select(d => (double)d).ToArray(), dates.Last() - dates.First(), 20);
|
||||
|
||||
|
||||
foreach(var d in dates)
|
||||
{
|
||||
da2.Add((float)FFT.Calc(harms, dates.First(), dates.Last(), d));
|
||||
}
|
||||
//var tem = arrv.Select(a => Complex32.Abs(a)).ToArray();
|
||||
//var s = tem.Sum();
|
||||
//Fourier.Inverse(arrv);
|
||||
//var res = arrv.Select(a => a.Real).ToArray();
|
||||
|
|
|
@ -192,6 +192,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
}
|
||||
|
||||
_ = SyncPortfolioWorker();
|
||||
_ = WritePricesTask();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -241,8 +242,12 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
|
||||
if (trade != null)
|
||||
{
|
||||
trade.Count = position.Quantity;
|
||||
trade.Position = position.Quantity > 0 ? DataLayer.Entities.Trades.Enums.PositionType.Long : DataLayer.Entities.Trades.Enums.PositionType.Short;
|
||||
trades.Remove(trade);
|
||||
price = trade.Price;
|
||||
context.Trades.Update(trade);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -351,40 +356,8 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
{
|
||||
trade.Price = (oldAmount + newAmount) / trade.Count;
|
||||
}
|
||||
}
|
||||
|
||||
if (Accounts.TryGetValue(dealResult.AccountId, out var account))
|
||||
{
|
||||
if (account.Assets.TryGetValue(dealResult.Figi, out var asset))
|
||||
{
|
||||
if (trade.Count == 0)
|
||||
{
|
||||
await context.Trades.Where(t => t.Id == trade.Id && t.ArchiveStatus == 0)
|
||||
.ExecuteUpdateAsync(t => t.SetProperty(tr => tr.ArchiveStatus, 1));
|
||||
account.Assets.TryRemove(dealResult.Figi, out _);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Trades.Update(trade);
|
||||
await context.SaveChangesAsync();
|
||||
var newAsset = new Asset()
|
||||
{
|
||||
AccountId = asset.AccountId,
|
||||
Figi = asset.Figi,
|
||||
Ticker = asset.Ticker,
|
||||
BlockedItems = asset.BlockedItems,
|
||||
BoughtAt = DateTime.UtcNow,
|
||||
BoughtPrice = trade.Price,
|
||||
Count = sign * trade.Count,
|
||||
Position = trade.Count > 0 ? PositionType.Long : PositionType.Short,
|
||||
Type = asset.Type,
|
||||
TradeId = asset.TradeId,
|
||||
};
|
||||
account.Assets[dealResult.Figi] = newAsset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
context.Trades.Update(trade);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,6 +392,25 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
}
|
||||
|
||||
private async Task SyncPortfolioWorker()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(20000);
|
||||
foreach (var acc in Accounts)
|
||||
{
|
||||
await SyncPortfolio(acc.Value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка при цикличном обновлении портфеля");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WritePricesTask()
|
||||
{
|
||||
var buffer1 = new List<ProcessedPrice>();
|
||||
|
|
|
@ -245,6 +245,36 @@ namespace KLHZ.Trader.Service.Controllers
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task TestFFT(string figi)
|
||||
{
|
||||
try
|
||||
{
|
||||
var t1 = new DateTime(2025, 9, 15, 6, 30, 0, DateTimeKind.Utc);
|
||||
var t2 = new DateTime(2025, 9, 15, 7, 50, 50, DateTimeKind.Utc);
|
||||
|
||||
using var context1 = await _dbContextFactory.CreateDbContextAsync();
|
||||
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
var data = await context1.PriceChanges
|
||||
.Where(i => i.Time >= t1 && i.Time <= t2 && i.Figi == figi)
|
||||
.OrderBy(i => i.Time)
|
||||
.ToArrayAsync();
|
||||
|
||||
var buffer = new List<ProcessedPrice>();
|
||||
var values = data.Select(d => (double)d.Value).ToArray();
|
||||
var times = data.Select(d => d.Time).ToArray();
|
||||
var res = SignalProcessing.InterpolateData(times, values,
|
||||
TimeSpan.FromSeconds(10));
|
||||
|
||||
FFT.GetMainHarmonictPeriod(res.Item2, res.Item1.Last() - res.Item1.First());
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
//[HttpGet]
|
||||
//public async Task GetBalance(string figi)
|
||||
//{
|
||||
|
|
Loading…
Reference in New Issue