[Python] How to reference the current instrument ID to use calc_on()

Discussão em 'Python' iniciado por Stack, Abril 29, 2025.

  1. Stack

    Stack Membro Participativo

    I'm writing an indicator in Indie v5 and want to get higher timeframe values using calc_on(). The documentation suggests using something like:

    sec_ctx = self.calc_on(self.symbol, htf)


    However, this raises the error:


    Error: symbol 'self.symbol' not found
    ​

    I tried replacing self.symbol with self.id, as in:

    sec_ctx = self.calc_on(self.id, htf)


    But this also raises:


    Error: symbol 'self.id' not found
    ​

    I also checked the context object (MainContext) but couldn’t find any documented field that refers to the instrument or symbol ID.

    What is the correct way to reference the current instrument’s ID or symbol in Indie v5 when calling self.calc_on()? How should I obtain it inside the Main() function?

    Full code:

    # indie:lang_version = 5
    from math import sqrt
    from indie import indicator, param, color, plot, MutSeriesF, Optional
    from indie.algorithms import Atr, Sma, Ema, FixNan
    from indie.plot import line, background

    @indicator("Enhanced Andean Oscillator 2025", overlay_main_pane=False)
    @param.int("length", default=25, min=1, title="Base Length")
    @param.int("signalLength", default=9, min=1, title="Signal Smoothing Length")
    @param.str("htf", default="60", title="Higher Timeframe")
    @param.float("deadZone", default=0.05, min=0.0, title="Dead Zone Threshold")
    @param.int("atrLength", default=14, min=1, title="ATR Length")
    @param.int("volumeLength", default=20, min=1, title="Volume Lookback")
    @param.int("slopeLookback", default=2, min=1, title="Slope Confirmation Bars")
    @plot.line(title="Bullish", color=color.GREEN)
    @plot.line(title="Bearish", color=color.RED)
    @plot.line(title="Signal", color=color.YELLOW)
    @plot.background()
    def Main(self, length: int, signalLength: int, htf: str, deadZone: float, atrLength: int, volumeLength: int, slopeLookback: int):

    atr_now = Atr.new(atrLength)[0]
    atr_ref = Sma.new(Atr.new(atrLength), atrLength)[0]
    alpha = 2 / (length + 1)
    volRatio = atr_now / atr_ref
    alpha = max(min(alpha * volRatio, 1), 0.001)

    vol = self.volume[0]
    avgVol = Sma.new(self.volume, volumeLength)[0]
    volFactor = vol / avgVol if avgVol != 0 else 1.0

    up1 = MutSeriesF.new(init=self.close[0])
    dn1 = MutSeriesF.new(init=self.close[0])
    up2 = MutSeriesF.new(init=self.close[0] ** 2)
    dn2 = MutSeriesF.new(init=self.close[0] ** 2)

    c, o = self.close[0], self.open[0]
    c2, o2 = c * c, o * o

    up1[0] = max(c, o, up1[1] - alpha * (up1[1] - c))
    dn1[0] = min(c, o, dn1[1] + alpha * (c - dn1[1]))
    up2[0] = max(c2, o2, up2[1] - alpha * (up2[1] - c2))
    dn2[0] = min(c2, o2, dn2[1] + alpha * (c2 - dn2[1]))

    bull = sqrt(max(dn2[0] - dn1[0] * dn1[0], 0)) * volFactor
    bear = sqrt(max(up2[0] - up1[0] * up1[0], 0)) * volFactor

    max_val = max(bull, bear)
    signal1 = Ema.new(MutSeriesF.new(max_val), signalLength)[0]
    signal = Ema.new(MutSeriesF.new(signal1), signalLength)[0]

    diff = bull - bear
    inDeadZone = abs(diff) < deadZone

    slopeBull = 0.0
    slopeBear = 0.0
    if slopeLookback < len(self.close):
    slopeBull = bull - self.close[slopeLookback]
    slopeBear = bear - self.open[slopeLookback]
    validSlope = slopeBull > 0 and slopeBear < 0

    sec_ctx = self.calc_on(self.id, htf) #<---ERROR
    bull_htf = sec_ctx.close[0]
    bear_htf = sec_ctx.open[0]
    htf_ok = bull_htf > bear_htf

    longCond = bull > bear + deadZone and not inDeadZone and validSlope and htf_ok
    shortCond = bear > bull + deadZone and not inDeadZone and slopeBear > 0 and slopeBull < 0 and not htf_ok

    exitLong = bull < signal
    exitShort = bear < signal

    bg_color = None
    if longCond:
    bg_color = color.GREEN.alpha(0.85)
    elif shortCond:
    bg_color = color.RED.alpha(0.85)

    return bull, bear, signal, bg_color

    Continue reading...

Compartilhe esta Página