예제 #1
0
        public async Task DeleteBacktestCandles(BacktestOptions backtestOptions)
        {
            LiteCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <CandleAdapter>("Candle_" + backtestOptions.CandlePeriod);

            candleCollection.EnsureIndex("Timestamp");
            candleCollection.Delete(Query.Between("Timestamp", backtestOptions.StartDate, backtestOptions.EndDate, true, true));
        }
예제 #2
0
        public async Task <ActionResult> GetSignals(string exchange, string coinsToBuy, string strategy, string candleSize = "5")
        {
            var strategyName = WebUtility.HtmlDecode(strategy);

            List <string> coins     = new List <string>();
            Char          delimiter = ',';

            String[] coinsToBuyArray = coinsToBuy.Split(delimiter);
            foreach (var coin in coinsToBuyArray)
            {
                coins.Add(coin.ToUpper());
            }

            var backtestOptions = new BacktestOptions
            {
                DataFolder   = Global.DataPath,
                Exchange     = (Exchange)Enum.Parse(typeof(Exchange), exchange, true),
                Coins        = coins,
                Coin         = coinsToBuy,
                CandlePeriod = Int32.Parse(candleSize)
            };

            var candleProvider = new DatabaseCandleProvider();
            var items          = await candleProvider.GetSignals(backtestOptions, Global.DataStoreBacktest, strategyName);

            return(new JsonResult(items));
        }
예제 #3
0
        public static async void BackTestConsole(ITradingStrategy strategy, BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            List <BackTestResult> results = await BackTest(strategy, backtestOptions, dataStore);

            if (results.Count > 0)
            {
                Console.WriteLine(results
                                  .OrderByDescending(x => x.SuccessRate)
                                  .ToList()
                                  .ToStringTable(new[] { "Market", "# Trades", "# Profitable", "Success Rate", "BTC Profit", "Profit %", "Avg. Duration", "Period" },
                                                 (x) => x.Market,
                                                 (x) => x.AmountOfTrades,
                                                 (x) => x.AmountOfProfitableTrades,
                                                 (x) => $"{x.SuccessRate:0.00}%",
                                                 (x) => $"{x.TotalProfit:0.00000000}",
                                                 (x) => $"{x.TotalProfitPercentage:0.00}%",
                                                 (x) => $"{(x.AverageDuration):0.00} hours",
                                                 (x) => $"{x.DataPeriod} days"));
            }
            else
            {
                ConsoleUtility.WriteColoredLine("\tNo backtests results found...", ConsoleColor.Red);
            }
            ConsoleUtility.WriteSeparator();
        }
예제 #4
0
        public static async Task <JArray> BackTestJson(ITradingStrategy strategy, BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            List <BackTestResult> results = await BackTest(strategy, backtestOptions, dataStore);

            JArray jArrayResult = new JArray();

            if (results.Count > 0)
            {
                foreach (var result in results)
                {
                    JObject currentResult = new JObject();
                    currentResult["Market"]                   = result.Market;
                    currentResult["Strategy"]                 = strategy.Name;
                    currentResult["AmountOfTrades"]           = result.AmountOfTrades;
                    currentResult["AmountOfProfitableTrades"] = result.AmountOfProfitableTrades;
                    currentResult["SuccessRate"]              = result.SuccessRate;
                    currentResult["TotalProfit"]              = result.TotalProfit;
                    currentResult["TotalProfitPercentage"]    = result.TotalProfitPercentage;
                    currentResult["AverageDuration"]          = result.AverageDuration;
                    currentResult["DataPeriod"]               = result.DataPeriod;
                    jArrayResult.Add(currentResult);
                }
            }
            return(jArrayResult);
        }
