Skip to content
Open RaamTrade

RC2_PARAM_DEFAULT_OUT_OF_RANGE

Param <name> defaults to a value below its own min or above its own max.

What it means

The default is the value the strategy runs with when nobody changes it. If it sits outside the bounds the same declaration sets, it is a value the parameter is not allowed to hold: the control clamps it the first time a user touches the field, and the optimizer never visits it.

So the run the author tested is not the run anyone else gets, and nothing says so. The enum form of this has been refused since the parameter-kinds ruling — “a default the parameter is not allowed to hold is a value no run can reproduce” — and the numeric form is the same sentence.

Why it happens

A bound tightened later, with the default left where it was:

class DefaultBelowMin(Strategy):
period = Param(20, min=50, max=200)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
sma = SMA(self.period, on=self.trade)
if sma.value > 0 and self.trade.is_flat:
self.buy(self.trade)

Or a default that outgrew its ceiling:

class DefaultAboveMax(Strategy):
period = Param(500, min=2, max=200)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
sma = SMA(self.period, on=self.trade)
if sma.value > 0 and self.trade.is_flat:
self.buy(self.trade)

How to fix it

Move the default inside the bounds, or widen the bounds to admit it. Sitting exactly ON a bound is fine.

class DefaultInRange(Strategy):
period = Param(50, min=50, max=200)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
sma = SMA(self.period, on=self.trade)
if sma.value > 0 and self.trade.is_flat:
self.buy(self.trade)

The optimizer range is a different thing: Param(7, min=2, max=200, opt_min=20, opt_max=50) is legal, and means “sweep 20..50, but ship 7”. Only min/max fence what the parameter may hold.

  • Param()
  • RC2_PARAM_DEFAULT_NOT_IN_CHOICES — the same rule for an enum.
  • RC2_PARAM_RANGE_INVERTED — the two ends are the wrong way round.