You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Indie v5构建堆叠成交量直方图指标时遭遇模块使用限制错误的求助

Indie v5构建堆叠成交量直方图指标时遭遇模块使用限制错误的求助

我正在Indie v5中构建一个堆叠成交量直方图指标,但遇到了如下错误:

direct use of modules without reference to their attributes is prohibited

我的代码如下:

# indie:lang_version = 5
import indie

@indie.indicator('Advanced Stacked Volume Histogram')
@indie.param.int('rsi_length', default=14, min=1, title='RSI Length')
@indie.param.int('volume_length', default=14, min=1, title='Volume Length')
@indie.param.source('src', default=indie.source.CLOSE, title='Source')
@indie.param.str('analysis_mode', default='Trend', options=['Trend', 'Momentum', 'Volatility'], title='Analysis Mode')
@indie.plot.histogram(title='Bullish Volume')
@indie.plot.histogram(title='Bearish Volume')
@indie.plot.histogram(title='Neutral Volume')
def Main(self, rsi_length: int, volume_length: int, src: indie.MutSeriesF, analysis_mode: str):

    rsi = indie.algorithms.Rsi.new(src, rsi_length)[0]
    volume_change = indie.algorithms.Change.new(self.volume)[0]
    volatility = indie.algorithms.StdDev.new(self.close, rsi_length)[0]
    

    bullish_vol, bearish_vol, neutral_vol = calculate_volume_components(self.close, self.volume)
    
 
    bullish_sum = indie.algorithms.Sum.new(indie.MutSeriesF.new(max(bullish_vol, 0)), volume_length)[0]
    bearish_sum = indie.algorithms.Sum.new(indie.MutSeriesF.new(max(bearish_vol, 0)), volume_length)[0]
    neutral_sum = indie.algorithms.Sum.new(indie.MutSeriesF.new(max(neutral_vol, 0)), volume_length)[0]
    
    # Return stacked histogram bars with dynamic colors
    return (
        indie.plot.Histogram(bullish_sum, color=determine_color(bullish_sum, True, analysis_mode, rsi, volume_change, volatility)),
        indie.plot.Histogram(bearish_sum, color=determine_color(bearish_sum, False, analysis_mode, rsi, volume_change, volatility)),
        indie.plot.Histogram(neutral_sum, color=indie.color.GRAY)
    )


def calculate_volume_components(close: indie.MutSeriesF, volume: indie.MutSeriesF) -> tuple[float, float, float]:
  
    price_change = close[0] - close[1]
    
    bullish_volume = volume[0] if price_change > 0 or volume[0] > volume[1] else 0
    bearish_volume = volume[0] if price_change < 0 or volume[0] < volume[1] else 0
    neutral_volume = volume[0] - (bullish_volume + bearish_volume)
    
    return bullish_volume, bearish_volume, neutral_volume


def determine_color(volume: float, is_bullish: bool, analysis_mode: str, rsi: float, volume_change: float, volatility: float) -> indie.color:
   
    if analysis_mode == 'Trend':
        if is_bullish:
            return (indie.color.GREEN if rsi >= 50 else 
                    indie.color.LIME if rsi > 30 else 
                    indie.color.GREEN(0.5))
        else:
            return (indie.color.RED if rsi <= 50 else 
                    indie.color.MAROON if rsi < 70 else 
                    indie.color.RED(0.5))

    elif analysis_mode == 'Momentum':
        intensity = min(255, int(abs(volume_change) * 100))
        return indie.color.rgba(0, intensity, 0) if is_bullish else indie.color.rgba(intensity, 0, 0)

    elif analysis_mode == 'Volatility':
        vol_intensity = min(255, int(volatility * 10))
        return indie.color.rgba(int(vol_intensity * 0.2), int(vol_intensity), int(vol_intensity * 0.6)) if is_bullish else indie.color.rgba(int(vol_intensity), int(vol_intensity * 0.2), int(vol_intensity * 0.6))

我已经尝试过以下方法:

  • 完全限定所有Indie模块调用(例如 indie.plot.histogram、indie.algorithms.Rsi.new())
  • 确保所有参数都有明确的类型注解
  • 使用 import indie 正确导入Indie模块

为什么即使完全限定了所有模块引用,Indie仍然抛出错误*"Direct use of modules without reference to their attributes is prohibited"*?


问题分析与解决方案