예제 #5
0
        public static async void BackTestAllConsole(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            List <BackTestStrategyResult> results = await BackTestAll(backtestOptions, dataStore);

            Console.WriteLine();
            Console.WriteLine($"\t=============== BACKTESTING REPORT ===============");
            Console.WriteLine();
            ConsoleUtility.WriteColoredLine($"\tNote: Profit is based on trading with 0.1 BTC each trade.", ConsoleColor.Cyan);
            Console.WriteLine();

            // Prints the results for each coin for this strategy.
            if (results.Count > 0)
            {
                Console.WriteLine(results
                                  .OrderByDescending(x => x.SuccessRate)
                                  .ToList()
                                  .ToStringTable(new[] { "Strategy", "# Trades", "# Profitable", "Success Rate", "BTC Profit", "Profit %", "Avg. Duration", "Max. Period" },
                                                 (x) => x.Strategy,
                                                 (x) => x.AmountOfTrades,
                                                 (x) => x.AmountOfProfitableTrades,
                                                 (x) => $"{x.SuccessRate:0.00}%",
                                                 (x) => $"{x.TotalProfit:0.00000000}",
                                                 (x) => $"{x.TotalProfitPercentage:0.00}%",
                                                 (x) => $"{(x.AverageDuration):0.00} hours",
                                                 (x) => $"{x.DataPeriod} days"));
            }
            else
            {
                ConsoleUtility.WriteColoredLine("\tNo backtests results found...", ConsoleColor.Red);
            }
            ConsoleUtility.WriteSeparator();
        }
 public async Task DeleteBacktestDatabase(BacktestOptions backtestOptions)
 {
     if (File.Exists(GetDatabase(backtestOptions)))
     {
         File.Delete(GetDatabase(backtestOptions));
     }
 }
예제 #7
0
        public static async Task <JArray> GetCacheAge(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            JArray jArrayResult = new JArray();

            foreach (var globalSymbol in backtestOptions.Coins)
            {
                backtestOptions.Coin = globalSymbol;

                Candle currentHistoricalDataFirst = await dataStore.GetBacktestFirstCandle(backtestOptions);

                Candle currentHistoricalDataLast = await dataStore.GetBacktestLastCandle(backtestOptions);

                if (currentHistoricalDataFirst != null && currentHistoricalDataLast != null)
                {
                    JObject currentResult = new JObject();
                    currentResult["Exchange"]        = backtestOptions.Exchange.ToString();
                    currentResult["Coin"]            = globalSymbol;
                    currentResult["CandlePeriod"]    = backtestOptions.CandlePeriod;
                    currentResult["FirstCandleDate"] = currentHistoricalDataFirst.Timestamp.ToUniversalTime();
                    currentResult["LastCandleDate"]  = currentHistoricalDataLast.Timestamp.ToUniversalTime();
                    jArrayResult.Add(currentResult);
                }
            }
            return(jArrayResult);
        }
