דלגו לתוכן
פתיחת RaamTrade

RC2_IND_INCONSISTENT_OUTPUTS

תוכן זה אינו זמין עדיין בשפה שלך.

Multi-value indicator has inconsistent output keys — line N returns (a, b) but line M returns (a, b, c). All return paths must use the same keys.

What it means

A multi-output indicator’s dict keys are its public surface. They become the fields of the generated value record, the names a strategy reads (bands.upper), and the series the chart draws. That surface is fixed at compile time, from the return statements.

So every return must carry the same key set. A branch that drops a key would leave a field with no value on the bars that branch fires, and a strategy reading bands.mid would get a number that silently means “this bar took the other path” — which is exactly the class of bug this refusal exists to prevent.

The keys must also match in order, not just as a set: the value record’s constructor takes them positionally.

Why it happens

A warmup branch and a main branch that drifted apart:

class MyBands(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self, close):
self.buffer.add(close)
mid = sum(self.buffer) / len(self.buffer)
if not self.is_ready:
return {"upper": close, "lower": close} # ❌ no "mid"
return {"upper": mid + 1, "mid": mid, "lower": mid - 1}

The same error catches a reordering — {"upper": …, "lower": …, "mid": …} against {"upper": …, "mid": …, "lower": …} — even though the set of names is identical.

How to fix it

Give every path the same keys, in the same order. A path that has nothing meaningful for an output should still name it, with whatever neutral value fits (the close, zero, the previous value).

class MyBands(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self, close):
self.buffer.add(close)
mid = sum(self.buffer) / len(self.buffer)
if not self.is_ready:
return {"upper": close, "mid": close, "lower": close}
return {"upper": mid + 1, "mid": mid, "lower": mid - 1}

The single-exit form sidesteps the problem entirely, and is usually clearer once there are more than two branches:

class MyBands(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self, close):
self.buffer.add(close)
mid = sum(self.buffer) / len(self.buffer)
width = 1
if not self.is_ready:
mid = close
width = 0
return {"upper": mid + width, "mid": mid, "lower": mid - width}
  • Custom Indicators
  • RC2_IND_MIXED_RETURN — one path returns a dict and another returns a bare number.
  • RC2_IND_RESERVED_OUTPUT_KEY — the keys are consistent, but value / color are reserved names.
  • RC2_IND_OUTPUT — the strategy side: reading an output name the indicator does not declare.