这个错误的核心原因在于Indie v5的脚本环境不允许直接传递模块类型(比如indie.MutSeriesF)作为函数参数、类型注解,或者直接实例化模块类,你的代码里正好有几处违反这个规则的地方:

1. 违规点拆解

  • 独立辅助函数calculate_volume_components和determine_color中,直接使用indie.MutSeriesF、indie.color作为类型注解,Indie无法识别这种直接引用模块类型的写法
  • 在计算bullish_sum时,直接调用indie.MutSeriesF.new(...)实例化模块类,这属于未通过合法属性引用的方式使用模块
  • 独立辅助函数的作用域脱离了指标主函数,Indie的脚本解析器无法正确处理这类函数中的模块引用

2. 修正后的代码示例

# indie:lang_version = 5
import indie

@indie.indicator('Advanced Stacked Volume Histogram')
@indie.param.int('rsi_length', default=14, min=1, title='RSI Length')
@indie.param.int('volume_length', default=14, min=1, title='Volume Length')
@indie.param.source('src', default=indie.source.CLOSE, title='Source')
@indie.param.str('analysis_mode', default='Trend', options=['Trend', 'Momentum', 'Volatility'], title='Analysis Mode')
@indie.plot.histogram(title='Bullish Volume')
@indie.plot.histogram(title='Bearish Volume')
@indie.plot.histogram(title='Neutral Volume')
def Main(self, rsi_length: int, volume_length: int, src, analysis_mode: str):
    rsi = indie.algorithms.Rsi.new(src, rsi_length)[0]
    volume_change = indie.algorithms.Change.new(self.volume)[0]
    volatility = indie.algorithms.StdDev.new(self.close, rsi_length)[0]
    
    # 将辅助函数移到主函数内部,确保作用域符合Indie规则
    def calculate_volume_components(close, volume):
        price_change = close[0] - close[1]
        bullish_volume = volume[0] if price_change > 0 or volume[0] > volume[1] else 0
        bearish_volume = volume[0] if price_change < 0 or volume[0] < volume[1] else 0
        neutral_volume = volume[0] - (bullish_volume + bearish_volume)
        return bullish_volume, bearish_volume, neutral_volume
    
    def determine_color(volume_val, is_bullish):
        if analysis_mode == 'Trend':
            if is_bullish:
                return indie.color.GREEN if rsi >= 50 else indie.color.LIME if rsi > 30 else indie.color.GREEN(0.5)
            else:
                return indie.color.RED if rsi <= 50 else indie.color.MAROON if rsi < 70 else indie.color.RED(0.5)
        elif analysis_mode == 'Momentum':
            intensity = min(255, int(abs(volume_change) * 100))
            return indie.color.rgba(0, intensity, 0) if is_bullish else indie.color.rgba(intensity, 0, 0)
        elif analysis_mode == 'Volatility':
            vol_intensity = min(255, int(volatility * 10))
            return indie.color.rgba(int(vol_intensity * 0.2), int(vol_intensity), int(vol_intensity * 0.6)) if is_bullish else indie.color.rgba(int(vol_intensity), int(vol_intensity * 0.2), int(vol_intensity * 0.6))
    
    bullish_vol, bearish_vol, neutral_vol = calculate_volume_components(self.close, self.volume)
    
    # 移除直接实例化MutSeriesF的操作,直接传递处理后的数值
    bullish_sum = indie.algorithms.Sum.new(bullish_vol if bullish_vol > 0 else 0, volume_length)[0]
    bearish_sum = indie.algorithms.Sum.new(bearish_vol if bearish_vol > 0 else 0, volume_length)[0]
    neutral_sum = indie.algorithms.Sum.new(neutral_vol if neutral_vol > 0 else 0, volume_length)[0]
    
    return (
        indie.plot.Histogram(bullish_sum, color=determine_color(bullish_sum, True)),
        indie.plot.Histogram(bearish_sum, color=determine_color(bearish_sum, False)),
        indie.plot.Histogram(neutral_sum, color=indie.color.GRAY)
    )

3. 关键修正说明

  • 移除了辅助函数中对模块类型的显式注解,改用Indie自动支持的隐式类型推断
  • 将辅助函数移入主函数Main内部,让作用域完全符合Indie的脚本解析要求
  • 删掉了直接实例化indie.MutSeriesF的代码,直接传递处理后的数值给Sum.new
  • 简化了determine_color的参数,利用内部作用域直接访问rsi、volume_change等变量,避免不必要的参数传递

备注:内容来源于stack exchange,提问作者turfira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:23:08