예제 #8
0
        public ActionResult BacktesterResults(string exchange, string coinsToBuy, string baseCurrency, string candleSize = "5", string strategy = "all")
        {
            JObject strategies = new JObject();

            List <string> coins = new List <string>();

            if (String.IsNullOrEmpty(coinsToBuy))
            {
                IExchangeAPI api           = ExchangeAPI.GetExchangeAPI(exchange.ToLower());
                var          exchangeCoins = api.GetSymbolsMetadataAsync().Result.Where(m => m.BaseCurrency == baseCurrency);
                foreach (var coin in exchangeCoins)
                {
                    coins.Add(api.ExchangeSymbolToGlobalSymbol(coin.MarketName));
                }
            }
            else
            {
                Char     delimiter       = ',';
                String[] coinsToBuyArray = coinsToBuy.Split(delimiter);
                foreach (var coin in coinsToBuyArray)
                {
                    coins.Add(coin.ToUpper());
                }
            }

            var backtestOptions = new BacktestOptions
            {
                DataFolder   = Global.DataPath,
                Exchange     = (Exchange)Enum.Parse(typeof(Exchange), exchange, true),
                Coins        = coins,
                CandlePeriod = Int32.Parse(candleSize)
            };

            var cts             = new CancellationTokenSource();
            var parallelOptions = new ParallelOptions
            {
                CancellationToken      = cts.Token,
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            Parallel.ForEach(BacktestFunctions.GetTradingStrategies(), parallelOptions, async tradingStrategy =>
            {
                if (strategy != "all")
                {
                    var base64EncodedBytes = Convert.FromBase64String(strategy);
                    if (tradingStrategy.Name != Encoding.UTF8.GetString(base64EncodedBytes))
                    {
                        return;
                    }
                }
                var result = await BacktestFunctions.BackTestJson(tradingStrategy, backtestOptions, Global.DataStoreBacktest);
                foreach (var item in result)
                {
                    await Runtime.GlobalHubBacktest.Clients.All.SendAsync("Send", JsonConvert.SerializeObject(item));
                }
            });

            return(new JsonResult(strategies));
        }
        public async Task SaveBacktestCandlesBulk(List <Candle> candles, BacktestOptions backtestOptions)
        {
            var items = Mapping.Mapper.Map <List <CandleAdapter> >(candles);
            LiteCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <CandleAdapter>("Candle_" + backtestOptions.CandlePeriod);

            candleCollection.EnsureIndex("Timestamp");
            candleCollection.InsertBulk(items);
        }
        public async Task <Candle> GetBacktestLastCandle(BacktestOptions backtestOptions)
        {
            IMongoCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(MongoDbBaseName + backtestOptions.CandlePeriod).GetTable <CandleAdapter>(backtestOptions.Exchange + "_" + backtestOptions.Coin);
            CandleAdapter lastCandle = await candleCollection.Find(_ => true).SortByDescending(e => e.Timestamp).Limit(1).FirstOrDefaultAsync();

            var items = Mapping.Mapper.Map <Candle>(lastCandle);

            return(items);
        }
        public async Task SaveTradeSignals(BacktestOptions backtestOptions, IDataStoreBacktest dataStore, List <TradeSignal> signals)
        {
            if (backtestOptions.EndDate == DateTime.MinValue)
            {
                backtestOptions.EndDate = DateTime.UtcNow;
            }

            await dataStore.SaveBacktestTradeSignalsBulk(signals, backtestOptions);
        }
예제 #12
0
        public static async Task <bool> CheckForCandleData(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            List <string> allDatabases = await dataStore.GetBacktestAllDatabases(backtestOptions);

            if (allDatabases.Count == 0)
            {
                return(false);
            }
            return(true);
        }
        public async Task <Candle> GetBacktestFirstCandle(BacktestOptions backtestOptions)
        {
            LiteCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <CandleAdapter>("Candle_" + backtestOptions.CandlePeriod);

            candleCollection.EnsureIndex("Timestamp");
            CandleAdapter lastCandle = candleCollection.Find(Query.All("Timestamp"), limit: 1).FirstOrDefault();
            var           items      = Mapping.Mapper.Map <Candle>(lastCandle);

            return(items);
        }
        public async Task <List <TradeSignal> > GetBacktestSignalsByStrategy(BacktestOptions backtestOptions, string strategy)
        {
            IMongoCollection <TradeSignalAdapter> itemCollection = DataStoreBacktest.GetInstance("Signals_" + MongoDbBaseName + backtestOptions.CandlePeriod).GetTable <TradeSignalAdapter>(backtestOptions.Exchange + "_" + backtestOptions.Coin);
            var items = await itemCollection.Find(entry => entry.StrategyName == strategy).ToListAsync();

#warning TODO: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit=> temporarly order by LINQ

            var result = Mapping.Mapper.Map <List <TradeSignal> >(items).OrderBy(c => c.Timestamp).ToList();
            return(result);
        }
        public async Task <List <TradeSignal> > GetBacktestSignalsByStrategy(BacktestOptions backtestOptions, string strategy)
        {
            var itemCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <TradeSignalAdapter>("Signals_" + backtestOptions.CandlePeriod);

            itemCollection.EnsureIndex("StrategyName");
            var items  = itemCollection.Find(Query.Where("StrategyName", s => s.AsString == strategy), Query.Descending).ToList();
            var result = Mapping.Mapper.Map <List <TradeSignal> >(items);

            return(result);
        }
        public async Task <List <Candle> > GetCandles(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            if (backtestOptions.EndDate == DateTime.MinValue)
            {
                backtestOptions.EndDate = DateTime.UtcNow;
            }

            List <Candle> candles = await dataStore.GetBacktestCandlesBetweenTime(backtestOptions);

            return(candles);
        }
        public async Task <List <string> > GetBacktestAllDatabases(BacktestOptions backtestOptions)
        {
            List <string> allDatabases = new List <string>();
            var           dbList       = await _client.GetDatabase(MongoDbOptions.MongoDatabaseName).ListCollectionsAsync();

            foreach (var item in await dbList.ToListAsync())
            {
                allDatabases.Add(item.ToString());
            }
            return(allDatabases);
        }
        public async Task <List <TradeSignal> > GetSignals(BacktestOptions backtestOptions, IDataStoreBacktest dataStore, string strategy)
        {
            if (backtestOptions.EndDate == DateTime.MinValue)
            {
                backtestOptions.EndDate = DateTime.UtcNow;
            }

            List <TradeSignal> items = await dataStore.GetBacktestSignalsByStrategy(backtestOptions, strategy);

            return(items);
        }
예제 #19
0
        public static async Task <JArray> BackTestJson(ITradingStrategy strategy, BacktestOptions backtestOptions, IDataStoreBacktest dataStore, string baseCurrency, bool saveSignals, decimal startingWallet, decimal tradeAmount)
        {
            var results = await BackTest(strategy, backtestOptions, dataStore, baseCurrency, saveSignals, startingWallet, tradeAmount);

            var jArrayResult = new JArray();

            if (results.Count > 0)
            {
                var resultsSummary = new BackTestStrategyResult();
                resultsSummary.Results          = results;
                resultsSummary.Strategy         = strategy.Name;
                resultsSummary.ConcurrentTrades = results.First().ConcurrentTrades;
                resultsSummary.Wallet           = results.First().Wallet;
                resultsSummary.LowWallet        = results.First().LowWallet;

                var endWallet            = Math.Round(resultsSummary.Wallet, 3);
                var walletRealPercentage = Math.Round(((resultsSummary.Wallet - startingWallet) / startingWallet) * 100, 3);
                var lowWallet            = Math.Round(resultsSummary.LowWallet, 3);

                var currentResult1 = new JObject();
                currentResult1["Strategy"]                 = resultsSummary.Strategy;
                currentResult1["ConcurrentTrades"]         = resultsSummary.ConcurrentTrades;
                currentResult1["Wallet"]                   = endWallet + " " + baseCurrency + " (" + walletRealPercentage + "%)";
                currentResult1["LowWallet"]                = lowWallet;
                currentResult1["AmountOfTrades"]           = resultsSummary.AmountOfTrades;
                currentResult1["AmountOfProfitableTrades"] = resultsSummary.AmountOfProfitableTrades;
                currentResult1["SuccessRate"]              = resultsSummary.SuccessRate;
                currentResult1["TotalProfit"]              = resultsSummary.TotalProfit;
                currentResult1["TotalProfitPercentage"]    = resultsSummary.TotalProfitPercentage;
                currentResult1["AverageDuration"]          = resultsSummary.AverageDuration;
                currentResult1["DataPeriod"]               = resultsSummary.DataPeriod;
                currentResult1["BaseCurrency"]             = baseCurrency;
                jArrayResult.Add(currentResult1);

                foreach (var result in results)
                {
                    var currentResult = new JObject();
                    currentResult["Market"]                   = result.Market;
                    currentResult["Strategy"]                 = strategy.Name;
                    currentResult["AmountOfTrades"]           = result.AmountOfTrades;
                    currentResult["AmountOfProfitableTrades"] = result.AmountOfProfitableTrades;
                    currentResult["SuccessRate"]              = result.SuccessRate;
                    currentResult["TotalProfit"]              = result.TotalProfit;
                    currentResult["TotalProfitPercentage"]    = result.TotalProfitPercentage;
                    currentResult["AverageDuration"]          = result.AverageDuration;
                    currentResult["DataPeriod"]               = result.DataPeriod;

                    jArrayResult.Add(currentResult);
                }
            }

            return(jArrayResult);
        }
        public async Task <List <Candle> > GetBacktestCandlesBetweenTime(BacktestOptions backtestOptions)
        {
            var results = new List <Candle>();

            IMongoCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(MongoDbBaseName + backtestOptions.CandlePeriod).GetTable <CandleAdapter>(backtestOptions.Exchange + "_" + backtestOptions.Coin);
            List <CandleAdapter>             candles          = await candleCollection.Find(entry => entry.Timestamp >= backtestOptions.StartDate && entry.Timestamp <= backtestOptions.EndDate).ToListAsync();

#warning TODO: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit=> temporarly order by LINQ

            results = Mapping.Mapper.Map <List <Candle> >(candles).OrderBy(c => c.Timestamp).ToList();

            return(results);
        }
        public async Task SaveBacktestTradeSignalsBulk(List <TradeSignal> signals, BacktestOptions backtestOptions)
        {
            var items = Mapping.Mapper.Map <List <TradeSignalAdapter> >(signals);

            IMongoCollection <TradeSignalAdapter> itemCollection = DataStoreBacktest.GetInstance("Signals_" + MongoDbBaseName + backtestOptions.CandlePeriod).GetTable <TradeSignalAdapter>(backtestOptions.Exchange + "_" + backtestOptions.Coin);

            foreach (var item in items)
            {
                await itemCollection.DeleteManyAsync(i => i.StrategyName == item.StrategyName);
            }

            await itemCollection.InsertManyAsync(items);
        }
        public async Task SaveBacktestCandle(Candle candle, BacktestOptions backtestOptions)
        {
            var item = Mapping.Mapper.Map <CandleAdapter>(candle);
            LiteCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <CandleAdapter>("Candle_" + backtestOptions.CandlePeriod);

            candleCollection.EnsureIndex("Timestamp");
            var newCandle = candleCollection.FindOne(x => x.Timestamp == item.Timestamp);

            if (newCandle == null)
            {
                candleCollection.Insert(item);
            }
        }
        public static string GetDatabase(BacktestOptions backtestOptions)
        {
            if (!Directory.Exists(backtestOptions.DataFolder))
            {
                Directory.CreateDirectory(backtestOptions.DataFolder);
            }

            if (backtestOptions.Coin == null)
            {
                return(backtestOptions.DataFolder.Replace("\\", "/"));
            }
            return(backtestOptions.DataFolder.Replace("\\", "/") + "/" + backtestOptions.Exchange + "_" + backtestOptions.Coin + ".db");
        }
예제 #24
0
        public async Task <ActionResult> FillCandlesGaps(string exchange, string coinsToBuy, string baseCurrency, DateTime?from = null, DateTime?to = null, string candleSize = "5")
        {
            var coins = new List <string>();

            if (String.IsNullOrEmpty(coinsToBuy))
            {
                IExchangeAPI api           = ExchangeAPI.GetExchangeAPI(exchange);
                var          exchangeCoins = api.GetSymbolsMetadataAsync().Result.Where(m => m.BaseCurrency == baseCurrency);
                foreach (var coin in exchangeCoins)
                {
                    coins.Add(api.ExchangeSymbolToGlobalSymbol(coin.MarketName));
                }
            }
            else
            {
                Char     delimiter       = ',';
                String[] coinsToBuyArray = coinsToBuy.Split(delimiter);
                foreach (var coin in coinsToBuyArray)
                {
                    coins.Add(coin.ToUpper());
                }
            }

            var backtestOptions = new BacktestOptions
            {
                DataFolder   = Global.DataPath,
                Exchange     = (Exchange)Enum.Parse(typeof(Exchange), exchange, true),
                Coins        = coins,
                CandlePeriod = Int32.Parse(candleSize),
                EndDate      = DateTime.Now
            };

            if (from.HasValue)
            {
                backtestOptions.StartDate = from.Value;
            }

            if (to.HasValue)
            {
                backtestOptions.EndDate = to.Value;
                backtestOptions.EndDate = backtestOptions.EndDate.AddDays(1).AddMinutes(-1);
            }

            await DataRefresher.FillCandlesGaps(x => Global.Logger.Information(x), backtestOptions, Global.DataStoreBacktest);

            var result = new JObject {
                ["result"] = "success"
            };

            return(new JsonResult(result));
        }
        public async Task SaveBacktestCandle(Candle candle, BacktestOptions backtestOptions)
        {
            var item = Mapping.Mapper.Map <CandleAdapter>(candle);
            IMongoCollection <CandleAdapter> candleCollection        = DataStoreBacktest.GetInstance(MongoDbBaseName + backtestOptions.CandlePeriod).GetTable <CandleAdapter>(backtestOptions.Exchange + "_" + backtestOptions.Coin);
            FindOptions <CandleAdapter>      marketCandleFindOptions = new FindOptions <CandleAdapter> {
                Limit = 1
            };
            IAsyncCursor <CandleAdapter> checkData = await candleCollection.FindAsync(x => x.Timestamp == item.Timestamp, marketCandleFindOptions);

            if (await checkData.FirstOrDefaultAsync() == null)
            {
                await candleCollection.InsertOneAsync(item);
            }
        }
예제 #26
0
        public async Task <string> Refresh(string exchange, string coinsToBuy, string candleSize = "5")
        {
            var backtestOptions = new BacktestOptions
            {
                DataFolder   = Global.DataPath,
                Exchange     = (Exchange)Enum.Parse(typeof(Exchange), exchange, true),
                Coins        = new List <string>(new[] { coinsToBuy }),
                CandlePeriod = Int32.Parse(candleSize)
            };

            await DataRefresher.RefreshCandleData(x => Global.Logger.Information(x), backtestOptions, Global.DataStoreBacktest);

            return("Refresh Done");
        }
 public async Task <List <Candle> > GetBacktestCandlesBetweenTime(BacktestOptions backtestOptions)
 {
     try
     {
         LiteCollection <CandleAdapter> candleCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <CandleAdapter>("Candle_" + backtestOptions.CandlePeriod);
         candleCollection.EnsureIndex("Timestamp");
         List <CandleAdapter> candles = candleCollection.Find(Query.Between("Timestamp", backtestOptions.StartDate, backtestOptions.EndDate), Query.Ascending).ToList();
         var items = Mapping.Mapper.Map <List <Candle> >(candles);
         return(items);
     }
     catch (Exception ex)
     {
         Global.Logger.Error(ex.ToString());
         throw;
     }
 }
        public async Task SaveBacktestTradeSignalsBulk(List <TradeSignal> signals, BacktestOptions backtestOptions)
        {
            var items = Mapping.Mapper.Map <List <TradeSignalAdapter> >(signals);

            LiteCollection <TradeSignalAdapter> itemCollection = DataStoreBacktest.GetInstance(GetDatabase(backtestOptions)).GetTable <TradeSignalAdapter>("Signals_" + backtestOptions.CandlePeriod);

            foreach (var item in items)
            {
                itemCollection.Delete(i => i.StrategyName == item.StrategyName);
            }

            // TradeSignalAdapter lastCandle = itemCollection.Find(Query.All("Timestamp", Query.Descending), limit: 1).FirstOrDefault();

            itemCollection.EnsureIndex("Timestamp");
            itemCollection.InsertBulk(items);
        }
예제 #29
0
        public static async Task <List <BackTestStrategyResult> > BackTestAll(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            var runner  = new BackTestRunner();
            var results = new List <BackTestStrategyResult>();

            foreach (var item in GetTradingStrategies())
            {
                var stratResult = new BackTestStrategyResult()
                {
                    Strategy = item.Name
                };
                stratResult.Results.AddRange(await runner.RunSingleStrategy(item, backtestOptions, dataStore));
                results.Add(stratResult);
            }

            return(results);
        }
예제 #30
0
        public static async Task <JArray> BackTestAllJson(BacktestOptions backtestOptions, IDataStoreBacktest dataStore)
        {
            List <BackTestStrategyResult> results = await BackTestAll(backtestOptions, dataStore);

            JArray jArrayResult = new JArray();

            foreach (var result in results)
            {
                JObject currentResult = new JObject();
                currentResult["Strategy"]                 = result.Strategy;
                currentResult["AmountOfTrades"]           = result.AmountOfTrades;
                currentResult["AmountOfProfitableTrades"] = result.AmountOfProfitableTrades;
                currentResult["SuccessRate"]              = result.SuccessRate;
                currentResult["TotalProfit"]              = result.TotalProfit;
                currentResult["TotalProfitPercentage"]    = result.TotalProfitPercentage;
                currentResult["AverageDuration"]          = result.AverageDuration;
                currentResult["DataPeriod"]               = result.DataPeriod;
                jArrayResult.Add(currentResult);
            }
            return(jArrayResult);
        }