| 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))