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

Param()

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

A Param() is a tunable strategy input. It has a default, an optional range, and optional optimizer hints. Every Param() is visible to the user in the UI and to the optimizer as a search dimension.

Its TYPE comes from its default value. Nothing else declares it, and you never have to write it down: 7 is an int, 2.0 a float, False a bool, and choices= makes a fixed set of options. 7 and 7.0 are two different declarations, so write the default the way you mean the parameter to behave.

Signature

Param(default, *, min=None, max=None, opt_min=None, opt_max=None, opt_step=None,
choices=None, type=None, title=None)
Argument Required Notes
default Yes Sets the type: 7 = int, 2.0 = float, True = bool, "trail" needs choices=.
min / max No Hard bounds. Boundary violations reject at compile time (no silent clamping).
opt_min / opt_max No Optimizer grid range. Must be within min/max. Defaults to min/max.
opt_step No Grid step. Defaults to 1 (int) or 0.01 (float). A fractional step on an int is rejected.
choices No A fixed set of allowed values. Makes the parameter an enum.
type No int, float, bool or enum. A second opinion on the default, never a conversion.
title No The setting’s title on the run form: one text, or one per language, {"en": "…", "he": "…"}. See Titles.

Examples

# Integer with hard bounds
fast_period = Param(7, min=2, max=50)
# Float
sl_pct = Param(2.0, min=0.1, max=20.0)
# Boolean
fractional = Param(False)
# Separate optimization bounds — sweep 15..100 step 5, but the user can still type 10..200
slow = Param(21, min=10, max=200, opt_min=15, opt_max=100, opt_step=5)
# Enum — a fixed set of options. Three spellings: value-to-label, a bare list, strings.
mode = Param(2, choices={1: "cross only", 2: "aroon", 3: "momentum"})
exits = Param(0, choices=[0, 1, 2])
style = Param("trail", choices=["none", "trail", "fixed"])
# Plain literal — not a Param. Appears as a constant in the editor; not optimizable.
position_size = 100

The four types

int, float, bool, enum. Each gets its own control and its own optimizer walk.

Type Declared by Control Optimizer
int a whole-number default integer slider, step 1, one stop per value an integer grid; never hands the strategy 2.5
float a default with a decimal point step-aware slider plus a decimal box a decimal grid from opt_step
bool True / False a switch exactly {False, True}
enum choices= the options as a checklist the choice SET you tick, never a grid

choices= (enum)

class ModeSwitch(Strategy):
mode = Param(2, choices={1: "cross only", 2: "aroon", 3: "momentum"})
style = Param("trail", choices=["none", "trail", "fixed"])
trade = Symbol()
sizing = FixedCapital()
def execute(self):
fast = SMA(10, on=self.trade)
slow = SMA(30, on=self.trade)
if self.mode == 2 and fast.crossed_above(slow) and self.trade.is_flat:
self.buy(self.trade, reason="Aroon mode")
  • Values stay raw. self.mode is the integer 2, not "2" and not the label, so if self.mode == 2: is how you branch. Saved parameter sets, walk-forward results, runner parameters and old backtests all keep meaning the same thing.
  • Labels are your strings, shown as written. The platform never translates them and never invents one; a bare list shows the values themselves.
  • The default must be one of the choices, and min/max/opt_min/opt_max/opt_step are rejected on an enum — the choices ARE the range.
  • Every option is the same type, listed once, and there is at least one. choices=[False, True] is rejected: a bool already is two values, so write Param(False).

The explicit type=

Optional everywhere. Write it when the intent benefits from being spelled out, most often when a deliberate 0/1 integer switch sits next to a real bool:

enable_stop_loss = Param(0, min=0, max=1, type=int) # deliberate integer switch
use_trailing = Param(False) # a real bool

type= never converts, so it has to agree with the default:

class TypeDisagrees(Strategy):
bars = Param(2.5, type=int)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
if self.trade.is_flat:
self.buy(self.trade)

