Overall Statistics
Total Trades
1059
Average Win
0.35%
Average Loss
-0.30%
Compounding Annual Return
-97.338%
Drawdown
26.800%
Expectancy
-0.186
Net Profit
-25.774%
Sharpe Ratio
-4.826
Probabilistic Sharpe Ratio
0%
Loss Rate
62%
Win Rate
38%
Profit-Loss Ratio
1.16
Alpha
-0.816
Beta
-0.03
Annual Standard Deviation
0.195
Annual Variance
0.038
Information Ratio
-13.218
Tracking Error
0.391
Treynor Ratio
31.386
Total Fees
$1959.15
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)