admin管理员组

文章数量:1355658

I'm building an indicator that visualizes candle volume per bin on a higher timeframe (HTF), like the classic "HTF Candle Volume Thermometer".

My PineScript version uses request.security() to get HTF values and works fine. I'm trying to convert this to Indie, and I'm stuck using @sec_context and MutSeriesF properly.

Here are my goals:

  • Use @sec_context('timeframe') to calculate HTF open/close values.
  • Access those values in the main indicator function.
  • Use MutSeriesF to track evolving data like high, low, and volume.
  • Avoid invalid operations or restricted syntax (like global or list comprehension).

Errors Encountered

MutSeriesF.new(...) outside context:

Error: `indie.MutSeriesF.new` is a syntactic sugar function in Indie and can only be called from a function decorated with @indie.algorithm, @indie.sec_context or @indie.indicator

Use of global

Error: 11:4 `global` statements are prohibited

self.security(...) not recognized

Error: 13:15 symbol `self.security` not found

Current code.

I tried using @sec_context to get HTF values and store them in MutSeriesF variables declared outside the function (but this triggered error #1 and #2). Then I tried using self.security(...), but that seems not to exist in Indie.

# indie:lang_version = 5
from indie import indicator, param, color, MutSeriesF, plot, sec_context
from indie.algorithms import Atr
from indie.color import LIME, RED, YELLOW

open_htf = MutSeriesF.new(0)
close_htf = MutSeriesF.new(0)

@sec_context('timeframe')
def Htf(self):
    open_htf[0] = self.open[1]
    close_htf[0] = self.close[1]

@indicator('HTF Candle Volume Thermometer', overlay_main_pane=True)
@param.str('timeframe', default='D', title='HTF Timeframe')
@param.str('resolution', default='Mid', options=['High', 'Mid', 'Low'], title='Resolution')
@plot.line(id='top', color=color.GRAY)
@plot.line(id='bottom', color=color.GRAY)
@plot.fill('top', 'bottom')
def Main(self, timeframe, resolution):
    htf_high = MutSeriesF.new(self.high[0])
    htf_low = MutSeriesF.new(self.low[0])
    bars_volume = MutSeriesF.new(self.volume[0])
    bar_index0 = self.index

    is_new_htf_bar = self.index > 0 and self.time[0] != self.time[1]

    if is_new_htf_bar:
        htf_high[0] = self.high[0]
        htf_low[0] = self.low[0]
        bars_volume[0] = self.volume[0]
        bar_index0 = self.index
    else:
        htf_high[0] = max(htf_high[1], self.high[0])
        htf_low[0] = min(htf_low[1], self.low[0])
        bars_volume[0] = bars_volume[1] + self.volume[0]

    div = 3
    if resolution == 'High':
        div = 5
    elif resolution == 'Low':
        div = 1

    step = Atr.new(200)[0] / div
    box_size = htf_high[0] - htf_low[0]
    levels = int(box_size / step)
    bin = box_size / levels if levels > 0 else 1

    bins = []
    for _ in range(levels):
        bins.append(0.0)

    for i in range(self.index - bar_index0):
        for j in range(levels):
            lo = htf_low[0] + bin * j
            hi = lo + bin
            c = self.close[i]
            if lo <= c and c <= hi:
                bins[j] += self.volume[i]

    min_vol = min(bins)
    max_vol = max(bins)

    top = MutSeriesF.new(0)
    bottom = MutSeriesF.new(0)

    max_index = 0
    max_value = 0
    for i in range(levels):
        lo = htf_low[0] + bin * i
        hi = lo + bin
        vol = bins[i]

        if vol > max_value:
            max_value = vol
            max_index = i

    for i in range(levels):
        lo = htf_low[0] + bin * i
        hi = lo + bin
        vol = bins[i]

        norm = (vol - min_vol) / (max_vol - min_vol) if max_vol > min_vol else 0
        c_up = LIME.alpha(0.8 * (1 - norm))
        c_dn = RED.alpha(0.8 * (1 - norm))
        fill_color = YELLOW if i == max_index else (c_up if close_htf[0] > open_htf[0] else c_dn)

        top[0] = hi
        bottom[0] = lo

    return top[0], bottom[0]

What is the correct way to:

  • Use HTF series (like open[1], close[1]) from another timeframe.
  • Pass those values safely into the @indicator function.
  • Declare MutSeriesF safely across contexts without using global or invalid scope.

本文标签: