RC2_PARAM_STEP_NOT_POSITIVE
Param
<name>declaresopt_stepof zero or less.
What it means
opt_step is the DISTANCE between two values the optimizer tries. Zero never reaches the end of the range — it is an infinite grid — and a negative step walks away from the end it is supposed to reach.
Both used to be accepted and then defended against downstream: the frontend’s own walk clamps a non-positive step to 1, which means the sweep ran on different values than the author declared, silently.
Why it happens
A placeholder that was never filled in, or a sign that came along for the ride:
class ZeroStep(Strategy): period = Param(20, min=2, max=200, opt_step=0) 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)class NegativeStep(Strategy): period = Param(20, min=2, max=200, opt_step=-5) 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
Write a step greater than zero, or drop opt_step and take the default (1 for an int, 0.01 for a float). Direction is not the step’s business — the grid always walks from opt_min up to opt_max.
class RealStep(Strategy): period = Param(20, min=2, max=200, opt_step=5) 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)Related
Param()RC2_PARAM_INT_STEP— the step is positive but fractional on an integer parameter.RC2_PARAM_RANGE_INVERTED— the range the step is meant to walk is empty.