public void PollForEventActionsToStop() { using (var db = new PoloniexContext()) { _EventActionsToStop = db.EventActions.Where(x => x.EventActionStatus == EventActionStatus.RequestToStop).ToList(); } }
public void StartEventActions() { foreach (var ea in _EventActionsToStart) { switch (ea.EventActionType) { case EventActionType.MovingAverage: MovingAverageManager.InitEmaBySma(ea.EventActionId); ea.Action = MovingAverageManager.UpdateEma; break; case EventActionType.TradeSignal: var currencyPair = ea.TradeSignalEventAction.CurrencyPair; var tradeSignalConfiguration = ea.TradeSignalEventAction.TradeSignalConfiguration; TradeSignalManager.InitProcessEmaCrossOverSignal(currencyPair, tradeSignalConfiguration); ea.Action = TradeSignalManager.ProcessEmaCrossOverSignal; break; case EventActionType.ProcessTradeOrder: ea.Action = TradeOrderManager.ProcessTradeOrders; break; } var globalStateEvent = _globalStateManager.GetTaskLoop(ea.TaskId); var eventActions = globalStateEvent.Item3; ea.EventActionStatus = EventActionStatus.Started; using (var db = new PoloniexContext()) { db.Entry(ea).State = EntityState.Modified; db.SaveChanges(); } eventActions.Add(ea); Logger.Write($"Started {ea.EventActionType} with eventActionId: {ea.EventActionId}", Logger.LogType.ServiceLog); } }
public void StopTasks() { foreach (var taskLoop in _tasksToStop) { switch (taskLoop.Task.TaskType) { case "GatherTask": var tuple = _globalStateManager.RemoveTaskLoop(taskLoop.TaskId); tuple.Item2.Stop(); // stop timer (Item2 is timer) using (var db = new PoloniexContext()) { taskLoop.LoopStatus = LoopStatus.Stopped; db.Entry(taskLoop).State = EntityState.Modified; db.SaveChanges(); } var eventActions = tuple.Item3; foreach (var ea in eventActions) { ea.EventActionStatus = EventActionStatus.Stopped; using (var db = new PoloniexContext()) { db.Entry(ea).State = EntityState.Modified; db.SaveChanges(); } Logger.Write($"Stopped {ea.EventActionType} with eventActionId: {ea.EventActionId}", Logger.LogType.ServiceLog); } Logger.Write($"Stopped {taskLoop.Task.TaskType} with taskId: {taskLoop.TaskId}", Logger.LogType.ServiceLog); break; } } }
public void PollForTasksToStop() { using (var db = new PoloniexContext()) { _tasksToStop = db.TaskLoops.Where(x => x.LoopStatus == LoopStatus.RequestToStop).Include(x => x.Task.GatherTask).ToList(); } }
public void StartTasks() { foreach (var taskLoop in _tasksToStart) { switch (taskLoop.Task.TaskType) { case "GatherTask": System.Threading.Tasks.Task.Run(() => { try { GatherTaskManager.BackFillGatherTaskData(6, taskLoop.Task.GatherTask.CurrencyPair, null, DateTime.Parse("01/01/1970")); } catch (Exception exception) { Logger.WriteException(exception); } }); var eventActions = new List <EventAction>(); _globalStateManager.AddTaskLoop(taskLoop, GatherTaskManager.GetGatherTaskTimer(taskLoop.TaskId, eventActions), eventActions); using (var db = new PoloniexContext()) { taskLoop.LoopStatus = LoopStatus.Started; taskLoop.LoopStartedDateTime = DateTime.UtcNow; db.Entry(taskLoop).State = EntityState.Modified; db.SaveChanges(); } Logger.Write($"Started {taskLoop.Task.TaskType} with taskId: {taskLoop.TaskId}", Logger.LogType.ServiceLog); break; } } }
public static Timer GetGatherTaskTimer(Guid taskId, List <EventAction> eventActions) { GatherTask gatherTask; using (var db = new PoloniexContext()) { gatherTask = db.GatherTasks.Include(x => x.Task.TaskLoop).Single(x => x.TaskId == taskId); } return(GetGatherTaskTimer(gatherTask.CurrencyPair, gatherTask.Task.TaskLoop.SecondsPerTick, eventActions, true)); }
public static void Terminate() { using (var db = new PoloniexContext()) { var taskLoops = db.TaskLoops.Where(x => x.LoopStatus == LoopStatus.Started || x.LoopStatus == LoopStatus.RequestToStop).ToList(); taskLoops.ForEach(x => { x.LoopStatus = LoopStatus.Stopped; }); db.SaveChanges(); } }
public void PollForEventActionsToStart() { using (var db = new PoloniexContext()) { _EventActionsToStart = db.EventActions .Where(x => x.EventActionStatus == EventActionStatus.RequestToStart && x.Task.TaskLoop.LoopStatus == LoopStatus.Started) .Include(x => x.MovingAverageEventAction) .Include(x => x.TradeSignalEventAction.TradeSignalConfiguration) .Include(x => x.TradeOrderEventAction) .ToList(); } }
public static void ProcessTradeOrders(Guid eventActionId) { using (var db = new PoloniexContext()) { var currencyPair = db.EventActions.Single(x => x.EventActionId == eventActionId).TradeOrderEventAction.CurrencyPair; // get oldest uncompleted order var oldest = db.TradeSignalOrders .Where(x => x.CurrencyPair == currencyPair && !x.IsProcessed) .OrderBy(x => x.OrderRequestedDateTime) .FirstOrDefault(); if (oldest != null) { Logger.Write($"Processing TradeSignalOrderId: {oldest.TradeSignalOrderId} for eventActionId: {eventActionId}", Logger.LogType.TransactionLog); oldest.IsProcessed = true; oldest.InProgress = true; db.Entry(oldest).State = EntityState.Modified; db.SaveChanges(); if (oldest.TradeOrderType == TradeOrderType.Buy) { TradeManager.BuyCurrencyFromUsdt(currencyPair, ref oldest); } else { TradeManager.SellCurrencyToUsdt(currencyPair, ref oldest); } oldest.OrderCompletedDateTime = DateTime.UtcNow; oldest.InProgress = false; oldest.ProcessedByEventActionId = eventActionId; db.Entry(oldest).State = EntityState.Modified; db.SaveChanges(); } }; }
public static void UpdateEma(Guid eventActionId) { using (var db = new PoloniexContext()) { var eventAction = db.EventActions.Include(x => x.MovingAverageEventAction).Single(x => x.EventActionId == eventActionId); var closingValue = db.CurrencyDataPoints .Where(x => x.CurrencyPair == eventAction.MovingAverageEventAction.CurrencyPair) .OrderByDescending(x => x.ClosingDateTime) .First(); var prevEma = db.MovingAverages .Where(x => x.MovingAverageType == eventAction.MovingAverageEventAction.MovingAverageType && x.CurrencyPair == eventAction.MovingAverageEventAction.CurrencyPair && x.Interval == eventAction.MovingAverageEventAction.Interval && x.MinutesPerInterval == eventAction.MovingAverageEventAction.MinutesPerInterval) .OrderByDescending(x => x.ClosingDateTime) .First(); // -15 seconds to account for timer skew if (closingValue.ClosingDateTime >= prevEma.ClosingDateTime.AddSeconds(-15).AddMinutes(prevEma.MinutesPerInterval)) { var curEma = new MovingAverage() { MovingAverageType = MovingAverageType.ExponentialMovingAverage, CurrencyPair = eventAction.MovingAverageEventAction.CurrencyPair, Interval = eventAction.MovingAverageEventAction.Interval, MinutesPerInterval = eventAction.MovingAverageEventAction.MinutesPerInterval, ClosingDateTime = DateTime.UtcNow, MovingAverageValue = MovingAverageCalculations.CalculateEma(closingValue.ClosingValue, prevEma.MovingAverageValue, eventAction.MovingAverageEventAction.Interval), LastClosingValue = closingValue.ClosingValue }; db.MovingAverages.Add(curEma); db.SaveChanges(); } } }
public static void InitEmaBySma(Guid eventActionId) { using (var db = new PoloniexContext()) { var eventAction = db.EventActions.Include(x => x.MovingAverageEventAction).Single(x => x.EventActionId == eventActionId); try { var beginDateTime = DateTime.UtcNow.AddMilliseconds(333); var endDateTime = beginDateTime.AddMinutes(-(eventAction.MovingAverageEventAction.Interval * eventAction.MovingAverageEventAction.MinutesPerInterval)); var currencyPair = eventAction.MovingAverageEventAction.CurrencyPair; var interval = eventAction.MovingAverageEventAction.Interval; var minutesPerInterval = eventAction.MovingAverageEventAction.MinutesPerInterval; BackFillEma(currencyPair, interval, minutesPerInterval, beginDateTime, endDateTime); } catch (Exception exception) { Logger.WriteException(exception); } } }
public void StopEventActions() { foreach (var ea in _EventActionsToStop) { var globalStateEvent = _globalStateManager.GetTaskLoop(ea.TaskId); var eventActions = globalStateEvent.Item3; for (int i = 0; i < eventActions.Count; i++) { if (eventActions[i].EventActionId == ea.EventActionId) { eventActions.RemoveAt(i); break; } } ea.EventActionStatus = EventActionStatus.Stopped; using (var db = new PoloniexContext()) { db.Entry(ea).State = EntityState.Modified; db.SaveChanges(); } Logger.Write($"Stopped {ea.EventActionType} with eventActionId: {ea.EventActionId}", Logger.LogType.ServiceLog); } }
/* additional helpers */ public static void BackFillEma(string currencyPair, int interval, int minutesPerInterval, DateTime beginDateTime, DateTime endDateTime, decimal?prevEmaSeed = null) { // add time buffer to guarantee beginDate inclusive / endDate exclusive var delEndDateTime = endDateTime.AddSeconds(30); var delBeginDateTime = beginDateTime.AddSeconds(30); List <CurrencyDataPoint> dataPoints; List <decimal> smaInput; decimal prevEma; using (var db = new PoloniexContext()) { var delMovingAverages = db.MovingAverages .Where(x => x.CurrencyPair == currencyPair && x.Interval == interval && x.MinutesPerInterval == minutesPerInterval && x.ClosingDateTime <= delBeginDateTime && x.ClosingDateTime >= delEndDateTime); db.MovingAverages.RemoveRange(delMovingAverages); db.SaveChanges(); dataPoints = db.CurrencyDataPoints .Where(x => x.CurrencyPair == currencyPair && x.ClosingDateTime <= beginDateTime && x.ClosingDateTime >= endDateTime) .ToList(); if (prevEmaSeed == null) { smaInput = db.CurrencyDataPoints .Where(x => x.CurrencyPair == currencyPair && x.ClosingDateTime < endDateTime) .OrderBy(x => x.ClosingDateTime) .Select(x => x.ClosingValue) .Take(interval) .ToList(); prevEma = MovingAverageCalculations.CalculateSma(smaInput); } else { prevEma = prevEmaSeed.Value; } } // Begin calculating List <MovingAverage> movingAveragesData = new List <MovingAverage>(); for (int i = 0; i < dataPoints.Count; i++) { if (i % minutesPerInterval == 0) { var newMovingAverage = new MovingAverage() { MovingAverageType = MovingAverageType.ExponentialMovingAverage, CurrencyPair = currencyPair, Interval = interval, MinutesPerInterval = minutesPerInterval, ClosingDateTime = dataPoints[i].ClosingDateTime, MovingAverageValue = MovingAverageCalculations.CalculateEma(dataPoints[i].ClosingValue, prevEma, interval), LastClosingValue = dataPoints[i].ClosingValue }; movingAveragesData.Add(newMovingAverage); prevEma = newMovingAverage.MovingAverageValue; } } BulkInsertMovingAverages(movingAveragesData); }
/* additional helpers */ public static void BackFillGatherTaskData(int numberOfQuarterDays, string currencyPair, DateTime?inputDateTime = null, DateTime?markerDate = null) { markerDate = markerDate ?? DateTime.Parse("01/01/1970"); // marker date is for setting CreatedDateTime (useful for knowing which data was prepopulated) var totalTimeToGoBack = numberOfQuarterDays * 21600; var curDateTime = inputDateTime ?? DateTime.UtcNow; // add 30 seconds for possible processing delay from gatherers (maintains begin inclusive and end exclusive) var delBeginDateTime = curDateTime.AddSeconds(30); var delEndDateTime = curDateTime.AddSeconds(-totalTimeToGoBack).AddSeconds(30); using (var db = new PoloniexContext()) { var del = db.CurrencyDataPoints .Where(x => x.ClosingDateTime <= delBeginDateTime && x.ClosingDateTime >= delEndDateTime && x.CurrencyPair == currencyPair).ToList(); db.CurrencyDataPoints.RemoveRange(del); db.SaveChanges(); } var currencyDataPoints = new List <CurrencyDataPoint>(); // 2678400 seconds = 31 days // 21600 seconds = 6 hours //for (int i = 2678400; i > 0; i = i - 21600) for (int i = totalTimeToGoBack; i > 0; i = i - 21600) { var intervalBeginningDateTime = curDateTime.AddSeconds(-i); var intervalEndDateTime = curDateTime.AddSeconds(-(i - 21600)); var poloniexData = PoloniexExchangeService.Instance.ReturnTradeHistory(currencyPair, intervalBeginningDateTime, intervalEndDateTime); poloniexData = poloniexData.OrderBy(x => x.date).ToList(); decimal rate = poloniexData.First().rate; // how many minute intervals in 21600 seconds ... 360 for (int j = 0; j < 360; j++) { int pos = 0; var currencyDataPoint = new CurrencyDataPoint { CurrencyPair = currencyPair, ClosingDateTime = intervalBeginningDateTime.AddSeconds((j + 1) * 60), CreatedDateTime = markerDate.Value // notify was populated by backfill }; bool isAnyData = false; while (pos < poloniexData.Count && poloniexData[pos].date < currencyDataPoint.ClosingDateTime) { isAnyData = true; pos++; } if (pos == poloniexData.Count) { pos--; } if (isAnyData) { rate = poloniexData[pos].rate; } currencyDataPoint.ClosingValue = rate; currencyDataPoints.Add(currencyDataPoint); } if (currencyDataPoints.Count > 25000) { BulkInsertCurrencyDataPoints(currencyDataPoints); currencyDataPoints = new List <CurrencyDataPoint>(); } } BulkInsertCurrencyDataPoints(currencyDataPoints); return; }
public static void GatherTaskElapsed(object sender, string currencyPair, int interval, Timer t, List <EventAction> eventActions) { t.Interval = TimerUtility.GetAdjustedInterval(interval); t.Start(); System.Threading.Tasks.Task.Run(() => { try { DateTime dateTimeNow = DateTime.UtcNow; DateTime dateTimePast = dateTimeNow.AddSeconds(-(60 * 4)); var result = PoloniexExchangeService.Instance.ReturnTradeHistory(currencyPair, dateTimePast, dateTimeNow); result = result.OrderBy(x => x.date).ToList(); var dataPoint = new CurrencyDataPoint { CurrencyPair = currencyPair, ClosingDateTime = dateTimeNow, }; if (result.Any()) { var curRate = result.Last().rate; dataPoint.ClosingValue = curRate; } else { using (var db = new PoloniexContext()) { dataPoint.ClosingValue = db.CurrencyDataPoints .Where(x => x.CurrencyPair == dataPoint.CurrencyPair) .OrderByDescending(x => x.ClosingDateTime) .First().ClosingValue; } } using (var db = new PoloniexContext()) { dataPoint.CreatedDateTime = DateTime.UtcNow; db.CurrencyDataPoints.Add(dataPoint); db.SaveChanges(); } if (eventActions != null) { var sortedActions = eventActions.OrderBy(x => x.Priority).ToList(); for (int i = 0; i < sortedActions.Count(); i++) { Logger.Write($"{sortedActions[i].EventActionId}: Executing action {i + 1} of {sortedActions.Count()} - {sortedActions[i].EventActionType}", Logger.LogType.ServiceLog); var threadEventAction = sortedActions[i]; threadEventAction.Action(threadEventAction.EventActionId); } } } catch (Exception exception) { Logger.WriteException(exception); } }); }
public static void ProcessEmaCrossOverSignal(Guid eventActionId) { using (var db = new PoloniexContext()) { var tradeSignalEventAction = db.TradeSignalEventActions .Single(x => x.EventActionId == eventActionId); var currencyPair = tradeSignalEventAction.CurrencyPair; var latestShorterMovingAverage = db.MovingAverages .Where(x => x.CurrencyPair == tradeSignalEventAction.CurrencyPair && x.Interval == tradeSignalEventAction.ShorterMovingAverageInterval) .OrderByDescending(x => x.ClosingDateTime) .First(); var latestLongerMovingAverage = db.MovingAverages .Where(x => x.CurrencyPair == tradeSignalEventAction.CurrencyPair && x.Interval == tradeSignalEventAction.LongerMovingAverageInterval) .OrderByDescending(x => x.ClosingDateTime) .First(); var lastClosingValue = db.CurrencyDataPoints .Where(x => x.CurrencyPair == tradeSignalEventAction.CurrencyPair) .OrderByDescending(x => x.ClosingDateTime) .First().ClosingValue; Signals[currencyPair].IsBullish = latestShorterMovingAverage.MovingAverageValue - latestLongerMovingAverage.MovingAverageValue >= 0; if (!Signals[currencyPair].Init) { if (!Signals[currencyPair].WasBullish && Signals[currencyPair].IsBullish && !Signals[currencyPair].HasHoldings) { // BUY Signals[currencyPair].ShouldBuy = true; Signals[currencyPair].BuyValue = lastClosingValue; } if (Signals[currencyPair].HasHoldings) { decimal high; decimal low; high = Signals[currencyPair].BuyValue * (1M + Configurations[currencyPair].StopLossPercentageUpper); low = Signals[currencyPair].BuyValue * (1M - Configurations[currencyPair].StopLossPercentageLower); if (Configurations[currencyPair].IsStopLossTailing) { if (lastClosingValue >= high) { Signals[currencyPair].BuyValue = high * (1M + Configurations[currencyPair].StopLossPercentageUpper); } if (lastClosingValue <= low) { Signals[currencyPair].ShouldSell = true; } } else { if (lastClosingValue >= high || lastClosingValue <= low) { Signals[currencyPair].ShouldSell = true; } } } if (Signals[currencyPair].ShouldBuy) { var buyTradeSignalOrder = new TradeSignalOrder() { CurrencyPair = currencyPair, TradeOrderType = TradeOrderType.Buy, LastValueAtRequest = latestShorterMovingAverage.LastClosingValue, IsProcessed = false, InProgress = false, OrderRequestedDateTime = DateTime.UtcNow, CreatedByEventActionId = eventActionId }; db.TradeSignalOrders.Add(buyTradeSignalOrder); db.SaveChanges(); Signals[currencyPair].HasHoldings = true; } if (Signals[currencyPair].ShouldSell) { var sellTradeSignalOrder = new TradeSignalOrder() { CurrencyPair = currencyPair, TradeOrderType = TradeOrderType.Sell, LastValueAtRequest = latestShorterMovingAverage.LastClosingValue, IsProcessed = false, InProgress = false, OrderRequestedDateTime = DateTime.UtcNow, CreatedByEventActionId = eventActionId }; db.TradeSignalOrders.Add(sellTradeSignalOrder); db.SaveChanges(); Signals[currencyPair].HasHoldings = false; } Logger.Write($"currencyPair: {currencyPair}, wasBullish: {Signals[currencyPair].WasBullish}, isBullish: {Signals[currencyPair].IsBullish}, hasHolding: {Signals[currencyPair].HasHoldings}, shouldBuy: {Signals[currencyPair].ShouldBuy}, shouldSell: {Signals[currencyPair].ShouldSell}", Logger.LogType.TransactionLog); Signals[currencyPair].ShouldBuy = false; Signals[currencyPair].ShouldSell = false; } else { Logger.Write($"TradeTask init for {currencyPair}, evenActionId: {eventActionId} (see TransactionLog)", Logger.LogType.ServiceLog); Signals[currencyPair].Init = false; } Signals[currencyPair].WasBullish = Signals[currencyPair].IsBullish; } }
public static void Test() { var currencyPairsStr = ConfigurationManager.AppSettings["currencyPairs"]; var currencyPairs = currencyPairsStr.Split(',').ToList(); for (int counter = 1; counter <= 4; counter++) { foreach (var currencyPair in currencyPairs) { /* inclusive latest date */ var dt = DateTime.UtcNow.AddDays(0); // trim to start of hour (begin) dt = dt.AddMilliseconds(-dt.Millisecond); dt = dt.AddSeconds(-dt.Second); dt = dt.AddMinutes(-dt.Minute); //dt = dt.AddHours(-dt.Hour); //dt = dt.AddDays(-dt.Day + 1); // trim to start of hour (end) var numberOfDays = 45; int quarterDaysToGoBack = (int)(4 * (double)numberOfDays); var shorterInterval = 12; var longerInterval = 26; var minutesPerInterval = 15 * counter; dt = dt.AddMinutes(-(2 * minutesPerInterval)); //var currencyPair = CurrencyPairConstants.USDT_BTC; // 15 //var currencyPair = CurrencyPairConstants.USDT_DASH; // 30 // 45 //var currencyPair = CurrencyPairConstants.USDT_ETH; // 15 //var currencyPair = CurrencyPairConstants.USDT_LTC; // 30 // 45 //var currencyPair = CurrencyPairConstants.USDT_ZEC; // 30 // 45 // ################################################################ var secondsBack = quarterDaysToGoBack * 21600; quarterDaysToGoBack++; // ################################################################ var window = numberOfDays; //var window = 30; //var window = 60; //var window = 120; var numberOfTimesToShift = numberOfDays / window; DateTime startDateTime = dt; DateTime endDateTime = dt.AddSeconds(-secondsBack); bool backFillCurrencyDataPoints = false; backFillCurrencyDataPoints = counter == 1;//true; if (backFillCurrencyDataPoints) { //GatherTaskManager.BackFillGatherTaskData(quarterDaysToGoBack, currencyPair, dt, DateTime.Parse("1970-01-01 00:00:00.000")); // only need to backfill 6 quarter days if AutoLoader is used. GatherTaskManager.BackFillGatherTaskData(6, currencyPair, dt, DateTime.Parse("1970-01-01 00:00:00.000")); } // ################################################################ if (ForceIntervalForRegression != null && ForceIntervalForRegression[currencyPair] != minutesPerInterval) { continue; } // ################################################################ bool backFillMovingAverages = false; backFillMovingAverages = true; if (backFillMovingAverages) { MovingAverageManager.BackFillEma(currencyPair, shorterInterval, minutesPerInterval, dt, dt.AddSeconds(-secondsBack), null); MovingAverageManager.BackFillEma(currencyPair, longerInterval, minutesPerInterval, dt, dt.AddSeconds(-secondsBack), null); } // ################################################################ // start manipulations startDateTime = endDateTime.AddDays(window); List <RegressionResults> results = new List <RegressionResults>(); for (int looper = 0; looper < numberOfTimesToShift; looper++) { ProfitAnalyzer.ResetMemory(); ProfitAnalyzer.ResetStats(); List <MovingAverage> shorterMovingAverages; List <MovingAverage> longerMovingAverages; using (var db = new PoloniexContext()) { shorterMovingAverages = db.MovingAverages .Where(x => x.Interval == shorterInterval && x.MinutesPerInterval == minutesPerInterval && x.CurrencyPair == currencyPair && x.ClosingDateTime >= endDateTime && x.ClosingDateTime <= startDateTime) .OrderBy(x => x.ClosingDateTime) .ToList(); longerMovingAverages = db.MovingAverages .Where(x => x.Interval == longerInterval && x.MinutesPerInterval == minutesPerInterval && x.CurrencyPair == currencyPair && x.ClosingDateTime >= endDateTime && x.ClosingDateTime <= startDateTime) .OrderBy(x => x.ClosingDateTime) .ToList(); } //ProfitAnalyzer.MacdEma = shorterMovingAverages[0].MovingAverageValue - longerMovingAverages[0].MovingAverageValue; for (int i = 0; i < shorterMovingAverages.Count; i++) { //ProfitAnalyzer.ProcessMacdMovingAverageSignals(shorterMovingAverages[i].MovingAverageValue, longerMovingAverages[i].MovingAverageValue, shorterMovingAverages[i].LastClosingValue, shorterMovingAverages[i].ClosingDateTime); ProfitAnalyzer.Process(shorterMovingAverages[i].MovingAverageValue, longerMovingAverages[i].MovingAverageValue, shorterMovingAverages[i].LastClosingValue, shorterMovingAverages[i].ClosingDateTime); } ProfitAnalyzer.CloseOpenPosition(); var inputBalance = 500M; ProfitAnalyzer.CalculateProfit(inputBalance); var dataMin = ProfitAnalyzer.Data_GetMin(); var dataMax = ProfitAnalyzer.Data_GetMax(); var dataMean = ProfitAnalyzer.Data_GetMean(); var dataMedian = ProfitAnalyzer.Data_GetMedian(); var dataStd = (decimal)Math.Sqrt((double)ProfitAnalyzer.Data_GetVariance()); var profitMin = ProfitAnalyzer.Profit_GetMin(); var profitMax = ProfitAnalyzer.Profit_GetMax(); var profitMean = ProfitAnalyzer.Profit_GetMean(); var profitMedian = ProfitAnalyzer.Profit_GetMedian(); var profitStd = (decimal)Math.Sqrt((double)ProfitAnalyzer.Profit_GetVariance()); var totalProfit = ProfitAnalyzer.GetTotalProfit(); //Console.WriteLine($"CurrencyPair: {currencyPair}"); //Console.WriteLine($"Data-Min: {dataMin}"); //Console.WriteLine($"Data-Max: {dataMax}"); //Console.WriteLine($"Data-Mean: {dataMean}"); //Console.WriteLine($"Data-Median: {dataMedian}"); //Console.WriteLine($"Data-Std: {dataStd}"); //Console.WriteLine($"Profit-Min: {profitMin}"); //Console.WriteLine($"Profit-Max: {profitMax}"); //Console.WriteLine($"Profit-Mean: {profitMean}"); //Console.WriteLine($"Profit-Median: {profitMedian}"); //Console.WriteLine($"Profit-Std: {profitStd}"); //Console.WriteLine($"TotalProfit: {totalProfit}"); results.Add(new RegressionResults { CurrencyPair = currencyPair, MinutesPerInterval = minutesPerInterval, StartDateTime = startDateTime, EndDateTime = endDateTime, DataMin = dataMin, DataMax = dataMax, DataMean = dataMean, DataMedian = dataMedian, DataStd = dataStd, ProfitMin = profitMin, ProfitMax = profitMax, ProfitMean = profitMean, ProfitMedian = profitMedian, ProfitStd = profitStd, PercentageChange = (totalProfit) / inputBalance, TotalProfit = totalProfit }); startDateTime = startDateTime.AddDays(window); endDateTime = endDateTime.AddDays(window); } foreach (var item in results) { Console.WriteLine(item.ToString()); Console.WriteLine("################################################################"); } if (!_regressionResults.ContainsKey(currencyPair) || _regressionResults[currencyPair].TotalProfit < results[0].TotalProfit) { if (_regressionResults.ContainsKey(currencyPair)) { _regressionResults[currencyPair] = results[0]; } else { _regressionResults.Add(currencyPair, results[0]); } } } } foreach (var item in _regressionResults.OrderByDescending(x => x.Value.TotalProfit)) { Console.WriteLine("XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx"); Console.WriteLine($"key: {item.Key}\nvalue: {item.Value.ToString()}"); Console.WriteLine("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_"); } }