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

RC2_ASSIGN_LHS

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

Assignment must target a single local name or a single self.xxx. Tuple unpacking is not supported.

What it means

An assignment in execute() (or in a helper) has a left-hand side the transpiler can’t turn into one storage slot. There are exactly three legal targets: a local name (x = …), a scalar state slot (self.x = …), and an element of a class-body collection (self.x[i] = … / self.x[k] = …). Anything else — unpacking into several names, chained targets, a subscript into something that isn’t a declared list or dict — has no single slot to write to, so it is refused rather than guessed at.

Why it happens

The most common shape is tuple unpacking, which reads as one statement but is really two writes:

class Bad(Strategy):
trade = Symbol()
sizing = FixedCapital()
def execute(self):
high, low = self.trade.high, self.trade.low # ❌ — two targets, one statement
if self.trade.is_flat:
self.buy(self.trade)

Chained targets (a = b = 0) are refused for the same reason.

Subscript writes into an undeclared slot

self.x[i] = … requires x to be declared as a list or dict in the class body. There is no execute()-side discovery for collections — a bare first write carries no element type, so there is nothing to declare from:

class Bad2(Strategy):
trade = Symbol()
sizing = FixedCapital()
def execute(self):
self.recent_highs[0] = self.trade.high # ❌ — recent_highs was never declared
if self.trade.is_flat:
self.buy(self.trade)

The same diagnostic fires when the slot exists but is a scalar: with last_high = 0.0 in the class body, self.last_high[0] = … is “subscript assignment is only valid on lists and dicts.”

How to fix it

One target per assignment; declare collections in the class body and write them by index or key.

class Good(Strategy):
trade = Symbol()
sizing = FixedCapital()
recent_highs = [0.0]*5
def execute(self):
high = self.trade.high # ✅ one name per statement
low = self.trade.low
for i in range(4): # ✅ index write into a declared list
self.recent_highs[i] = self.recent_highs[i+1]
self.recent_highs[4] = high
if high - low > 0 and self.trade.is_flat:
self.buy(self.trade)

Two near misses

Both of these look like RC2_ASSIGN_LHS and are not:

  • self.capital = 100000 — capital is a computed strategy property, not a slot you own. Assigning to it is RC2_STATE_RESERVED, and the same goes for initial_capital, bar_count, and ready.
  • self.stop_loss = 2.0 — this is not an error at all, which is the trap. stop_loss is a method, and assigning to the name quietly creates an unrelated persistent-state slot called stop_loss while your stop is never set. Call it instead: self.stop_loss(2.0). See Exit Rules.