121 lines
4.5 KiB
C#
121 lines
4.5 KiB
C#
using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
|
|
using MathNet.Numerics;
|
|
|
|
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
|
{
|
|
/// <summary>
|
|
/// Обработка последних интервалов истории изменения цен.
|
|
/// </summary>
|
|
public static class LocalTrends
|
|
{
|
|
public static bool TryGetLocalTrends(DateTime[] times, decimal[] prices, TimeSpan firstPeriod, TimeSpan lastPeriod,
|
|
double meanfullDiff, out TradingEvent res)
|
|
{
|
|
res = TradingEvent.None;
|
|
var success = false;
|
|
|
|
if (times.Length == 0)
|
|
{
|
|
return success;
|
|
}
|
|
var x1 = new List<double>();
|
|
var y1 = new List<double>();
|
|
var x1d = new List<DateTime>();
|
|
var x2 = new List<double>();
|
|
var y2 = new List<double>();
|
|
var x2d = new List<DateTime>();
|
|
var y1_approximated = new List<double>();
|
|
var y2_approximated = new List<double>();
|
|
|
|
var lastTime = times[times.Length - 1];
|
|
var firstTime = times[0];
|
|
var fullPeriod = firstPeriod + lastPeriod;
|
|
|
|
if (lastTime - firstTime > fullPeriod)
|
|
{
|
|
for (int i = 1; i < times.Length - 1; i++)
|
|
{
|
|
var dt1 = lastTime - times[times.Length - i];
|
|
if (dt1 <= lastPeriod)
|
|
{
|
|
x2.Add((times[times.Length - i] - firstTime).TotalSeconds);
|
|
x2d.Add(times[times.Length - i]);
|
|
y2.Add((double)prices[times.Length - i]);
|
|
}
|
|
else if (dt1 <= fullPeriod)
|
|
{
|
|
x1.Add((times[times.Length - i] - firstTime).TotalSeconds);
|
|
x1d.Add(times[times.Length - i]);
|
|
y1.Add((double)prices[times.Length - i]);
|
|
}
|
|
else
|
|
{
|
|
success = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (x1.Count > 1 && x2.Count > 1)
|
|
{
|
|
var line1 = Fit.Line(x1.ToArray(), y1.ToArray());
|
|
var line2 = Fit.Line(x2.ToArray(), y2.ToArray());
|
|
foreach (var x in x1)
|
|
{
|
|
y1_approximated.Add(line1.A + x * line1.B);
|
|
}
|
|
foreach (var x in x2)
|
|
{
|
|
y2_approximated.Add(line2.A + x * line2.B);
|
|
}
|
|
var diff1 = y1_approximated[0] - y1_approximated[y1_approximated.Count - 1];
|
|
var diff2 = y2_approximated[0] - y2_approximated[y2_approximated.Count - 1];
|
|
if (diff1 <= -meanfullDiff && diff2 >= meanfullDiff)
|
|
{
|
|
res |= TradingEvent.CloseShort;
|
|
}
|
|
else if (diff1 >= meanfullDiff && diff2 <= -meanfullDiff)
|
|
{
|
|
res |= TradingEvent.CloseLong;
|
|
}
|
|
else if (diff1 <= -meanfullDiff && diff2 >= meanfullDiff)
|
|
{
|
|
res |= TradingEvent.CloseShort;
|
|
}
|
|
else if (diff1 >= 0 && diff2 <= -meanfullDiff)
|
|
{
|
|
res |= TradingEvent.OpenShort;
|
|
}
|
|
success = true;
|
|
}
|
|
|
|
}
|
|
return success;
|
|
}
|
|
|
|
public static bool TryCalcTrendDiff(DateTime[] times, decimal[] prices, out decimal diff)
|
|
{
|
|
diff = 0;
|
|
if (times.Length <= 1 || times.Length != prices.Length)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
var startTime = times[0];
|
|
var x = new double[times.Length];
|
|
for (int i = 0; i < times.Length - 1; i++)
|
|
{
|
|
x[i] = (times[i] - startTime).TotalSeconds;
|
|
}
|
|
var line = Fit.Line(x.ToArray(), prices.Select(p => (double)p).ToArray());
|
|
|
|
var p1 = line.A + line.B * 0;
|
|
var p2 = line.A + line.B * (times[times.Length - 1] - times[0]).TotalSeconds;
|
|
|
|
diff = (decimal)(p2 - p1);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|