from AlgorithmImports import *
from collections import deque

class RushStrategy(QCAlgorithm):

    def Initialize(self):

        # Backtest period
        self.SetStartDate(2022, 1, 1)                
        self.SetEndDate(2023, 12, 1) 

        # Starting cash
        self.SetCash(1000)

        # Simulate a backtest with a margin account at Binance, so fees ... are include
        self.SetBrokerageModel(BrokerageName.Binance, AccountType.Margin) #Simulate the broker component of trading

        self.symbol = self.AddCrypto("BTCUSDT", Resolution.Daily).Symbol #BTCUSDT symbol for daily resolution

        # ADX in Quantconnect include the +DI and -DI, that can be retrived
        self.adx = self.ADX(self.symbol, 14)
        self.diplus = self.adx.PositiveDirectionalIndex
        self.diminus = self.adx.NegativeDirectionalIndex

        #increase the indicators' number of stored value
        self.adx.Window.Size = 7
        self.diplus.Window.Size = 7
        self.diminus.Window.Size = 7

        # Keltner Channels
        self.kc = self.KCH(self.symbol, 20, 2, MovingAverageType.Simple)

        # Retreive bands from KC.
        self.upperband = self.kc.UpperBand
        self.lowerband = self.kc.LowerBand

        # Compute again the Keltner Channels but this time with 2.5 stdev
        self.kcUP = self.KCH(self.symbol, 20, 2.5, MovingAverageType.Simple)

        
        # create a void SMA
        self.volume_sma = SimpleMovingAverage('Volume SMA', 10)

        # fill the SMA with volume for inputs
        # Register the indicator for automatic update 
        self.RegisterIndicator(self.symbol, self.volume_sma, Resolution.Daily, Field.Volume)

        self.SetWarmUp(30)

        self.PlotIndicator("Volume SMA", self.volume_sma)
        self.PlotIndicator("adx", self.adx)

        # compute the fast ADX based on an 7 period average 
        # with DI+ and DI- computed on 14 periods
        self.fast_adx = FastADX('Fast ADX', 7)

        self.RegisterIndicator(self.symbol, self.fast_adx, Resolution.Daily)

        self.PlotIndicator('Fast ADX', self.fast_adx)


    def OnData(self, data):
        # Check if data for "Crypto" is available
        if not data.Bars.ContainsKey(self.symbol):
            return

        # Don't run if the indicators aren't ready
        if self.IsWarmingUp: return

      




class FastADX(PythonIndicator):

    def __init__(self, name, period):
        super().__init__()
        self.Name = name
        self.Value = None
        self.Time = datetime.now()
        self.current = IndicatorDataPoint()
        self.adxf = AverageDirectionalIndex(period)
      
        # double queue
        self.queue = deque(maxlen=period)


    def Update(self, input):

        self.adxf.Update(input)
        if self.adxf.IsReady:
            diplusf = self.adxf.PositiveDirectionalIndex.Current.Value
            diminusf = self.adxf.NegativeDirectionalIndex.Current.Value
            # compute DX
            DX = (100 * abs((diplusf) - (diminusf))) / ((diplusf) + (diminusf))

            # Store the last 7 value of DX in an array (add new to the left, get rid old value to the right)
            self.queue.appendleft(DX)
        
            # count number of value in the array
            count = len(self.queue)

            if count == self.queue.maxlen:

                # compute the 7 period ADX base on the values include in the array
                self.Value = np.sum(self.queue) / count

                self.current = IndicatorDataPoint(input.EndTime, self.Value)

                return self.current



I'm trying to build a fast adx that is an average of 7 DX periods, but the +DI and -DI are computed on a 14 basis period. (I know I could aslo build a fast adx by taking self.ADX(self.symbol, 7) = fast adx, and doing an IndicatorExtension that compute the SMA of this adx, to obtain the slow adx. But i don't want this and i also want to learn how to create a custom indicator on the basis of another indicator as well) Thank you :)))