public static Func <WaveRange, double> BestFitProp(this WaveRange wa) { Func <Func <WaveRange, double>, Func <WaveRange, double> > foo = f => f; var foos = new[] { foo(w => w.DistanceByRegression), foo(w => w.WorkByTime) }; return(foos.OrderBy(f => f(wa)).First()); }
public static int Index(this WaveRange wr, IList <WaveRange> wrs, Func <WaveRange, double> value) { return(wrs.OrderByDescending(value).ToList().IndexOf(wr)); }
private void ScanForWaveRanges2(List <Rate> rates) { try { #region Average Wave Height Calc var makeWaves = MonoidsCore.ToFunc((List <Rate>)null, 0.0, 0, (rateses, period, cmaPasses) => { List <WaveRange> wr = GetWaveRanges(rateses, period, cmaPasses); #region Split First Wave var splitIndex = wr.Take(1) .Where(w => !w.IsEmpty) .Select(w => w.Range.IndexOf((w.Slope > 0 ? w.Range.MaxBy(r => r.AskHigh) : w.Range.MinBy(r => r.AskLow) ).First())) .DefaultIfEmpty(-1) .First(); WaveRange wTail = new WaveRange(0); wr.Take(1) .Where(w => !w.IsEmpty) .ToArray() .Select(w => w.Count) .Where(wrCount => splitIndex.Div(wrCount) > .1) .Select(wrCount => { var range = wr[0].Range; var wr0 = range.GetRange(0, splitIndex + 1).ToList(); var rangeTail = range.GetRange(splitIndex + 1, range.Count - (splitIndex + 1)); if (rangeTail.Any() && rangeTail.Last().StartDate.Subtract(rangeTail[0].StartDate).TotalSeconds > 3) { return new { wr0, wrTail = new WaveRange(rangeTail, PointSize, BarPeriod) { IsTail = true } } } ; return(null); }) .Where(x => x != null) .ForEach(x => { wr = new[] { x.wr0 }.Select(w => new WaveRange(w, PointSize, BarPeriod)).Concat(wr.Skip(1)).ToList(); wTail = x.wrTail; }); if (wTail.Count < 3 || wTail.TotalSeconds < 3) { wTail = new WaveRange(); } #endregion #region Wave Stats #region Stats Funcs Func <IList <WaveRange>, Func <WaveRange, double>, double> summ = (wrs0, v) => wrs0.Select(v).DefaultIfEmpty(double.NaN).Sum(); Func <IList <WaveRange>, Func <WaveRange, double>, double> avg = (wrs0, v) => summ(wrs0, w => v(w) * w.HSDRatio) / summ(wrs0, w => w.HSDRatio); Func <IList <WaveRange>, Func <WaveRange, double>, Func <WaveRange, double>, double> avg2 = (wrs0, v, d) => summ(wrs0, w => v(w) * d(w)) / summ(wrs0, w => d(w)); Func <Func <WaveRange, double>, double> avgUp = value => wr.Select(value).DefaultIfEmpty().ToArray().AverageByAverageUp(); Func <IList <WaveRange>, Func <WaveRange, double>, double> avgStd = (wrs0, v) => { var sd = wrs0.StandardDeviation(v) * 2; var a = wrs0.Average(v); return(wrs0.Select(w => v(w).Abs()).Where(d => d.Between(a - sd, a + sd)).Average()); }; Func <Func <WaveRange, double>, double> rsd = value => wr.Select(value).DefaultIfEmpty().Sum(); #endregion var wrs = wr.SkipLast(wr.Count > 4 ? 1 : 0).Where(w => !w.Distance.IsNaNOrZero()).ToArray(); Func <Func <WaveRange, double>, double, double> pwmp = (w, power) => wrs.Select(w).DefaultIfEmpty().RootMeanPower(power); var hasCalm3 = TradeConditionsHave(Calm3Ok); var TrendHeightPerc = 2.0; var ws = new WaveRange(1) { Distance = pwmp(w => w.Distance, 1 / TrendHeightPerc), DistanceCma = avg2(wrs, w => w.DistanceCma, w => w.Distance), DistanceByRegression = avg2(wrs, w => w.DistanceByRegression, w => w.Distance), WorkByHeight = rsd(w => w.WorkByHeight), WorkByTime = rsd(w => w.WorkByTime), Angle = hasCalm3 ? pwmp(w => w.Angle.Abs(), 1 / TrendHeightPerc) : wrs.Select(w => w.Angle.Abs()).RelativeStandardDeviation().ToPercent(), TotalMinutes = pwmp(w => w.TotalMinutes, 1 / TrendHeightPerc), HSDRatio = wrs.Select(w => w.StDev).RelativeStandardDeviation().ToPercent(),//avg2(wrs, w => w.HSDRatio, w => 1 / w.Distance), Height = rsd(w => w.Height), StDev = wrs.Select(w => w.StDev).RootMeanPowerByPosition(WaveStDevPowerS) }; ws.PipsPerMinute = ws.Distance / ws.TotalMinutes; var wa = new WaveRange(1) { DistanceCma = avg2(wrs, w => w.DistanceCma, w => 1 / Math.Pow(w.Distance, 1 / 3.0)), DistanceByRegression = avg2(wrs, w => w.DistanceByRegression, w => 1 / Math.Pow(w.Distance, 1 / 3.0)), WorkByHeight = avg(wrs, w => w.WorkByHeight), WorkByTime = avg(wrs, w => w.WorkByTime), HSDRatio = avg2(wrs, w => w.HSDRatio, w => w.Distance), Height = avg(wrs, w => w.Height), StDev = wrs.Select(w => w.StDev).RootMeanPowerByPosition(WaveStDevPower) }; try { wa.Distance = pwmp(w => w.Distance, TrendHeightPerc); wa.Angle = pwmp(w => w.Angle.Abs(), TrendHeightPerc); wa.TotalMinutes = pwmp(w => w.TotalMinutes, TrendHeightPerc); wa.PipsPerMinute = wa.Distance / wa.TotalMinutes; } catch (Exception exc) { Log = exc; return(null); } #endregion #region Conditions wr.ForEach(w => w.IsFatnessOk = w.StDev <= wa.StDev); wr.ForEach(w => w.IsDistanceCmaOk = w.DistanceCma >= wa.DistanceCma); #endregion return(new { wr, wTail, wa, ws }); }); #endregion if (!IsCorridorFrozen()) { var wrwt = makeWaves(rates, PriceCmaLevels, CmaPasses); if (wrwt == null) { return; } WaveRanges = wrwt.wr; WaveRangeTail = wrwt.wTail; WaveRangeSum = wrwt.ws; WaveRangeAvg = wrwt.wa; #region Adjust CmaPasses Action setCmaPasses = () => { try { Func <WaveRange, double> stDever = WaveSmoothFunc(); var makeWaveses = MonoidsCore.ToFunc((IEnumerable <int>)null, ups => Partitioner.Create(ups.ToArray(), true) .AsParallel().Select(cmaPasses => new { sd = stDever(makeWaves(rates, PriceCmaLevels, cmaPasses).ws), cmaPasses })); var up = makeWaveses(Lib.IteratonSequence(1, 600, i => i.Div(200).Ceiling())).OrderBy(x => x.cmaPasses).ToList(); var bufferCount = rates.Count.Div(100).ToInt(); var cma = Enumerable.Range(0, up.Count - bufferCount) .Select(i => up.GetRange(i, bufferCount).AsIList()) .Where(b => b.Count == bufferCount) .Select(b => new { b, avg = b.Average(y => y.sd) }) .Aggregate((b1, b2) => b1.avg < b2.avg ? b1 : b2) .b.MinBy(x => x.sd) .OrderBy(x => x.cmaPasses) .First().cmaPasses; CmaPassesCalc = cma; CmaPasses = CmaPassesCalc; } catch (Exception exc) { Log = exc; } }; if (CmaPassesMin > 0) { //setCmaPasses(); _addHistoryOrdersBuffer.Push(() => { var sw = Stopwatch.StartNew(); setCmaPasses(); Log = new Exception(new { CmaPassesCalc, CmaPasses, sw.ElapsedMilliseconds } +""); }); } #endregion } else { var firstWaveRange = WaveRanges.Take(1).Select(wr => rates.BackwardsIterator().TakeWhile(r => r.StartDate >= wr.StartDate).Reverse().ToList()); WaveRanges = firstWaveRange.Select(wr => new WaveRange(wr, PointSize, BarPeriod)).Concat(WaveRanges.Skip(1)).ToList(); WaveRangeTail = new WaveRange(0); } Func <WaveRange, double> bfp = w => w.DistanceByRegression;// WaveRangeAvg.BestFitProp(); WaveFirstSecondRatio = WaveRanges.Take(1).Select(w1 => bfp(w1) / bfp(WaveRangeAvg)).FirstOrDefault(); WaveHeightAverage = WaveRangeAvg.Height; WaveHeightPower = new[] { WaveRangeAvg.WorkByHeight, WaveRangeAvg.Height, WaveRangeAvg.DistanceByRegression }.StandardDeviation(); } catch (Exception exc) { Log = exc; } }