Sizing
תוכן זה אינו זמין עדיין בשפה שלך.
Every strategy must declare exactly one sizing property at class level. It tells entry verbs (buy, sell_short) how to compute quantity. Missing sizing → RC2_NO_SIZING.
Three models
FixedQuantity(n) — n contracts/shares
sizing = FixedQuantity() # default: 1 contractsizing = FixedQuantity(5) # always 5sizing = FixedQuantity(contracts=Param(1, min=1, max=100)) # user-tunable- Compute:
quantity = n. Capital and price are ignored. - Walk-forward: constant — no equity chaining.
FixedCapital(percent) — percent of initial capital
sizing = FixedCapital() # 100% of initial capitalsizing = FixedCapital( percent=Param(80, min=10, max=100), fractional=Param(False),)- Compute:
floor(initial_capital * percent / 100 / execution_price)— exact division iffractional=True. - Defaults:
percent=100,fractional=False. - Walk-forward: constant — initial capital is fixed per window.
Compounding(percent) — percent of current equity
sizing = Compounding() # 100% of current equitysizing = Compounding( percent=Param(95, min=10, max=100), fractional=Param(False),)- Compute:
floor(capital * percent / 100 / execution_price). - Defaults:
percent=100,fractional=False. - Walk-forward: compounding — equity chains across windows.
When each model fits
| Model | Use when |
|---|---|
FixedQuantity |
Futures / options where contract size is intrinsic. Risk-based sizing (compute quantity manually, override with qty=). |
FixedCapital |
Equity strategies you want to compare on equal footing — every backtest starts from the same dollar amount. |
Compounding |
Long-horizon strategies where you want winners to grow the position. The realistic “let it run” model. |
Sizing params are optimizable
Any Param() inside a sizing model behaves like any other Param — the optimizer sweeps it.
sizing = Compounding(percent=Param(95, min=50, max=100, opt_step=5))To freeze a sizing param, set min == max (or opt_min == opt_max).
Override per signal
Entry verbs accept override kwargs that replace the class-level setting for that one trade.
| Sizing model | qty= |
percent= |
|---|---|---|
FixedQuantity |
Allowed | RC2_OVERRIDE_INVALID |
FixedCapital |
RC2_OVERRIDE_INVALID |
Allowed |
Compounding |
RC2_OVERRIDE_INVALID |
Allowed |
class QuantityOverride(Strategy): trade = Symbol() sizing = FixedQuantity(5)
def execute(self): if self.trade.is_flat: self.buy(self.trade, qty=10) # 10 contracts instead of 5class CapitalOverride(Strategy): trade = Symbol() sizing = FixedCapital(percent=80)
def execute(self): if self.trade.is_flat: self.buy(self.trade, percent=50) # 50% of initial_capital — replaces 80class CompoundingOverride(Strategy): trade = Symbol() sizing = Compounding(percent=95)
def execute(self): if self.trade.is_flat: self.sell_short(self.trade, percent=50) # 50% of current equitypercent= is always a replacement, not multiplicative. The class-level value is ignored for that trade.
Quantity resolution timing
Entry verbs do not resolve quantity at signal time. The platform computes the final quantity at fill time using the execution price:
- Market orders — quantity computed from the next bar’s open.
- Stop / limit orders — quantity computed from the stop or limit price.
If the computed quantity is 0 (insufficient capital for even 1 unit), the trade is silently skipped. The order does not appear in fills.
Common diagnostics
| Code | What it means |
|---|---|
RC2_NO_SIZING |
No sizing = … in the class body. |
RC2_SIZING_UNKNOWN |
Unrecognized sizing model name. |
RC2_OVERRIDE_INVALID |
Override kwarg not allowed for this sizing model. |