A 0/1 integer compiles green with a hint (RC2_PARAM_BOOL_HINT) suggesting Param(False); writing type=int silences it. Lists, dicts and tuples are still not parameters — a free-form string (a note, an arbitrary date) has no Param equivalent either; use a bool switch or split into multiple strategies.

Titles

The run form shows each setting under a title. Without title= the title is the Param’s own name, so fast_length reads as fast_length. With it, the member reads your words in their own language:

class TitledCross(Strategy):
fast = Param(7, min=2, max=50, title={"en": "Fast average", "he": "ממוצע מהיר"})
slow = Param(21, min=10, max=200, title="Slow average")
trade = Symbol()
sizing = FixedCapital()
def execute(self):
f = SMA(self.fast, on=self.trade)
s = SMA(self.slow, on=self.trade)
if f.value > s.value and self.trade.is_flat:
self.buy(self.trade)
  • A dict gives one title per language. The platform speaks en and he.
  • A plain string is shown to everyone as written.
  • A member whose language is missing from the dict sees the other one.
  • A title is words only: changing it changes nothing a backtest, an optimizer or a live strategy does. Renaming the Param itself does, because saved values are kept by name.
  • title= is for strategy parameters. An indicator’s Param refuses it (RC2_PARAM_TITLE) until the indicator settings show titles.

How Params reach you

Inside execute() (or any helper method) every Param is exposed as self.<name>:

class MACross(Strategy):
fast = Param(7, min=2, max=50)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
ma = SMA(self.fast, on=self.trade) # self.fast reads the Param's current value

Optimizer integration

Every Param with min/max (or opt_min/opt_max) automatically becomes a dimension in the optimizer grid. There is no separate “optimizer schema” to maintain.

fast = Param(7, min=2, max=50) # 49 values, step 1 = 49 dims
slow = Param(21, min=10, max=200, opt_step=5) # 39 values, step 5 = 39 dims
sl_pct = Param(2.0, min=0.5, max=5.0, opt_step=0.5) # 10 float steps

To freeze a Param (keep it in the UI but exclude from optimization), set opt_min == opt_max:

slippage = Param(0.5, min=0.0, max=5.0, opt_min=0.5, opt_max=0.5)

Naming rules

A Param name cannot:

  • Shadow a strategy-level property (capital, initial_capital, bar_count, ready) → RC2_PARAM_RESERVED
  • Collide with a Symbol name in the same class → RC2_STATE_PARAM_CLASH
  • Be assigned a value other than a Param() call or a plain literal in the class body → RC2_CLASS_BODY

Common diagnostics

Code What it means
RC2_PARAM_DEFAULT Param() called without a default value.
RC2_PARAM_RESERVED Param name shadows a reserved property.
RC2_PARAM_UNKNOWN_KWARG A keyword outside min, max, opt_min, opt_max, opt_step, choices, type, title.
RC2_PARAM_TITLE title= is not text, or names a language the platform does not speak.
RC2_STATE_PARAM_CLASH Param name collides with a Symbol or persistent state variable.
RC2_PARAM_TYPE_MISMATCH type= disagrees with the default literal.
RC2_PARAM_TYPE_UNKNOWN type= is not one of int, float, bool, enum.
RC2_PARAM_DEFAULT_NOT_IN_CHOICES The default is not one of the declared choices.
RC2_PARAM_ENUM_NO_RANGE A range keyword on an enum. The choices are the range.
RC2_PARAM_ENUM_EMPTY choices= with nothing in it.
RC2_PARAM_ENUM_DUPLICATE The same option listed twice.
RC2_PARAM_ENUM_MIXED_TYPES The options are not all the same type.
RC2_PARAM_ENUM_BOOL True/False as choices. Write Param(False).
RC2_PARAM_ENUM_LABEL A choices dict’s values must be text labels.
RC2_PARAM_ENUM_SHAPE choices= takes a list or a value-to-label dict.
RC2_PARAM_RANGE_NOT_NUMERIC A range keyword on a bool or a text parameter.
RC2_PARAM_INT_STEP A fractional opt_step on an integer parameter.
RC2_PARAM_INT_BOUND A fractional min/max/opt_min/opt_max on an integer parameter.