Overall Statistics |
Total Trades 152 Average Win 11.48% Average Loss -2.08% Compounding Annual Return 398.958% Drawdown 29.900% Expectancy 2.510 Net Profit 2442.683% Sharpe Ratio 4.469 Probabilistic Sharpe Ratio 99.118% Loss Rate 46% Win Rate 54% Profit-Loss Ratio 5.51 Alpha 2.156 Beta 0.282 Annual Standard Deviation 0.567 Annual Variance 0.322 Information Ratio 1.689 Tracking Error 0.703 Treynor Ratio 8.999 Total Fees $36196.04 Estimated Strategy Capacity $15000000.00 Lowest Capacity Asset BNBUSDT 18N |
from datetime import timedelta from AlgorithmImports import * import math # from Shared.IntradayMomentumIndex importIn from SmartRollingWindow import * def truncate(number, decimals=0): """ Returns a value truncated to a specific number of decimal places. """ if not isinstance(decimals, int): raise TypeError("decimal places must be an integer.") elif decimals < 0: raise ValueError("decimal places has to be 0 or more.") elif decimals == 0: return math.trunc(number) factor = 10.0 ** decimals return math.trunc(number * factor) / factor class Asset(): def __init__(self, algorithm, symbol): self.symbol = symbol self.algorithm = algorithm def InitIndicators(self, slowPeriod, fastPeriod, resolution): self.fast = self.algorithm.EMA(self.symbol, fastPeriod, resolution) self.slow = self.algorithm.EMA(self.symbol, slowPeriod, resolution) self.slowWindow = SmartRollingWindow('float', 2) self.fastWindow = SmartRollingWindow('float', 2) self.priceWindow = SmartRollingWindow('float', 2) def UpdateIndicators(self): self.slowWindow.Add(self.slow.Current.Value) self.fastWindow.Add(self.fast.Current.Value) self.priceWindow.Add(self.algorithm.Securities[self.symbol].Price) def PrefixWithSymbol(self, str): return "{}: {}".format(self.symbol.Value, str) def Plot(self, chartName): self.algorithm.Plot(chartName, self.PrefixWithSymbol("Price"), self.algorithm.Securities[self.symbol].Price) self.algorithm.Plot(chartName, self.PrefixWithSymbol("Slow"), self.slow.Current.Value) self.algorithm.Plot(chartName, self.PrefixWithSymbol("Fast"), self.fast.Current.Value) class FocusedYellowGreenJellyfish(QCAlgorithm): def Initialize(self): self.InitAlgoParams() self.InitBacktestParams() self.InitAssets() self.InitIndicators() def InitAlgoParams(self): self.benchmarkTicker = 'BTCUSDT'; self.tickers = ["SOLUSDT", "ETHUSDT", "BNBUSDT"] self.assets = {} self.ticker = "SOLUSDT" self.resolution = Resolution.Daily self.slowPeriod = int(self.GetParameter('slowPeriod')) self.fastPeriod = int(self.GetParameter('fastPeriod')) def InitBacktestParams(self): self.SetAccountCurrency("USDT") self.SetCash(100000) self.SetStartDate(2020, 1, 1) def InitAssets(self): self.SetBrokerageModel(BrokerageName.Binance, AccountType.Cash) self.benchmarkSymbol = self.AddCrypto(self.benchmarkTicker, self.resolution).Symbol for ticker in self.tickers: symbol = self.AddCrypto(ticker, self.resolution).Symbol self.assets[ticker] = Asset(self, symbol) self.SetBenchmark(self.benchmarkTicker) def InitIndicators(self): self.SetWarmUp(self.slowPeriod * 2, self.resolution) for asset in self.assets.values(): asset.InitIndicators(self.slowPeriod, self.fastPeriod, self.resolution) self.Consolidate(self.benchmarkSymbol, self.resolution, self.OnConsolidatedBarClose) def UpdateRollingWindows(self): for asset in self.assets.values(): asset.UpdateIndicators() def ShouldExit(self, asset): return asset.priceWindow.isBelow(asset.slowWindow) or asset.slowWindow.isAbove(asset.fastWindow) def ShouldEnter(self, asset): return asset.fastWindow.isAbove(asset.slowWindow) and asset.priceWindow.isAbove(asset.fastWindow) def OnEndOfDay(self): self.PlotCharts() self.UpdateRollingWindows() def OnConsolidatedBarClose(self, bar): for asset in self.assets.values(): if not asset.slowWindow.IsReady(): return if self.Portfolio[asset.symbol].Invested and self.ShouldExit(asset): self.Liquidate(asset.symbol) elif not self.Portfolio[asset.symbol].Invested and self.ShouldEnter(asset): percent = truncate(1 / len(self.assets.values()), 1) self.SetHoldings(asset.symbol, percent); def PlotCharts(self): chartName = "Charts" self.Plot(chartName, "Benchmark", self.Securities[self.benchmarkSymbol].Price) for asset in self.assets.values(): asset.Plot(chartName)