RC2_STATE_REBIND_COLLECTION
תוכן זה אינו זמין עדיין בשפה שלך.
Cannot rebind a class-body-declared list or dict. Mutate elements via index or key writes instead.
What it means
A persistent-state list or dict slot is set up once at warmup, and re-applied at the start of every walk-forward window. Inside execute() the contract is mutate, not re-assign: index writes (self.vals[i] = …) and key writes (self.counts[k] = …) update the slot’s contents, whereas re-assignment would throw the buffer away and build a fresh one on every bar.
The same rule covers augmented assignment applied to the slot itself — self.vals += … is a rebind, not an element update.
Why it happens
class Bad(Strategy): trade = Symbol() sizing = FixedCapital() nq_highs = [0.0]*5
def execute(self): self.nq_highs = [1.0, 2.0, 3.0, 4.0, 5.0] # ❌ re-assignment in execute() if self.trade.is_flat: self.buy(self.trade)This is nearly always a bug. The author believes the buffer persists across bars; the rebind silently resets it every bar.
How to fix it
Mutate through the subscript:
class Good(Strategy): trade = Symbol() sizing = FixedCapital() nq_highs = [0.0]*5
def execute(self): # Shift the buffer left, then write the newest high at the right edge. for i in range(4): self.nq_highs[i] = self.nq_highs[i+1] self.nq_highs[4] = self.trade.high
if self.trade.close > self.nq_highs[0] and self.trade.is_flat: self.buy(self.trade, reason="Break above the 5-bar high")To clear the buffer back to a known state, do it element by element:
class Resettable(Strategy): trade = Symbol() sizing = FixedCapital() nq_highs = [0.0]*5
def execute(self): if self.trade.is_flat and self.bar_count > 1000: for i in range(5): self.nq_highs[i] = 0.0 # ✅ element-by-element resetScalars are different
Re-assigning scalar state IS allowed:
class ScalarOK(Strategy): trade = Symbol() sizing = FixedCapital() up_count = 0
def execute(self): self.up_count = 0 # ✅ scalar re-assignment is fine if self.trade.close > self.trade.open: self.up_count = self.up_count + 1The asymmetry is deliberate. self.scalar = value has one unambiguous meaning; self.list = [...] mid-execute() almost always means the author forgot the buffer was supposed to survive the bar.
Related
- Persistent State
- For Loops — the loop-plus-subscript idioms this rule pushes you toward.
RC2_ASSIGN_LHS— writingself.x[i] = …whenxis a scalar, or was never declared.RC2_STATE_AUGASSIGN_UNINIT— augmented assignment on a slot that does not exist yet.