Skip to content
Open RaamTrade

RC2_IND_COMPUTE_SIG

compute() must start with self, followed by bar-field parameters (close, open, high, low, volume).

What it means

compute()’s parameter list is not an ordinary signature you get to design — it is a declaration of which parts of the bar the indicator consumes. The transpiler reads the names, and the runtime feeds exactly those fields, in that order, every bar.

That is why the names are fixed. def compute(self, price) gives the platform no way to know whether “price” means the close, the high, or the typical price, so it refuses instead of guessing. It is also what lets the chart know an indicator is volume-aware, and lets on=self.trade.high retarget a close-only indicator without touching its body.

Why it happens

A field name the language does not have — the most common by far:

class MySMA(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self, price): # ❌ 'price' is not a bar field
self.buffer.add(price)
return sum(self.buffer) / len(self.buffer)

No bar fields at all — self on its own is not a signature, because the indicator would then have no input:

class Constant(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self): # ❌ needs at least one bar field
return 0

How to fix it

Rename the parameters to the fields you actually want.

class MySMA(Indicator):
position = ON_CHART
period = Param(20, min=2, max=200)
buffer = Series(period)
def compute(self, close):
self.buffer.add(close)
return sum(self.buffer) / len(self.buffer)

Any non-empty subset works, in any order — a range-style indicator takes three:

class NormRange(Indicator):
position = OFF_CHART
period = Param(14, min=2, max=200)
buffer = Series(period)
def compute(self, high, low, close):
self.buffer.add((high - low) / close)
return sum(self.buffer) / len(self.buffer)