class FuturesAlgo(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 4, 1)
self.SetEndDate(2020, 5, 1)
self.SetCash(100000)
es = self.AddFuture(Futures.Indices.SP500EMini, Resolution.Minute)
self.es = es.Symbol
# Filter contracts to only front month contract
es.SetFilter(lambda x : x.FrontMonth())
# 14 period RSI
self.rsi = RelativeStrengthIndex(14, MovingAverageType.Wilders)
self.lastrsi = None
def OnData(self, data):
chain = data.FutureChains.get(self.es, None)
if chain is None:
return
contract = chain.Contracts.values()[0]
self.rsi.Update(self.Time, contract.LastPrice)
if not self.rsi.IsReady: return
if self.lastrsi is None:
self.lastrsi = self.rsi.Current.Value
return
if not self.Portfolio.Invested:
symbol = contract.Symbol
if self.lastrsi < 30 and self.rsi.Current.Value > 30:
self.OrderTick = self.MarketOrder(symbol, 1)
self.SafeDebug(f"LONG, Bid: {contract.BidPrice}, Ask: {contract.AskPrice}, Last: {contract.LastPrice}, FillPrice: {self.OrderTick.AverageFillPrice}, {self.rsi.Current.Value}, {self.Time}")
if self.lastrsi > 70 and self.rsi.Current.Value < 70:
self.OrderTick = self.MarketOrder(symbol, -1)
self.SafeDebug(f"SHORT, Bid: {contract.BidPrice}, Ask: {contract.AskPrice}, Last: {contract.LastPrice}, FillPrice: {self.OrderTick.AverageFillPrice}, {self.rsi.Current.Value}, {self.Time}")
else:
symbol = self.OrderTick.Symbol
holdings = self.Portfolio[symbol]
if holdings.UnrealizedProfit > 250:
if holdings.IsLong:
self.MarketOrder(symbol, -1)
self.SafeDebug("Out of long for 400")
else:
self.MarketOrder(symbol, 1)
self.SafeDebug("Out of short for 400")
elif holdings.UnrealizedProfit < -200:
if holdings.IsLong:
OrderSell = self.MarketOrder(symbol, -1)
self.SafeDebug(f"LONG EXIT, Ask: {contract.AskPrice}, FillPrice: {OrderSell.AverageFillPrice}")
else:
OrderSell = self.MarketOrder(symbol, 1)
self.SafeDebug(f"SHORT EXIT, Ask: {contract.AskPrice}, FillPrice: {OrderSell.AverageFillPrice}")
self.lastrsi = self.rsi.Current.Value
self.SafeDebug(f"RSI: {self.rsi.Current.Value}")
def SafeDebug(self, message):
'''Turn Debug On/Off to avoid reaching quota limit'''
if False:
self.Debug(message)