public PairOfVolts(VoltForGrid peak, VoltForGrid valley) { Peak = peak; Valley = valley; }
public static List <Volt> FindMaximasPeakAndValley( IEnumerable <Rate> ticks, int voltageCMA, bool saveVoltsToFile, ref VoltForGrid PeakVolt, ref VoltForGrid ValleyVolt) { var time = DateTime.Now; var tickTimeFirst = ticks.Min(t => t.StartDate); List <Volt> voltagesByTick = GetVoltageByTick(ticks, voltageCMA); var peakVolts = (from v2 in voltagesByTick join v1 in voltagesByTick on v2.Index equals v1.Index + voltageCMA join v3 in voltagesByTick on v2.Index equals v3.Index - voltageCMA where v1.PriceAvg <= v2.PriceAvg && v2.PriceAvg >= v3.PriceAvg select v1).ToArray(); var valleyVolts = (from v2 in voltagesByTick join v1 in voltagesByTick on v2.Index equals v1.Index + voltageCMA join v3 in voltagesByTick on v2.Index equals v3.Index - voltageCMA where v1.PriceAvg >= v2.PriceAvg && v2.PriceAvg <= v3.PriceAvg select v1).ToArray(); var pairOfVolts = new List <PairOfVolts>(); var coeffs = ticks.Select(t => t.PriceAvg).Reverse().ToArray().Regress(1); double a = coeffs[1]; DateTime dateMin = ticks.Min(t => t.StartDate), dateMax = ticks.Max(t => t.StartDate); var borderDate = dateMin.AddSeconds((dateMax - dateMin).TotalSeconds / 2); var peakLambda = new Func <Volt, bool>( (t) => a > 0 ? t.StartDate > borderDate : t.StartDate < borderDate); var valleyLambda = new Func <Volt, bool>( (t) => a <0 ? t.StartDate> borderDate: t.StartDate < borderDate); { var voltPeak = voltagesByTick.Where(peakLambda).Where(rd => rd.PriceAvg > rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).LastOrDefault(); if (voltPeak != null) { var voltValley = voltagesByTick.Where(valleyLambda).Where(rd => rd.PriceAvg < rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).LastOrDefault(); if (voltValley != null) { pairOfVolts.Add(new PairOfVolts( new VoltForGrid(voltPeak.StartDate, voltPeak.VoltsCMA, voltPeak.AskMax, voltPeak.BidMax, voltPeak.PriceAvg1), new VoltForGrid(voltValley.StartDate, voltValley.VoltsCMA, voltValley.AskMin, voltValley.BidMin, voltValley.PriceAvg1) )); } } } #region peak Up/Down if (false) { var peakDown = voltagesByTick.Where(t => t.StartDate < borderDate).Where(rd => rd.PriceAvg > rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).Last(); var valleyDown = voltagesByTick.Where(t => t.StartDate > borderDate).Where(rd => rd.PriceAvg < rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).Last(); var peakUp = voltagesByTick.Where(t => t.StartDate > borderDate).Where(rd => rd.PriceAvg > rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).Last(); var valleyUp = voltagesByTick.Where(t => t.StartDate < borderDate).Where(rd => rd.PriceAvg < rd.PriceAvgAvg).OrderBy(rd => rd.VoltsCMA).Last(); } #endregion if (valleyVolts.Count() > 0 && peakVolts.Count() > 0) { { var voltsAvg = voltagesByTick.Average(v => v.VoltsCMA); var voltsMax = voltagesByTick.Max(v => v.VoltsCMA); var voltsMin = voltagesByTick.Min(v => v.VoltsCMA); var voltsTreashold = voltsAvg + (voltsMax - voltsMin) / 4; { var peakDown = peakVolts.Where(t => t.StartDate <borderDate && t.VoltsCMA> voltsTreashold).OrderBy(rd => rd.PriceAvg).LastOrDefault(); var valleyDown = valleyVolts.Where(t => t.StartDate > borderDate && t.VoltsCMA > voltsTreashold).OrderBy(rd => rd.PriceAvg).FirstOrDefault(); var peakUp = peakVolts.Where(t => t.StartDate > borderDate && t.VoltsCMA > voltsTreashold).OrderBy(rd => rd.PriceAvg).LastOrDefault(); var valleyUp = valleyVolts.Where(t => t.StartDate <borderDate && t.VoltsCMA> voltsTreashold).OrderBy(rd => rd.PriceAvg).FirstOrDefault(); if (peakDown != null && peakUp != null && valleyDown != null && valleyUp != null) { if (peakDown.PriceAvg - valleyDown.PriceAvg > peakUp.PriceAvg - valleyUp.PriceAvg) { pairOfVolts.Add(new PairOfVolts( new VoltForGrid(peakDown.StartDate, peakDown.VoltsCMA, peakDown.AskMax, peakDown.BidMax, peakDown.PriceAvg1), new VoltForGrid(valleyDown.StartDate, valleyDown.VoltsCMA, valleyDown.AskMin, valleyDown.BidMin, valleyDown.PriceAvg1)) ); } else { pairOfVolts.Add(new PairOfVolts( new VoltForGrid(peakUp.StartDate, peakUp.VoltsCMA, peakUp.AskMax, peakUp.BidMax, peakUp.PriceAvg1), new VoltForGrid(valleyUp.StartDate, valleyUp.VoltsCMA, valleyUp.AskMin, valleyUp.BidMin, valleyUp.PriceAvg1)) ); } } } { var peakDown = peakVolts.Where(t => t.StartDate < borderDate).OrderBy(rd => rd.VoltsCMA).LastOrDefault() ?? new Volt(); var valleyDown = valleyVolts.Where(t => t.StartDate > borderDate).OrderBy(rd => rd.VoltsCMA).LastOrDefault() ?? new Volt(); var peakUp = peakVolts.Where(t => t.StartDate > borderDate).OrderBy(rd => rd.VoltsCMA).LastOrDefault() ?? new Volt(); var valleyUp = valleyVolts.Where(t => t.StartDate < borderDate).OrderBy(rd => rd.VoltsCMA).LastOrDefault() ?? new Volt(); if (peakDown.PriceAvg - valleyDown.PriceAvg > peakUp.PriceAvg - valleyUp.PriceAvg) { pairOfVolts.Add(new PairOfVolts( new VoltForGrid(peakDown.StartDate, peakDown.VoltsCMA, peakDown.AskMax, peakDown.BidMax, peakDown.PriceAvg1), new VoltForGrid(valleyDown.StartDate, valleyDown.VoltsCMA, valleyDown.AskMin, valleyDown.BidMin, valleyDown.PriceAvg1)) ); } else { pairOfVolts.Add(new PairOfVolts( new VoltForGrid(peakUp.StartDate, peakUp.VoltsCMA, peakUp.AskMax, peakUp.BidMax, peakUp.PriceAvg1), new VoltForGrid(valleyUp.StartDate, valleyUp.VoltsCMA, valleyUp.AskMin, valleyUp.BidMin, valleyUp.PriceAvg1)) ); } } } } if (pairOfVolts.Count > 1) { var cross = (from p in pairOfVolts.Select(pv => pv.Peak) from v in pairOfVolts.Select(pv => pv.Valley) select new { Peak = p, Valley = v, Spread = p.Average - v.Average } ).OrderBy(pv => pv.Spread).Last(); PeakVolt = cross.Peak; ValleyVolt = cross.Valley; } else { var pair = pairOfVolts.Where(p => p.Spread > 0).OrderBy(p => p.Spread).LastOrDefault(); if (pair != null) { PeakVolt = pair.Peak; ValleyVolt = pair.Valley; } } return(voltagesByTick); }