| Overall Statistics |
|
Total Trades 396 Average Win 25.18% Average Loss -8.71% Compounding Annual Return -51.829% Drawdown 60.200% Expectancy 0.749 Net Profit -51.800% Sharpe Ratio -0.749 Loss Rate 55% Win Rate 45% Profit-Loss Ratio 2.89 Alpha -1.131 Beta 44.784 Annual Standard Deviation 0.562 Annual Variance 0.316 Information Ratio -0.777 Tracking Error 0.562 Treynor Ratio -0.009 Total Fees $732.60 |
from datetime import timedelta
import decimal
class BasicTemplateFuturesAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 6, 15)
self.SetEndDate(2019, 6, 15)
self.SetCash(25000)
slowperiod = 1720
self.SetWarmUp(slowperiod)
futureES = self.AddFuture(Futures.Indices.SP500EMini)
futureES.SetFilter(timedelta(0), timedelta(182))
futureNQ = self.AddFuture(Futures.Indices.NASDAQ100EMini)
futureNQ.SetFilter(timedelta(0), timedelta(182))
self.frontES = None
self.frontNQ = None
#Add the spread plot and mark the long/short spread point
spreadPlot = Chart("Spread Plot")
spreadPlot.AddSeries(Series("currentspread", SeriesType.Line, 0))
spreadPlot.AddSeries(Series("Long Spread Trade", SeriesType.Scatter, 0))
spreadPlot.AddSeries(Series("Short Spread Trade", SeriesType.Scatter, 0))
spreadPlot.AddSeries(Series("ESNQ SMA", SeriesType.Line, 0))
self.AddChart(spreadPlot)
def OnData(self,slice):
if (self.frontES is not None) and (self.Time > self.frontES.Expiry):
self.frontES = None
if (self.frontNQ is not None) and (self.Time > self.frontNQ.Expiry):
self.frontNQ = None
for chain in slice.FutureChains:
contracts = list(filter(lambda x: x.Expiry > self.Time + timedelta(45), chain.Value))
for contract in contracts:
if ('ES ' in str(contract.Symbol)) and (self.frontES is None):
self.frontES = sorted(contracts, key=lambda x: x.OpenInterest, reverse=False)[0] #True is lowest to highest
self.Consolidate(contract.Symbol, timedelta(minutes=240), self.twoforty)
self.essma = self.SMA(self.frontES.Symbol, 400, Resolution.Minute)
## Same as above but for NASDAQ -- Also, be sure to wrap the Symbol object in str() when comparing it to a character string or else
## the comparison will fail since they won't be of the same type
if ('NQ ' in str(contract.Symbol)) and (self.frontNQ is None):
self.frontNQ = sorted(contracts, key=lambda x: x.OpenInterest, reverse=False)[0]#True is lowest to highest
self.nqsma = self.SMA(self.frontNQ.Symbol, 400, Resolution.Minute)
self.esnqsma = IndicatorExtensions.Minus(self.nqsma, self.essma)
def OnOrderEvent(self, orderEvent):
#self.Log(str(orderEvent))
pass
def twoforty(self, consolidated):
''' This is our event handler for our 45 minute consolidated defined using the Consolidate method'''
self.consolidated45Minute = True
#self.Log(f"{consolidated.EndTime} >> twoforty >> {consolidated.Close}")
currentspread = (self.Securities[self.frontNQ.Symbol].Price - self.Securities[self.frontES.Symbol].Price)
tolerance = decimal.Decimal(18.25)
## Check to make sure both self.frontES and self.frontNQ are contracts that can be traded
if (self.frontES is not None) and (self.frontNQ is not None):
if not self.Portfolio.Invested and currentspread <= (self.esnqsma.Current.Value - tolerance):
self.MarketOrder(self.frontES.Symbol , -1)
self.MarketOrder(self.frontNQ.Symbol , 1)
self.Plot("Spread Plot", "Long Spread Trade", currentspread)
#self.Log("We are Long, Total Margin Used is: " + str(self.Portfolio.TotalAbsoluteHoldingsCost))
#self.Log("currentspread is less than esnq tolerance: " + str(currentspread) + " < " + str(self.esnqsma.Current.Value - tolerance))
#self.Log("What contracts are available??" + str(self.frontES) + " and " + str(self.frontNQ))
self.Notify.Sms("+test", "LONG, Paper Forex");
if not self.Portfolio.Invested and currentspread >= (self.esnqsma.Current.Value + tolerance):
self.MarketOrder(self.frontES.Symbol , 1)
self.MarketOrder(self.frontNQ.Symbol , -1)
self.Notify.Sms("+test", "Liquidate, Paper Forex");
self.Plot("Spread Plot", "Short Spread Trade", currentspread)
#self.Log("We are Short, Total Margin Used is: " + str(self.Portfolio.TotalAbsoluteHoldingsCost))
#self.Log("currentspread is greater than esnq tolerance: " + str(currentspread) + " > " + str(self.esnqsma.Current.Value + tolerance))
#self.Log("Did we purchase any contracts??" + str(self.frontES.Symbol) + " and " + str(self.frontNQ.Symbol))
if self.Portfolio.Invested:
if (self.esnqsma.Current.Value + 2.00) >= currentspread >= (self.esnqsma.Current.Value - 2.00):
self.Liquidate()
self.Plot("Spread Plot", "ESNQ SMA", self.esnqsma.Current.Value)
self.Plot("Spread Plot", "currentspread", currentspread)
def OnEndOfDay(self):
#self.Log("Settled Cash is: " + str(self.Portfolio.Cash))
#self.Log("Total Margin Used is: " + str(self.Portfolio.TotalAbsoluteHoldingsCost))
#self.Log("Total Units held is: " + str(self.Portfolio.TotalHoldingsValue))
morning = "05:00:00.000000"
afternoon = "11:30:00.000000"
time = str(self.Time)
#if not morning < time < afternoon:
# self.Log(str((datetime.now().time())))
pass