private void BtnSave_Click(object sender, EventArgs e) { var so = new StrategyOptions(); so.BacktestStartingBalance = Convert.ToDouble(txtBalance.EditValue); so.MinutesInBetweenOrders = Convert.ToInt32(txtMinsInbetweenOrders.EditValue); so.MaxOpenOrders = Convert.ToInt32(txtMaxOpenOrders.EditValue); so.Fees = Convert.ToDouble(txtFees.EditValue); Globals.ActiveStrategyOptions = so; this.Close(); }
public string Backtest(string source, string market, KlineInterval kline, DateTime start, DateTime end, StrategyOptions actStrat) { //var source = ""; //var market = "BTCTUSDT"; //var kline = Binance.Net.Objects.KlineInterval.FifteenMinutes; //var start = new DateTime(2019, 11, 1); //var end = new DateTime(2019, 12, 30); //var actStrat = new StrategyOptions(); // get all candles CandleHelper.RetrieveCandles(market, kline, start, end); DateTime small = DateTime.MinValue; DateTime big = DateTime.MinValue; List <CandleInfo> allCandles = null; if (!CandleHelper.CandlesAvailable(market, kline, start, end, out small, out big, out allCandles)) { return("no candles available"); } var temp = new Context(allCandles); temp.ActiveStrategyOptions = Globals.ActiveStrategyOptions; if (!CryptoGlobals.RunScript(source, ref temp)) { return("error in script: " + temp.SCRIPT_ERROR); } var c = new Context(allCandles); c.ActiveStrategyOptions = actStrat; var startingBalance = c.ActiveStrategyOptions.BacktestStartingBalance; var originalBalance = startingBalance; var l = new List <CandleInfo>(); dynamic script = CSScript.RoslynEvaluator.LoadCode(source); foreach (var item in allCandles) { l.Add(item); if (l.Count < 20) { continue; } c.RawCandles = l; try { script.OnData(c); }catch (Exception ex) { return("error: " + ex.Message); } } foreach (var item in c.GetOpenOrders()) { c.CloseOrder(item); } var orders = c.GetAllOrders(); var candlesAndOrders = new SortedDictionary <DateTime, List <OrderInfo> >(); foreach (var item in orders) { var buyDate = item.BuyCandle.OpenTime; var sellDate = item.SellCandle.OpenTime; if (!candlesAndOrders.ContainsKey(buyDate)) { candlesAndOrders[buyDate] = new List <OrderInfo>(); } if (!candlesAndOrders.ContainsKey(sellDate)) { candlesAndOrders[sellDate] = new List <OrderInfo>(); } candlesAndOrders[buyDate].Add(item); candlesAndOrders[sellDate].Add(item); } candlesAndOrders.OrderBy(x => x.Key); var originalEquity = originalBalance; double finalEquity = 0f; var equityOrders = new Dictionary <string, OrderInfo>(); List <OrderResultInfo> finalOrders = new List <OrderResultInfo>(); double totalProfits = 0f; var tempCount = 0; var alreadyAddedIds = new List <string>(); foreach (var cao in candlesAndOrders) { var currDate = cao.Key; var orderList = cao.Value; foreach (var item in orderList) { tempCount++; var isSell = false; if (alreadyAddedIds.Contains(item.Id)) { isSell = true; } else { alreadyAddedIds.Add(item.Id); } var ord = item; var id = ord.Id; string type; DateTime time; double orderPrice = 0.0f;; double size = ord.BuyAmountInUSD; double profitLoss = 0f; double balance = 0f; if (isSell == false) // buy { originalBalance -= ord.BuyAmountInUSD; originalBalance = Math.Round(originalBalance, 2); time = ord.BuyCandle.OpenTime; type = "Buy"; orderPrice = Math.Round(ord.BuyPrice, 2); equityOrders[ord.Id] = ord; } else // sell { var tUsd = ord.TotalUSD(); tUsd = Math.Round(tUsd, 2); originalBalance += tUsd; originalBalance = Math.Round(originalBalance, 2); time = ord.SellCandle.OpenTime; type = "Sell"; var tmpPL = Math.Round(tUsd - ord.BuyAmountInUSD, 2); profitLoss = tmpPL; balance = originalBalance; balance = Math.Round(balance, 2); totalProfits += tmpPL; orderPrice = Math.Round(ord.GetSellPrice(), 2); equityOrders.Remove(ord.Id); } size = Math.Round(size, 8); var finalBalance = balance;// (isSell) ? "$ " + balance.ToString() : ""; finalEquity = 0f; CandleInfo tempCandle = (isSell) ? orderList[0].SellCandle : orderList[0].BuyCandle; double ttttemp = 0f; foreach (var eOrd in equityOrders.Values) { finalEquity += tempCandle.MidPrice * ord.CoinAmount; ttttemp += ord.BuyAmountInUSD; } ttttemp = Math.Round(ttttemp, 3); finalEquity = Math.Round(finalEquity, 3); var ori = new OrderResultInfo() { Id = id.ToString(), Time = time, Type = type, OrderPrice = orderPrice, OrderAmountUSD = size, ProfitLoss = profitLoss, FinalBalance = finalBalance, FinalEquity = finalEquity }; finalOrders.Add(ori); } } var finalPL = Math.Round(originalBalance - startingBalance, 2); finalOrders.Add(new OrderResultInfo() { Id = "", Time = DateTime.MinValue, Type = "blank", OrderPrice = 0f, OrderAmountUSD = 0f, ProfitLoss = 0f, FinalBalance = 0f }); finalOrders.Add(new OrderResultInfo() { Id = "", Time = DateTime.MinValue, Type = "blank2", OrderPrice = 0f, OrderAmountUSD = 0f, ProfitLoss = finalPL, FinalBalance = originalBalance }); var final = JsonConvert.SerializeObject(finalOrders); return(final); }
private async Task RunAsync(Options options) { if (options.ShowAllDifferences) { options.ShowDifferences = true; } // Validate strategies (before we do any other processing IEnumerable <Type>?runSpecificStrategies = null; if (options.SpecificStrategies != null) { IEnumerable <string>?requestedStrategies = options.SpecificStrategies.Split(',').Select(s => s.Trim().ToLowerInvariant()).Distinct(); runSpecificStrategies = typeof(BaseStrategy).Assembly.GetTypes() .Where(t => t.IsSubclassOf(typeof(BaseStrategy))) .Where(t => requestedStrategies.Contains(t.Name.ToLowerInvariant())); Logger.Debug("Specific strategies requested: {0}", string.Join(", ", runSpecificStrategies.Select(t => t.Name))); if (requestedStrategies.Count() != runSpecificStrategies.Count()) { Logger.Debug("Invalid strategies."); Console.WriteLine("Invalid strategy, available options are:"); IEnumerable <Type>?allStrategies = typeof(BaseStrategy).Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(BaseStrategy))); foreach (Type?s in allStrategies) { Console.WriteLine($" * {s.Name}"); } Console.WriteLine("Example: oss-reproducible --specific-strategies AutoBuildProducesSamePackage,PackageMatchesSourceStrategy pkg:npm/[email protected]"); return; } } // Expand targets List <string>?targets = new List <string>(); foreach (string?target in options.Targets ?? Array.Empty <string>()) { PackageURL? purl = new PackageURL(target); PackageDownloader?downloader = new PackageDownloader(purl, ProjectManagerFactory, "temp"); foreach (PackageURL?version in downloader.PackageVersions) { targets.Add(version.ToString()); } } List <ReproducibleToolResult>?finalResults = new List <ReproducibleToolResult>(); foreach (string?target in targets) { try { Console.WriteLine($"Analyzing {target}..."); Logger.Debug("Processing: {0}", target); PackageURL?purl = new PackageURL(target); if (purl.Version == null) { Logger.Error("Package is missing a version, which is required for this tool."); continue; } string?tempDirectoryName = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString().Substring(0, 8)); FileSystemHelper.RetryDeleteDirectory(tempDirectoryName); // Download the package Console.WriteLine("Downloading package..."); PackageDownloader?packageDownloader = new PackageDownloader(purl, ProjectManagerFactory, Path.Join(tempDirectoryName, "package")); List <string>? downloadResults = await packageDownloader.DownloadPackageLocalCopy(purl, false, true); if (!downloadResults.Any()) { Logger.Debug("Unable to download package."); } // Locate the source Console.WriteLine("Locating source..."); FindSourceTool?findSourceTool = new FindSourceTool(ProjectManagerFactory); Dictionary <PackageURL, double>?sourceMap = await findSourceTool.FindSourceAsync(purl); if (sourceMap.Any()) { List <KeyValuePair <PackageURL, double> >?sourceMapList = sourceMap.ToList(); sourceMapList.Sort((a, b) => a.Value.CompareTo(b.Value)); PackageURL?bestSourcePurl = sourceMapList.Last().Key; if (string.IsNullOrEmpty(bestSourcePurl.Version)) { // Tie back the original version to the new PackageURL bestSourcePurl = new PackageURL(bestSourcePurl.Type, bestSourcePurl.Namespace, bestSourcePurl.Name, purl.Version, bestSourcePurl.Qualifiers, bestSourcePurl.Subpath); } Logger.Debug("Identified best source code repository: {0}", bestSourcePurl); // Download the source Console.WriteLine("Downloading source..."); foreach (string?reference in new[] { bestSourcePurl.Version, options.OverrideSourceReference, "master", "main" }) { if (string.IsNullOrWhiteSpace(reference)) { continue; } Logger.Debug("Trying to download package, version/reference [{0}].", reference); PackageURL?purlRef = new PackageURL(bestSourcePurl.Type, bestSourcePurl.Namespace, bestSourcePurl.Name, reference, bestSourcePurl.Qualifiers, bestSourcePurl.Subpath); packageDownloader = new PackageDownloader(purlRef, ProjectManagerFactory, Path.Join(tempDirectoryName, "src")); downloadResults = await packageDownloader.DownloadPackageLocalCopy(purlRef, false, true); if (downloadResults.Any()) { break; } } if (!downloadResults.Any()) { Logger.Debug("Unable to download source."); } } else { Logger.Debug("Unable to locate source repository."); } // Execute all available strategies StrategyOptions?strategyOptions = new StrategyOptions() { PackageDirectory = Path.Join(tempDirectoryName, "package"), SourceDirectory = Path.Join(tempDirectoryName, "src"), PackageUrl = purl, TemporaryDirectory = Path.GetFullPath(tempDirectoryName), DiffTechnique = options.DiffTechnique }; // First, check to see how many strategies apply IEnumerable <Type>?strategies = runSpecificStrategies; if (strategies == null || !strategies.Any()) { strategies = BaseStrategy.GetStrategies(strategyOptions) ?? Array.Empty <Type>(); } int numStrategiesApplies = 0; foreach (Type?strategy in strategies) { ConstructorInfo?ctor = strategy.GetConstructor(new Type[] { typeof(StrategyOptions) }); if (ctor != null) { BaseStrategy?strategyObject = (BaseStrategy)(ctor.Invoke(new object?[] { strategyOptions })); if (strategyObject.StrategyApplies()) { numStrategiesApplies++; } } } Console.Write($"Out of {Yellow(strategies.Count().ToString())} potential strategies, {Yellow(numStrategiesApplies.ToString())} apply. "); if (options.AllStrategies) { Console.WriteLine("Analysis will continue even after a successful strategy is found."); } else { Console.WriteLine("Analysis will stop after the first successful strategy is found."); } List <StrategyResult> strategyResults = new List <StrategyResult>(); Console.WriteLine($"\n{Blue("Results: ")}"); bool hasSuccessfulStrategy = false; foreach (Type?strategy in strategies) { ConstructorInfo?ctor = strategy.GetConstructor(new Type[] { typeof(StrategyOptions) }); if (ctor != null) { // Create a temporary directory, copy the contents from source/package // so that this strategy can modify the contents without affecting other strategies. StrategyOptions?tempStrategyOptions = new StrategyOptions { PackageDirectory = Path.Join(strategyOptions.TemporaryDirectory, strategy.Name, "package"), SourceDirectory = Path.Join(strategyOptions.TemporaryDirectory, strategy.Name, "src"), TemporaryDirectory = Path.Join(strategyOptions.TemporaryDirectory, strategy.Name), PackageUrl = strategyOptions.PackageUrl, IncludeDiffoscope = options.ShowDifferences }; try { OssReproducibleHelpers.DirectoryCopy(strategyOptions.PackageDirectory, tempStrategyOptions.PackageDirectory); OssReproducibleHelpers.DirectoryCopy(strategyOptions.SourceDirectory, tempStrategyOptions.SourceDirectory); } catch (Exception ex) { Logger.Debug(ex, "Error copying directory for strategy. Aborting execution."); } System.IO.Directory.CreateDirectory(tempStrategyOptions.PackageDirectory); System.IO.Directory.CreateDirectory(tempStrategyOptions.SourceDirectory); try { BaseStrategy? strategyObject = (BaseStrategy)(ctor.Invoke(new object?[] { tempStrategyOptions })); StrategyResult?strategyResult = strategyObject.Execute(); if (strategyResult != null) { strategyResults.Add(strategyResult); } if (strategyResult != null) { if (strategyResult.IsSuccess) { Console.WriteLine($" [{Bold().Yellow("PASS")}] {Yellow(strategy.Name)}"); hasSuccessfulStrategy = true; } else { Console.WriteLine($" [{Red("FAIL")}] {Red(strategy.Name)}"); } if (options.ShowDifferences) { foreach (StrategyResultMessage?resultMessage in strategyResult.Messages) { if (resultMessage.Filename != null && resultMessage.CompareFilename != null) { Console.WriteLine($" {Bright.Black("(")}{Blue("P ")}{Bright.Black(")")} {resultMessage.Filename}"); Console.WriteLine($" {Bright.Black("(")}{Blue(" S")}{Bright.Black(")")} {resultMessage.CompareFilename}"); } else if (resultMessage.Filename != null) { Console.WriteLine($" {Bright.Black("(")}{Blue("P+")}{Bright.Black(")")} {resultMessage.Filename}"); } else if (resultMessage.CompareFilename != null) { Console.WriteLine($" {Bright.Black("(")}{Blue("S+")}{Bright.Black(")")} {resultMessage.CompareFilename}"); } IEnumerable <DiffPiece>?differences = resultMessage.Differences ?? Array.Empty <DiffPiece>(); int maxShowDifferences = 20; int numShowDifferences = 0; foreach (DiffPiece?diff in differences) { if (!options.ShowAllDifferences && numShowDifferences > maxShowDifferences) { Console.WriteLine(Background.Blue(Bold().White("NOTE: Additional differences exist but are not shown. Pass --show-all-differences to view them all."))); break; } switch (diff.Type) { case ChangeType.Inserted: Console.WriteLine($"{Bright.Black(diff.Position + ")")}\t{Red("+")} {Blue(diff.Text)}"); ++numShowDifferences; break; case ChangeType.Deleted: Console.WriteLine($"\t{Green("-")} {Green(diff.Text)}"); ++numShowDifferences; break; default: break; } } if (numShowDifferences > 0) { Console.WriteLine(); } } string?diffoscopeFile = Guid.NewGuid().ToString() + ".html"; File.WriteAllText(diffoscopeFile, strategyResult.Diffoscope); Console.WriteLine($" Diffoscope results written to {diffoscopeFile}."); } } else { Console.WriteLine(Green($" [-] {strategy.Name}")); } } catch (Exception ex) { Logger.Warn(ex, "Error processing {0}: {1}", strategy, ex.Message); Logger.Debug(ex.StackTrace); } } if (hasSuccessfulStrategy && !options.AllStrategies) { break; // We don't need to continue } } ReproducibleToolResult?reproducibilityToolResult = new ReproducibleToolResult { PackageUrl = purl.ToString(), Results = strategyResults }; finalResults.Add(reproducibilityToolResult); (double score, string scoreText) = GetReproducibilityScore(reproducibilityToolResult); Console.WriteLine($"\n{Blue("Summary:")}"); string?scoreDisplay = $"{(score * 100.0):0.#}"; if (reproducibilityToolResult.IsReproducible) { Console.WriteLine($" [{Yellow(scoreDisplay + "%")}] {Yellow(scoreText)}"); } else { Console.WriteLine($" [{Red(scoreDisplay + "%")}] {Red(scoreText)}"); } if (options.LeaveIntermediateFiles) { Console.WriteLine(); Console.WriteLine($"Intermediate files are located in [{tempDirectoryName}]."); } else { FileSystemHelper.RetryDeleteDirectory(tempDirectoryName); } } catch (Exception ex) { Logger.Warn(ex, "Error processing {0}: {1}", target, ex.Message); Logger.Debug(ex.StackTrace); } } if (finalResults.Any()) { // Write the output somewhere string?jsonResults = Newtonsoft.Json.JsonConvert.SerializeObject(finalResults, Newtonsoft.Json.Formatting.Indented); if (!string.IsNullOrWhiteSpace(options.OutputFile) && !string.Equals(options.OutputFile, "-", StringComparison.InvariantCultureIgnoreCase)) { try { File.WriteAllText(options.OutputFile, jsonResults); Console.WriteLine($"Detailed results are available in {options.OutputFile}."); } catch (Exception ex) { Logger.Warn(ex, "Unable to write to {0}. Writing to console instead.", options.OutputFile); Console.WriteLine(jsonResults); } } else if (string.Equals(options.OutputFile, "-", StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine(jsonResults); } } else { Logger.Debug("No results were produced."); } }
private async Task RunAsync(CancellationToken token) { while (!token.IsCancellationRequested) { // get live orders if (AllMarkets == null) { RefreshMarkets(); } if (AllUsers == null) { RefreshUsers(); } if (AllContexts == null) { AllContexts = new Dictionary <int, Context>(); } foreach (DataRow row in DBHelper.dtJobs.Rows) { var job = new JobInfo(row); if (job.IsLive) { // grab the latest candles var kline = CryptoGlobals.GetKlineFromString(job.Interval); var c = CryptoGlobals.LastCandleInDB(AllMarkets[job.MarketId].Symbol, kline); var shouldGetCandles = false; var firstDate = DateTime.Today.AddDays(60); if (c == null) { // ouch never got any candles :( shouldGetCandles = true; } else { // we got, that's our start date if (c.OpenTime < CryptoGlobals.MinusKlineInterval(DateTime.UtcNow, kline)) { shouldGetCandles = true; firstDate = c.OpenTime; } } if (shouldGetCandles) { CandleHelper.RetrieveCandles(AllMarkets[job.MarketId].Symbol, kline, firstDate, DateTime.Now.AddDays(1)); // TAKE IT ALLLLL } if (!AllUsers.ContainsKey(job.UserId)) { AllUsers = null; RefreshUsers(); if (!AllUsers.ContainsKey(job.UserId)) { // invalid user continue; } } var user = AllUsers[job.UserId]; // get candles var crows = DBHelper.GetDataTable("SELECT * FROM Candles WHERE Symbol='" + AllMarkets[job.MarketId].Symbol + "' AND Interval='" + job.Interval + "'"); // haha crows List <CandleInfo> CurrentCandles = new List <CandleInfo>(); foreach (DataRow crow in crows.Rows) { var tempC = new CandleInfo(crow); CurrentCandles.Add(tempC); } StrategyOptions myStrat = null; var strat = DBHelper.GetDataTable("SELECT * from Strategies where Id=" + job.ScriptId); if (strat.Rows.Count > 0) { myStrat = (new StrategyInfo(strat.Rows[0])).Options; } else { continue; // cancel!?!? } Context cxt = null; if (!AllContexts.ContainsKey(job.Id)) { cxt = new Context(CurrentCandles); cxt.IsLive = true; cxt.User = user; cxt.ActiveStrategyOptions = new StrategyOptions() { BacktestStartingBalance = 1000000, Fees = 0, MaxOpenOrders = myStrat.MaxOpenOrders, MinutesInBetweenOrders = myStrat.MinutesInBetweenOrders }; } else { cxt = AllContexts[job.Id]; cxt.RawCandles = CurrentCandles; } var l = new List <CandleInfo>(); if (CurrentCandles.Count == 0) { continue; } cxt.RawCandles = CurrentCandles; if (cxt.IsLive && !cxt.IsPaper) { //var orders = CryptoGlobals.UserBinances[user.Username].GetOpenOrders(); // //foreach (var item in orders.Data) //{ // // if (item.Symbol != AllMarkets[job.MarketId].Symbol) continue; // // var t = new OrderInfo(cxt, (float)(item.Price * item.ExecutedQuantity)); // t.CoinAmount = (float)item.ExecutedQuantity; // t.IsOpen = true; // t.Id = item.ClientOrderId.ToString(); //} } else { } if (!Globals.RunScript(cxt.StrategyScript, ref cxt)) { continue; } // we now can run the script } } System.Diagnostics.Debug.WriteLine(DateTime.Now); await Task.Delay(1000); } }