Overall Statistics |
Total Trades 502 Average Win 1.01% Average Loss -1.30% Compounding Annual Return 20.289% Drawdown 70.200% Expectancy 0.023 Net Profit 24.249% Sharpe Ratio 0.836 Probabilistic Sharpe Ratio 33.472% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 0.78 Alpha 1.301 Beta -0.679 Annual Standard Deviation 0.896 Annual Variance 0.803 Information Ratio -0.038 Tracking Error 1.665 Treynor Ratio -1.103 Total Fees $1964.06 |
import numpy as np import pandas as pd from System.Drawing import Color from QuantConnect.Data.Custom import * from collections import deque from QuantConnect.Indicators import * import decimal as d class QuantumOptimizedPrism(QCAlgorithm): def Initialize(self): self.Lookback = 175 #self.SetBrokerageModel(BrokerageName.Alpaca, AccountType.Cash) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.SetCash(100000) #self.symbolList = ["PG", "JNJ", "UNH", "MCK", "CI", "ABC", "NEE", "DUK", "T", "VZ", "VOD"] self.symbolList = ["SPXL"] #Initialize price change checks and holdings weight self.rollingWindow = {} self.weights = {} self.flashcheck = {} #Initialize Exponential Moving Averages self.EMAreq = None self.EMAshort = None self.EMAlong = None #Input date information for backtesting self.SetStartDate(2019, 6, 27) self.SetEndDate(2020, 8, 29) self.SetBenchmark("SPXL") self.SetWarmUp(self.Lookback) stockPlot = Chart("Trade Plot") stockPlot.AddSeries(Series('Price', SeriesType.Line, '$', Color.Blue)) #stockPlot.AddSeries(Series('orderBuy', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Triangle)) #stockPlot.AddSeries(Series('orderSell', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.TriangleDown)) stockPlot = Chart("Diamonds") stockPlot.AddSeries(Series('Short>Long', SeriesType.Scatter, '$', Color.Gold, ScatterMarkerSymbol.Diamond)) stockPlot.AddSeries(Series('Long<Short', SeriesType.Scatter, '$', Color.Purple, ScatterMarkerSymbol.Diamond)) stockPlot.AddSeries(Series('Above220EMA', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Diamond)) stockPlot.AddSeries(Series('orderBuy', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Triangle)) stockPlot.AddSeries(Series('orderSell', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.TriangleDown)) self.AddChart(stockPlot) #Initialize symbols for ticker in self.symbolList: #self.AddEquity(name, Resolution.Minute) self.AddEquity(ticker, Resolution.Hour) self.rollingWindow["close_top_{0}".format(ticker)] = deque(maxlen=self.Lookback) self.weights[ticker] = 1 / len(self.symbolList) self.flashcheck[ticker] = 0 self.EMAreq = self.EMA(ticker, 220, Resolution.Hour); self.PlotIndicator('Trade Plot', self.EMAreq); self.EMAshort = self.EMA(ticker, 13, Resolution.Hour); #self.PlotIndicator("My Indicators", self.EMAshort); self.PlotIndicator('Trade Plot', self.EMAshort); self.EMAlong = self.EMA(ticker, 49, Resolution.Hour); self.PlotIndicator('Trade Plot', self.EMAlong); def OnData(self, data): profitTargetPercent = 0.075 stopLossPercent = 0.05 buycrossover = 40 self.Plot("Diamonds", "Short>Long", buycrossover) sellcrossover = 40 self.Plot("Diamonds", "Long<Short", sellcrossover) #emaclear = 40 #self.Plot("Diamonds", "Above220EMA", emaclear) '''Perform preliminary symbol data confirmation''' if not all([data.Bars.ContainsKey(symbol) for symbol in self.symbolList]): return '''Algorithm engine''' for symbol in self.symbolList: self.Plot('Trade Plot', 'Price', data.Bars[symbol].Close) sym_price = data[symbol].Price self.rollingWindow["close_top_{0}".format(symbol)].appendleft(sym_price) '''Check for algo being warmed up, not being in flash crash, and being above 220 EMA''' if not self.IsWarmingUp: if not self.EMAlong.IsReady: return if not self.EMAshort.IsReady: return if not self.EMAreq.IsReady: return if self.EMAreq.Current.Value < sym_price: #self.SetHoldings(symbol, 0) #self.Plot("Trade Plot", "Sell", sym_price) emaclear = 43 self.Plot("Diamonds", "Above220EMA", emaclear) if self.EMAshort.Current.Value > self.EMAlong.Current.Value: '''If there is a bullish EMA Crossover''' self.SetHoldings(symbol, self.weights[symbol]) #self.LimitOrder(symbol, -self.weights[symbol], sym_price * (1 + profitTargetPercent)) #self.StopMarketOrder(symbol, -self.weights[symbol], sym_price * (1 - stopLossPercent)) buycrossover = 50 self.Plot("Diamonds", "Short>Long", buycrossover) elif self.EMAshort.Current.Value < self.EMAlong.Current.Value: '''Liquidate holdings and cancel Open Orders''' #self.Transactions.CancelOpenOrders() self.SetHoldings(symbol, 0) sellcrossover = 45 self.Plot("Diamonds", "Long<Short", sellcrossover) elif self.EMAreq.Current.Value > sym_price: if self.EMAshort.Current.Value < self.EMAlong.Current.Value: '''If there is a bullish EMA Crossover''' self.SetHoldings(symbol, -self.weights[symbol]) #self.LimitOrder(symbol, self.weights[symbol], sym_price * (1 + profitTargetPercent)) #self.StopMarketOrder(symbol, self.weights[symbol], sym_price * (1 - stopLossPercent)) buycrossover = 50 self.Plot("Diamonds", "Short>Long", buycrossover) elif self.EMAshort.Current.Value > self.EMAlong.Current.Value: '''Liquidate holdings and cancel Open Orders''' #self.Transactions.CancelOpenOrders() self.SetHoldings(symbol, 0) sellcrossover = 45 self.Plot("Diamonds", "Long<Short", sellcrossover) #self.Transactions.CancelOpenOrders() #self.SetHoldings(symbol, 0) def OnOrderEvent(self, orderEvent): '''Print ordr summary in console''' order = self.Transactions.GetOrderById(orderEvent.OrderId) self.Debug("{} {}".format(self.Time, orderEvent.ToString())) '''Bad way of plotting buy and sell orders''' if orderEvent.FillQuantity > 0: #self.Plot("Trade Plot", 'orderBuy', orderEvent.FillPrice); self.Plot("Diamonds", 'orderBuy', 48); elif orderEvent.FillQuantity < 0: #self.Plot("Trade Plot", 'orderSell', orderEvent.FillPrice); self.Plot("Diamonds", 'orderSell', 47); #self.Plot("Trade Plot", 'Order', orderEvent.FillPrice); #self.Plot("Diamonds", 'orderBuy', 47); #self.Plot("Diamonds", 'orderSell', 47); def OnEndOfAlgorithm(self): self.Log("{} - TotalPortfolioValue: {}".format(self.Time, self.Portfolio.TotalPortfolioValue)) self.Log("{} - CashBook: {}".format(self.Time, self.Portfolio.CashBook))