using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums; using MathNet.Numerics; namespace KLHZ.Trader.Core.Math.Declisions.Utils { /// /// Обработка последних интервалов истории изменения цен. /// 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(); var y1 = new List(); var x1d = new List(); var x2 = new List(); var y2 = new List(); var x2d = new List(); var y1_approximated = new List(); var y2_approximated = new List(); 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; } } } }