Compare commits
No commits in common. "80221648f78fa7130e4aa15230a6e354b76d3897" and "7da563f0ff412f965ab929ad506a26a7518046c0" have entirely different histories.
80221648f7
...
7da563f0ff
|
@ -4,7 +4,6 @@ namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces
|
||||||
{
|
{
|
||||||
public interface ITradeCommand
|
public interface ITradeCommand
|
||||||
{
|
{
|
||||||
public Guid CommandId { get; }
|
|
||||||
public TradeCommandType CommandType { get; }
|
public TradeCommandType CommandType { get; }
|
||||||
public string Figi { get; }
|
public string Figi { get; }
|
||||||
public decimal? RecomendPrice { get; }
|
public decimal? RecomendPrice { get; }
|
||||||
|
|
|
@ -5,7 +5,6 @@ namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
||||||
{
|
{
|
||||||
public class TradeCommand : ITradeCommand
|
public class TradeCommand : ITradeCommand
|
||||||
{
|
{
|
||||||
public Guid CommandId { get; init; } = Guid.NewGuid();
|
|
||||||
public TradeCommandType CommandType { get; init; }
|
public TradeCommandType CommandType { get; init; }
|
||||||
public required string Figi { get; init; }
|
public required string Figi { get; init; }
|
||||||
public decimal? RecomendPrice { get; init; }
|
public decimal? RecomendPrice { get; init; }
|
||||||
|
|
|
@ -26,27 +26,6 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void А()
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
Fourier.Forward(arrv);
|
|
||||||
|
|
||||||
Fourier.Inverse(arrv);
|
|
||||||
var res = arrv.Select(a => a.Real).ToArray();
|
|
||||||
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
var d = res[i] - start[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TimeSpan CaclHarmonycPeriod(TimeSpan signalLength, int signalLengthItems, int harmonyNumber)
|
public static TimeSpan CaclHarmonycPeriod(TimeSpan signalLength, int signalLengthItems, int harmonyNumber)
|
||||||
{
|
{
|
||||||
var fdiscretisation = signalLengthItems /signalLength.TotalSeconds ;
|
var fdiscretisation = signalLengthItems /signalLength.TotalSeconds ;
|
||||||
|
@ -60,89 +39,32 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
return System.Math.Atan(item.Imaginary / item.Real);
|
return System.Math.Atan(item.Imaginary / item.Real);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (double min, double max) CalcPhaseRangeFoxMax(double aSin, double aCos, double initPhase, double level)
|
public static (double min, double max) CalcPhaseRange(double aSin, double aCos, double initPhase, double maxLevel)
|
||||||
{
|
|
||||||
return CalcPhaseRange(aSin, aCos,initPhase, level, CheckMaxValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static (double min, double max) CalcPhaseRangeFoxMin(double aSin, double aCos, double initPhase, double level)
|
|
||||||
{
|
|
||||||
return CalcPhaseRange(aSin, aCos, initPhase, level, CheckMinValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static (double min, double max) CalcPhaseRange(double aSin, double aCos, double initPhase, double level, Func<double, double, double, double,bool> comparer)
|
|
||||||
{
|
{
|
||||||
var x = new List<double>();
|
var x = new List<double>();
|
||||||
var xIndexes = new List<int>();
|
var x2 = new List<double>();
|
||||||
var y = new List<double>();
|
var y = new List<double>();
|
||||||
var max = double.MinValue;
|
for (double i = 0; i <= 10 * System.Math.PI; i += 0.0001)
|
||||||
var min = double.MaxValue;
|
{
|
||||||
var _2pi = 2 * System.Math.PI;
|
var _2pi = 2 * System.Math.PI;
|
||||||
for (double i = 0; i <= 10 * System.Math.PI; i += 0.01)
|
var df = ((i / _2pi) % 1) * _2pi;
|
||||||
{
|
|
||||||
var df = (((i) / _2pi) % 1) * _2pi;
|
|
||||||
var val = aSin * System.Math.Sin(i + initPhase) + aCos * System.Math.Cos(i + initPhase);
|
|
||||||
if (val > max)
|
|
||||||
{
|
|
||||||
max = val;
|
|
||||||
}
|
|
||||||
if (val < min)
|
|
||||||
{
|
|
||||||
min = val;
|
|
||||||
}
|
|
||||||
x.Add(df);
|
x.Add(df);
|
||||||
y.Add(val);
|
y.Add(aSin * System.Math.Sin(i + initPhase) + aCos * System.Math.Cos(i + initPhase));
|
||||||
}
|
}
|
||||||
|
|
||||||
int start = -2;
|
var prevI = -1;
|
||||||
int prevI = -2;
|
var max = y.Max();
|
||||||
int end = -2;
|
|
||||||
|
|
||||||
var drange = -2;
|
|
||||||
|
|
||||||
var minPhaseTmp = 0d;
|
|
||||||
var maxPhaseTmp = 0d;
|
|
||||||
|
|
||||||
var minPhase = 0d;
|
|
||||||
var maxPhase = 0d;
|
|
||||||
for (int i = 0; i < y.Count; i++)
|
for (int i = 0; i < y.Count; i++)
|
||||||
{
|
{
|
||||||
if (comparer(y[i],min,max,level))
|
if (y[i] > (1 - maxLevel) * max && (i - prevI == 1 || prevI < 0))
|
||||||
{
|
{
|
||||||
if (start < 0)
|
x2.Add(x[i]);
|
||||||
{
|
|
||||||
minPhaseTmp = x[i];
|
|
||||||
start = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (start >= 0 && i - prevI == 1)
|
|
||||||
{
|
|
||||||
end = prevI;
|
|
||||||
maxPhaseTmp = x[end];
|
|
||||||
var drangeTmp = end - start;
|
|
||||||
if (drangeTmp > drange)
|
|
||||||
{
|
|
||||||
drange = drangeTmp;
|
|
||||||
minPhase = minPhaseTmp;
|
|
||||||
maxPhase = maxPhaseTmp;
|
|
||||||
}
|
|
||||||
start = -2;
|
|
||||||
}
|
|
||||||
prevI = i;
|
prevI = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
var minPhase = x2.Min();
|
||||||
|
var maxPhase = x2.Max();
|
||||||
return (minPhase, maxPhase);
|
return (minPhase, maxPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool CheckMaxValue(double val, double min, double max, double relativeValue)
|
|
||||||
{
|
|
||||||
return (val > (1 - relativeValue) * max);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool CheckMinValue(double val, double min, double max, double relativeValue)
|
|
||||||
{
|
|
||||||
return (val < (1 - relativeValue) * min);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
|
||||||
{
|
|
||||||
public static class SignalProcessing
|
|
||||||
{
|
|
||||||
public static (DateTime[], double[]) InterpolateData(DateTime[] timestamps, double[] values, TimeSpan timeStep)
|
|
||||||
{
|
|
||||||
var res = new List<double>();
|
|
||||||
var res2 = new List<DateTime>();
|
|
||||||
|
|
||||||
var startTime = new DateTime(timestamps[0].Year, timestamps[0].Month, timestamps[0].Day, 0, 0, 0, DateTimeKind.Utc);
|
|
||||||
var dt = timestamps[0] - startTime;
|
|
||||||
|
|
||||||
var totalSteps = System.Math.Ceiling((timestamps[timestamps.Length - 1] - timestamps[0]).TotalSeconds / timeStep.TotalSeconds);
|
|
||||||
var deltaSeconds = System.Math.Floor(dt.TotalSeconds / timeStep.TotalSeconds);
|
|
||||||
startTime = startTime.AddSeconds(deltaSeconds * timeStep.TotalSeconds) ;
|
|
||||||
|
|
||||||
var firstBound = startTime;
|
|
||||||
var secondBound = startTime + timeStep;
|
|
||||||
var bound = 0;
|
|
||||||
for (int i = 0; i < totalSteps; i++)
|
|
||||||
{
|
|
||||||
var count = 0;
|
|
||||||
var sum = 0d;
|
|
||||||
|
|
||||||
for (int i1 = bound; i1 < timestamps.Length; i1++)
|
|
||||||
{
|
|
||||||
if (timestamps[i1]> firstBound && timestamps[i1] <= secondBound)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
sum += values[i1];
|
|
||||||
}
|
|
||||||
else if (count != 0)
|
|
||||||
{
|
|
||||||
bound = i1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count != 0)
|
|
||||||
{
|
|
||||||
res.Add(sum / count);
|
|
||||||
res2.Add(secondBound);
|
|
||||||
}
|
|
||||||
else if (bound< timestamps.Length-2)
|
|
||||||
{
|
|
||||||
res.Add(res.Last());
|
|
||||||
res2.Add(secondBound);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
firstBound += timeStep;
|
|
||||||
secondBound += timeStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (res2.ToArray(), res.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,24 +10,24 @@ namespace KLHZ.Trader.Core.Tests
|
||||||
[Test]
|
[Test]
|
||||||
public static void Test()
|
public static void Test()
|
||||||
{
|
{
|
||||||
//var da = new List<float>();
|
var da = new List<float>();
|
||||||
//for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++)
|
||||||
//{
|
{
|
||||||
// da.Add((float)System.Math.Sin(0.5 * i)+(float)System.Math.Cos(0.5 * i));
|
da.Add((float)System.Math.Sin(0.5 * i)+(float)System.Math.Cos(0.5 * i));
|
||||||
//}
|
}
|
||||||
|
|
||||||
//var start = da.ToArray();
|
var start = da.ToArray();
|
||||||
//var arrv = da.Select(d => new Complex32(d, 0)).ToArray();
|
var arrv = da.Select(d => new Complex32(d, 0)).ToArray();
|
||||||
//Fourier.Forward(arrv);
|
Fourier.Forward(arrv);
|
||||||
//var tem = arrv.Select(a => Complex32.Abs(a)).ToArray();
|
var tem = arrv.Select(a => Complex32.Abs(a)).ToArray();
|
||||||
//var s = tem.Sum();
|
var s = tem.Sum();
|
||||||
//Fourier.Inverse(arrv);
|
Fourier.Inverse(arrv);
|
||||||
//var res = arrv.Select(a => a.Real).ToArray();
|
var res = arrv.Select(a => a.Real).ToArray();
|
||||||
|
|
||||||
//for (int i = 0; i < 1000; i++)
|
for (int i = 0; i < 1000; i++)
|
||||||
//{
|
{
|
||||||
// var d = res[i] - start[i];
|
var d = res[i] - start[i];
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -41,69 +41,9 @@ namespace KLHZ.Trader.Core.Tests
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void CalcPhaseRangeForMax_Sin()
|
public static void CalcPhaseRange()
|
||||||
{
|
{
|
||||||
var res = FFT.CalcPhaseRangeFoxMax(1, 0, 0, 0.001);
|
var res = FFT.CalcPhaseRange(1, 0, 0, 0.001);
|
||||||
Assert.IsTrue(res.min < System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.min > System.Math.PI / 2 * 0.9);
|
|
||||||
Assert.IsTrue(res.max > System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.max < System.Math.PI / 2 * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMin_Sin()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMin(1, 0, 0, 0.001);
|
|
||||||
Assert.IsTrue(res.min < 3*System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.min > 3*System.Math.PI / 2 * 0.9);
|
|
||||||
Assert.IsTrue(res.max > 3*System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.max < 3*System.Math.PI / 2 * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMax_MinusSin()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMax(-1, 0, 0, 0.001);
|
|
||||||
Assert.IsTrue(res.min < 3*System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.min > 3*System.Math.PI / 2 * 0.9);
|
|
||||||
Assert.IsTrue(res.max > 3*System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.max < 3*System.Math.PI / 2 * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMax_Cos()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMax(0, 1, 0, 0.001);
|
|
||||||
Assert.IsTrue(res.min < System.Math.PI * 2);
|
|
||||||
Assert.IsTrue(res.min > System.Math.PI * 2 * 0.9);
|
|
||||||
Assert.IsTrue(res.max > 0);
|
|
||||||
Assert.IsTrue(res.max < System.Math.PI * 2*0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMin_Cos()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMin(0, 1, 0, 0.001);
|
|
||||||
Assert.IsTrue(res.min < System.Math.PI);
|
|
||||||
Assert.IsTrue(res.min > System.Math.PI * 0.9);
|
|
||||||
Assert.IsTrue(res.max > System.Math.PI);
|
|
||||||
Assert.IsTrue(res.max < System.Math.PI * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMax_CosWithShift()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMax(0, 1, System.Math.PI / 2, 0.001);
|
|
||||||
Assert.IsTrue(res.min < 3 * System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.min > 3 * System.Math.PI / 2 * 0.9);
|
|
||||||
Assert.IsTrue(res.max > 3 * System.Math.PI / 2);
|
|
||||||
Assert.IsTrue(res.max < 3 * System.Math.PI / 2 * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public static void CalcPhaseRangeForMax_CosWithShift2()
|
|
||||||
{
|
|
||||||
var res = FFT.CalcPhaseRangeFoxMax(0, 1, - System.Math.PI / 2, 0.001);
|
|
||||||
Assert.IsTrue(res.min < System.Math.PI / 2);
|
Assert.IsTrue(res.min < System.Math.PI / 2);
|
||||||
Assert.IsTrue(res.min > System.Math.PI / 2 * 0.9);
|
Assert.IsTrue(res.min > System.Math.PI / 2 * 0.9);
|
||||||
Assert.IsTrue(res.max > System.Math.PI / 2);
|
Assert.IsTrue(res.max > System.Math.PI / 2);
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
using KLHZ.Trader.Core.Math.Declisions.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.Tests
|
|
||||||
{
|
|
||||||
public class SignalProcessingTests
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public static void Test()
|
|
||||||
{
|
|
||||||
var da = new List<double>();
|
|
||||||
var times = new List<DateTime>();
|
|
||||||
var startDt = DateTime.UtcNow;
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
startDt = startDt.AddSeconds(((double)(RandomNumberGenerator.GetInt32(1, 100)))/100);
|
|
||||||
times.Add(startDt);
|
|
||||||
da.Add((float)System.Math.Sin(0.01 * i) + (float)System.Math.Cos(0.01 * i));
|
|
||||||
}
|
|
||||||
|
|
||||||
var res = SignalProcessing.InterpolateData(times.ToArray(), da.ToArray(), TimeSpan.FromSeconds(5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,8 +3,8 @@
|
||||||
public static class BotModeSwitcher
|
public static class BotModeSwitcher
|
||||||
{
|
{
|
||||||
private readonly static object _locker = new();
|
private readonly static object _locker = new();
|
||||||
private static bool _canSell = true;
|
private static bool _canSell = false;
|
||||||
private static bool _canPurchase = true;
|
private static bool _canPurchase = false;
|
||||||
|
|
||||||
public static bool CanSell()
|
public static bool CanSell()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@ using System.Collections.Concurrent;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
using Tinkoff.InvestApi;
|
using Tinkoff.InvestApi;
|
||||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
|
||||||
using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType;
|
using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType;
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.Exchange.Services
|
namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
|
@ -126,7 +125,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
var stoppingKey = message.Figi + asset.AccountId;
|
var stoppingKey = message.Figi + asset.AccountId;
|
||||||
if (message.Time - asset.BoughtAt > TimeSpan.FromMinutes(4) && profit < -66m && !ClosingStops.ContainsKey(stoppingKey))
|
if (message.Time - asset.BoughtAt > TimeSpan.FromMinutes(4) && profit < -66m && !ClosingStops.ContainsKey(stoppingKey))
|
||||||
{
|
{
|
||||||
var command = new TradeCommand()
|
await _dataBus.Broadcast(new TradeCommand()
|
||||||
{
|
{
|
||||||
AccountId = asset.AccountId,
|
AccountId = asset.AccountId,
|
||||||
Figi = message.Figi,
|
Figi = message.Figi,
|
||||||
|
@ -135,10 +134,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
Count = System.Math.Abs((long)asset.Count),
|
Count = System.Math.Abs((long)asset.Count),
|
||||||
RecomendPrice = null,
|
RecomendPrice = null,
|
||||||
EnableMargin = false,
|
EnableMargin = false,
|
||||||
};
|
});
|
||||||
await _dataBus.Broadcast(command);
|
|
||||||
_logger.LogWarning("Сброс актива {figi}! id команды {commandId} Направление сделки: {dir}; Количество активов: {count}; Разрешена ли маржиналка: {margin}",
|
|
||||||
message.Figi, command.CommandId, command.CommandType, command.Count, command.EnableMargin);
|
|
||||||
OpeningStops[message.Figi] = DateTime.UtcNow.AddMinutes(10);
|
OpeningStops[message.Figi] = DateTime.UtcNow.AddMinutes(10);
|
||||||
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
||||||
await LogDeclision(DeclisionTradeAction.CloseLong, message, profit);
|
await LogDeclision(DeclisionTradeAction.CloseLong, message, profit);
|
||||||
|
@ -147,7 +143,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
|
|
||||||
if (message.Time - asset.BoughtAt > TimeSpan.FromHours(4) && profit > 100 && !ClosingStops.ContainsKey(stoppingKey))
|
if (message.Time - asset.BoughtAt > TimeSpan.FromHours(4) && profit > 100 && !ClosingStops.ContainsKey(stoppingKey))
|
||||||
{
|
{
|
||||||
var command = new TradeCommand()
|
await _dataBus.Broadcast(new TradeCommand()
|
||||||
{
|
{
|
||||||
AccountId = asset.AccountId,
|
AccountId = asset.AccountId,
|
||||||
Figi = message.Figi,
|
Figi = message.Figi,
|
||||||
|
@ -156,10 +152,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
Count = (long)asset.Count,
|
Count = (long)asset.Count,
|
||||||
RecomendPrice = null,
|
RecomendPrice = null,
|
||||||
EnableMargin = false,
|
EnableMargin = false,
|
||||||
};
|
});
|
||||||
await _dataBus.Broadcast(command);
|
|
||||||
_logger.LogWarning("Сброс актива {figi}! id команды {commandId} Направление сделки: {dir}; Количество активов: {count}; Разрешена ли маржиналка: {margin}",
|
|
||||||
message.Figi, command.CommandId, command.CommandType, command.Count, command.EnableMargin);
|
|
||||||
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
||||||
await LogDeclision(DeclisionTradeAction.CloseLong, message, profit);
|
await LogDeclision(DeclisionTradeAction.CloseLong, message, profit);
|
||||||
await LogDeclision(DeclisionTradeAction.CloseLongReal, message, profit);
|
await LogDeclision(DeclisionTradeAction.CloseLongReal, message, profit);
|
||||||
|
@ -218,17 +211,14 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
{
|
{
|
||||||
if (RandomNumberGenerator.GetInt32(100) > 50)
|
if (RandomNumberGenerator.GetInt32(100) > 50)
|
||||||
{
|
{
|
||||||
var command = new TradeCommand()
|
await _dataBus.Broadcast(new TradeCommand()
|
||||||
{
|
{
|
||||||
AccountId = acc.Value.AccountId,
|
AccountId = acc.Value.AccountId,
|
||||||
Figi = message.Figi,
|
Figi = message.Figi,
|
||||||
CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.MarketBuy,
|
CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.MarketBuy,
|
||||||
Count = 1,
|
Count = 1,
|
||||||
RecomendPrice = null,
|
RecomendPrice = null,
|
||||||
};
|
});
|
||||||
await _dataBus.Broadcast(command);
|
|
||||||
_logger.LogWarning("Покупка актива {figi}! id команды {commandId}. Направление сделки: {dir}; Количество активов: {count}; Разрешена ли маржиналка: {margin}",
|
|
||||||
message.Figi, command.CommandId, command.CommandType, command.Count, command.EnableMargin);
|
|
||||||
if (loggedDeclisions == 0)
|
if (loggedDeclisions == 0)
|
||||||
{
|
{
|
||||||
await LogDeclision(DeclisionTradeAction.OpenLongReal, message);
|
await LogDeclision(DeclisionTradeAction.OpenLongReal, message);
|
||||||
|
@ -271,7 +261,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
if (profit > 0 && !ClosingStops.ContainsKey(stoppingKey))
|
if (profit > 0 && !ClosingStops.ContainsKey(stoppingKey))
|
||||||
{
|
{
|
||||||
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
ClosingStops[stoppingKey] = DateTime.UtcNow.AddSeconds(30);
|
||||||
var command = new TradeCommand()
|
await _dataBus.Broadcast(new TradeCommand()
|
||||||
{
|
{
|
||||||
AccountId = asset.AccountId,
|
AccountId = asset.AccountId,
|
||||||
Figi = message.Figi,
|
Figi = message.Figi,
|
||||||
|
@ -279,10 +269,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
Count = (long)asset.Count,
|
Count = (long)asset.Count,
|
||||||
RecomendPrice = null,
|
RecomendPrice = null,
|
||||||
EnableMargin = false,
|
EnableMargin = false,
|
||||||
};
|
});
|
||||||
await _dataBus.Broadcast(command);
|
|
||||||
_logger.LogWarning("Продажа актива {figi}! id команды {commandId}. Направление сделки: {dir}; Количество активов: {count}; Разрешена ли маржиналка: {margin}",
|
|
||||||
message.Figi, command.CommandId, command.CommandType, command.Count, command.EnableMargin);
|
|
||||||
if (loggedDeclisions == 0)
|
if (loggedDeclisions == 0)
|
||||||
{
|
{
|
||||||
loggedDeclisions++;
|
loggedDeclisions++;
|
||||||
|
|
|
@ -3,10 +3,8 @@ using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
using Telegram.Bot.Types;
|
|
||||||
using Tinkoff.InvestApi;
|
using Tinkoff.InvestApi;
|
||||||
using Tinkoff.InvestApi.V1;
|
using Tinkoff.InvestApi.V1;
|
||||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.Exchange.Services
|
namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
{
|
{
|
||||||
|
@ -71,13 +69,8 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
ConfirmMarginTrade = tradeCommand.EnableMargin,
|
ConfirmMarginTrade = tradeCommand.EnableMargin,
|
||||||
};
|
};
|
||||||
|
|
||||||
_logger.LogWarning("Получена команда c id {commandId} на операцию с активом {figi}! Тип заявки сделки: {dir}; Количество активов: {count}; Разрешена ли маржиналка: {margin}",
|
|
||||||
tradeCommand.CommandId, req.InstrumentId, req.OrderType, req.Quantity, req.ConfirmMarginTrade);
|
|
||||||
|
|
||||||
var res = await _investApiClient.Orders.PostOrderAsync(req);
|
var res = await _investApiClient.Orders.PostOrderAsync(req);
|
||||||
|
|
||||||
_logger.LogWarning("Исполнена команда c id {commandId} на операцию с активом {figi}! Направление: {dir}; Число лотов: {lots}; цена: {price}", tradeCommand.CommandId, res.Figi,
|
|
||||||
res.Direction, res.LotsExecuted, (decimal)res.ExecutedOrderPrice);
|
|
||||||
//var result = new DealResult
|
//var result = new DealResult
|
||||||
//{
|
//{
|
||||||
// Count = sign * res.LotsExecuted,
|
// Count = sign * res.LotsExecuted,
|
||||||
|
|
|
@ -4,10 +4,8 @@ using KLHZ.Trader.Core.DataLayer;
|
||||||
using KLHZ.Trader.Core.DataLayer.Entities.Orders;
|
using KLHZ.Trader.Core.DataLayer.Entities.Orders;
|
||||||
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
||||||
using KLHZ.Trader.Core.Exchange.Services;
|
using KLHZ.Trader.Core.Exchange.Services;
|
||||||
using KLHZ.Trader.Core.Math.Declisions.Utils;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace KLHZ.Trader.Service.Controllers
|
namespace KLHZ.Trader.Service.Controllers
|
||||||
{
|
{
|
||||||
|
@ -202,49 +200,6 @@ namespace KLHZ.Trader.Service.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task TestInmterpolate(string figi)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var t1 = DateTime.UtcNow.AddHours(-4);
|
|
||||||
var t2 = DateTime.UtcNow.AddHours(1);
|
|
||||||
|
|
||||||
//t1 = new DateTime(2025, 9, 15, 10, 1, 0, DateTimeKind.Utc);
|
|
||||||
//t2 = new DateTime(2025, 9, 15, 10, 1, 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 res = SignalProcessing.InterpolateData(data.Select(d => d.Time).ToArray(), data.Select(d => (double)d.Value).ToArray(),
|
|
||||||
TimeSpan.FromSeconds(1));
|
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i< res.Item1.Length; i++)
|
|
||||||
{
|
|
||||||
buffer.Add(new ProcessedPrice()
|
|
||||||
{
|
|
||||||
Figi = figi,
|
|
||||||
Processor = "1secinterpol",
|
|
||||||
Ticker = data[0].Ticker,
|
|
||||||
Count = 1,
|
|
||||||
Direction = 0,
|
|
||||||
Time = res.Item1[i],
|
|
||||||
Value =(decimal) res.Item2[i]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await context1.ProcessedPrices.AddRangeAsync(buffer);
|
|
||||||
await context1.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//[HttpGet]
|
//[HttpGet]
|
||||||
//public async Task GetBalance(string figi)
|
//public async Task GetBalance(string figi)
|
||||||
//{
|
//{
|
||||||
|
|
Loading…
Reference in New Issue