Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-12.843
Tracking Error
0.024
Treynor Ratio
0
Total Fees
$0.00
class FutureScalping(QCAlgorithm):
    
    def Initialize(self):
        self.firstlog = True 
        self.SetStartDate(2020, 8, 26)  # Set Start Date
        self.SetEndDate(2020, 8, 27)
        self.SetCash(40000)  # Set Strategy Cash
        
        self.SetSecurityInitializer(self.OpenInterestSecurityInitializer)
        
        self.contratSymbol = None
        # self.gold = self.AddFuture(Futures.Metals.Gold, resolution=Resolution.Second)
        self.gold = self.AddFuture(Futures.Metals.Gold, Resolution.Minute, Market.COMEX, True, 1)
        self.gold.SetFilter(100, 200)
        
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
        self.log_count = 0
        self.oi_zero_count = 0
        # self.sto = self.STO(self.gold.Symbol, 60, 300, Resolution.Second)
        # self.close = Identiy(self.gold.Symbol)
        # self.PlotIndicator("GC", self.sto, self.close);
        self.stochasticPeriod = 5
        self.KPeriod = 3
        self.DPeriod = 3
    def OpenInterestSecurityInitializer(self, security):
        if security.Type == SecurityType.Future:
            history = self.History([security.Symbol], timedelta(1))
            if 'openinterest' in history:
                oi = OpenInterest(self.Time, security.Symbol,
                    history.openinterest.dropna().iloc[-1])
                security.SetMarketPrice(oi)
    def OnData(self, data):
        if (self.Time.hour == 9) and (self.Time.minute == 30):
            self.Debug(f"The time of this slice of data is {self.Time}")
            self.Debug(f"The size of FutureChanins is {len(data.FutureChains)}")

        for chain in data.FutureChains.Values:
            # self.popularContracts = [contract for contract in chain if contract.OpenInterest != 0]
            self.popularContracts = [contract for contract in chain]
            if len(self.popularContracts) == 0:
                self.oi_zero_count += 1
                continue
            else:
                sortedByOIContracts = sorted(self.popularContracts, key=lambda x: x.OpenInterest, reverse=True)
                #if self.firstlog:    
                if True:    
                    self.Debug(f"The no. of contract is {len(self.popularContracts)}")
                    for i, contract in enumerate(sortedByOIContracts):
                        self.Log(f"Time: {self.Time}, Contract No.: {i}, Contract Symbol: {contract.Symbol}, Underlying Symbol: {contract.UnderlyingSymbol}, "
                                   f"Expiry: {contract.Expiry}, Open Interest: {contract.OpenInterest}, Volume: {contract.Volume}, "
                                   f"BidPrice: {contract.BidPrice}, AskPrice: {contract.AskPrice}")
                    self.firstlog = False
                self.activeSymbol = sortedByOIContracts[0]
            # if self.log_count < 10:
            #     self.Debug(f"OnData Time: {self.Time}")
            #     self.log_count += 1
            
    def OnEndOfAlgorithm(self):
        self.Debug(f"Minute with zero open interest count: {self.oi_zero_count}")
        pass
    
    def GetActiveContract(self, slice):
        for chain in data.FutureChains.Values:
            self.popularContracts = [contract for contract in chain if contract.OpenInterest != 0]
            if len(self.popularContracts) == 0:
                return None
            else:
                sortedByOIContracts = sorted(self.popularContracts, key=lambda x: x.OpenInterest, reverse=True)
                self.activeContract = sortedByOIContracts[0]
                return self.activeContract
    
    def SetupIndicator(self):
        pass
    
    def GetTradingContract(self, slice):
        if not self._newDay:
            return True

        if (self._contract != None and (self._contract.Expiry - self.Time).days >=3):
            return True
            
        for chain in slice.FutureChains.Values:
            contracts = chain.Contracts.Values
            
            #self.Log(str(chain))
            
            skip = 0
            if (self._contract != None):
                self.Log('Expiry days away {} - {} - {}'.format((self._contract.Expiry-self.Time).days, self._contract.Expiry, self.Time.date))
            if (self._contract != None and (self._contract.Expiry-self.Time).days <= 3):
                skip = 1
                
            chainContracts = list(contracts) #[contract for contract in chain]
            chainContracts = sorted(chainContracts, key=lambda x: x.Expiry)
                
            if (len(chainContracts) < skip+2):
                return False
                
            first = chainContracts[skip]
            second = chainContracts[skip+1]
            
            if (first != None and second != None):
                
                self.Log('RESET: ' + first.Symbol.Value + ' - ' + second.Symbol.Value)
                self.reset=True
                
                if (first != None and (self._contract == None or self._contract.Symbol != first.Symbol)):
                    
                    if (self._nextContract != None):
                        
                        self._bb = self._nextBb
                        self._contract = self._nextContract
                        
                    else:
                        
                        self._contract = first
                        
                        oneHour = TradeBarConsolidator(TimeSpan.FromMinutes(60))
                        oneHour.DataConsolidated += self.OnHour
                        
                        self.SubscriptionManager.AddConsolidator(self._contract.Symbol, oneHour)
                        self._bb = self.BB(self._contract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour)
                        
                        history = self.History(self._contract.Symbol, 50*60, Resolution.Minute).reset_index(drop=False)
                        self.Log(len(history))
                        
                        for bar in history.itertuples():

                            #if (bar.EndTime.Minute == 0 and (self.Time-bar.EndTime).TotalMinutes >=2):

                            if (bar.time.minute == 0 and ((self.Time-bar.time)/pd.Timedelta(minutes=1)) >=2):
                                
                                self.Log(str(bar))
                                #self._bb.Update(self._contract.Symbol, bar.time, bar.close)
                                self._bb.Update(bar.time, bar.close)
                                
                        self.Log(str(self._bb.IsReady))

                if (second != None and (self._nextContract == None or (self._nextContract.Symbol != second.Symbol))):
                    
                    self._nextContract = second
                    oneHour = TradeBarConsolidator(TimeSpan.FromMinutes(60))
                    oneHour.DataConsolidated += self.OnHour
                    
                    self.SubscriptionManager.AddConsolidator(self._nextContract.Symbol, oneHour)
                    self._nextBb = self.BB(self._nextContract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour)
                    
                self._newDay=False
                return True
        return False