klhztrader/KLHZ.Trader.Core.Math/Declisions/Utils/Statistics.cs

111 lines
4.1 KiB
C#

using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
namespace KLHZ.Trader.Core.Math.Declisions.Utils
{
public static class Statistics
{
public static decimal Mean(this CachedValue[] values)
{
return values.Sum(x => x.Count) / values.Length;
}
public static decimal Mean2(this CachedValue[] values)
{
return values.Sum(x => x.Price) / values.Length;
}
private static (decimal mean, decimal std) CaclSigma(decimal[] values)
{
var mean = values.Sum() / values.Length;
var data = new decimal[values.Length];
Array.Copy(values, data, data.Length);
for (int i = 0; i < data.Length; i++)
{
var v = data[i] - mean;
data[i] = v * v;
}
var std = System.Math.Pow((double)(data.Sum() / (data.Length - 1)), 0.5);
return (mean, (decimal)std);
}
public static decimal[] ClearNSigmaReqursive(decimal[] values, int depth = 0, int sigmasCount = 3)
{
if (values.Length <= 1 || depth > 10) return values;
var sigmaRes = CaclSigma(values);
var std = sigmaRes.std;
var mean = sigmaRes.mean;
var forRes = new List<decimal>();
var _3std = sigmasCount * std;
foreach (var v in values)
{
if (System.Math.Abs(mean - v) < _3std)
{
forRes.Add(v);
}
}
if (forRes.Count != values.Length)
{
return ClearNSigmaReqursive(forRes.ToArray(), depth + 1);
}
else
{
return forRes.ToArray();
}
}
public static bool TryCalcTimeWindowsDiff(this CachedValue[] values, TimeSpan boundLeft, TimeSpan boundRight,
Func<CachedValue, decimal> fieldSelector, bool calcMean, out decimal result)
{
result = default;
if (values.Length > 1)
{
var shiftTimeR = values.Last().Time - boundRight;
var shiftTimeL = values.Last().Time - boundLeft;
var valuesOld = values.Where(b => b.Time < shiftTimeR && b.Time >= shiftTimeL).ToArray();
var valuesNew = values.Where(b => b.Time >= shiftTimeR).ToArray();
if (valuesOld.Length > 0 && valuesNew.Length > 0)
{
var valNew = valuesNew.Sum(fieldSelector);
var valOld = valuesOld.Sum(fieldSelector);
if (calcMean)
{
valNew = valNew / valuesNew.Length;
valOld = valOld / valuesOld.Length;
}
result = valNew - valOld;
return true;
}
}
return false;
}
public static bool TryCalcPirsonCorrelation(this CachedValue[] values, TimeSpan period, out decimal result)
{
result = default;
if (values.Any())
{
var shiftTimeDiffs1 = values.Last().Time - period;
values = values.Where(b => b.Time >= shiftTimeDiffs1).ToArray();
if (values.Any())
{
var tradevolume_diffMean = values.Mean();
var dprice_diffMean = values.Mean2();
var sum1 = (double)values.Sum(d => (d.Value2 - tradevolume_diffMean) * (d.Value - dprice_diffMean));
var sum2 = values.Sum(d => (d.Value2 - tradevolume_diffMean) * (d.Value2 - tradevolume_diffMean));
var sum3 = values.Sum(d => (d.Value - dprice_diffMean) * (d.Value - dprice_diffMean));
if (sum2 != 0 && sum3 != 0)
{
result = (decimal)(sum1 / System.Math.Sqrt((double)(sum2 * sum3)));
return true;
}
}
}
return false;
}
}
}