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

For Loops

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

for loops in execute() and in helper methods support three shapes: range(...) iteration, list iteration, and dict-key iteration.

class Demo(Strategy):
trade = Symbol()
sizing = FixedCapital()
recent_highs = [0.0]*5
counts = {"up": 0, "down": 0}
total = 0.0
def execute(self):
# Integer ranges
for i in range(5): # 0..4
self.total = self.total + self.recent_highs[i]
for i in range(2, 5): # 2..4
self.total = self.total + 1
# List iteration — yields each element
for h in self.recent_highs:
self.total = self.total + h
# Dict iteration — yields each KEY (Python default)
for k in self.counts:
self.total = self.total + self.counts[k]

range(n) / range(start, stop)

Two argument forms. start defaults to 0; both are exclusive on the upper bound.

class Shift(Strategy):
trade = Symbol()
sizing = FixedCapital()
recent_highs = [0.0]*5
def execute(self):
for i in range(4): # i = 0, 1, 2, 3
self.recent_highs[i] = self.recent_highs[i+1]
self.recent_highs[4] = self.trade.high

The three-argument range(start, stop, step) is not supported — it raises RC2_FOR_RANGE. For a non-unit step, index arithmetic inside a unit-step loop does the same job.

range(...) is legal only as a for-loop’s iterable. r = range(3) on its own is refused.

Iterating a list

for x in self.<list>: yields each element. The loop variable is a fresh local; its type matches the list’s element type.

class Sum(Strategy):
trade = Symbol()
sizing = FixedCapital()
samples = [0.0, 1.5, 2.25, 3.125, 4.0]
total = 0.0
def execute(self):
self.total = 0.0
for x in self.samples:
self.total = self.total + x
if self.total > 10 and self.trade.is_flat:
self.buy(self.trade)

Iterating a dict

for k in self.<dict>: yields each key (a string). Pair it with self.<dict>[k] to read the value.

class CountAggregate(Strategy):
trade = Symbol()
sizing = FixedCapital()
counts = {"up": 0, "down": 0, "doji": 0}
total = 0
def execute(self):
self.total = 0
for k in self.counts:
self.total = self.total + self.counts[k]
if self.total > 100 and self.trade.is_flat:
self.buy(self.trade)

.items(), .keys(), and .values() are not supported. Use the key-then-lookup pattern above.

len()

len(self.<list>) and len(self.<dict>) return the element count as an int:

class Sizes(Strategy):
trade = Symbol()
sizing = FixedCapital()
recent_highs = [0.0]*5
counts = {"up": 0, "down": 0, "doji": 0}
def execute(self):
n = len(self.recent_highs) # 5
seen = len(self.counts) # 3
if n + seen > 0 and self.trade.is_flat:
self.buy(self.trade)

len() is supported only on persistent-state lists and dicts — not on strings, locals, or other expressions. Anywhere else it raises RC2_BUILTIN_ARG.

Rolling-window idiom

The canonical use: shift the buffer left, write the newest value at the right edge.

class RollingHigh(Strategy):
trade = Symbol()
sizing = FixedCapital()
recent_highs = [0.0]*5 # 5-bar rolling high buffer
def execute(self):
for i in range(4):
self.recent_highs[i] = self.recent_highs[i+1]
self.recent_highs[4] = self.trade.high
# Compare against the oldest value still in the window
if self.trade.close > self.recent_highs[0] and self.trade.is_flat:
self.buy(self.trade, reason="Break above the 5-bar high")

Loop-variable scope

The loop variable is a local declared by the for statement, and it is not persistent state — it resets on every bar. Reading it after the loop gives its last value, but write a separate named local if you actually need the final index; relying on loop-variable leakage is the kind of thing that reads as a bug on the next pass.

What’s not supported

  • range(start, stop, step) (the three-argument form)
  • while loops
  • break / continue
  • for … else clauses
  • enumerate(), zip(), reversed(), sorted() — all blocked builtins (SDK012)
  • .items() / .keys() / .values() on dicts
  • len() on anything other than a persistent-state list or dict

Common diagnostics

Code What it means
RC2_FOR_TARGET The loop variable isn’t a simple name.
RC2_FOR_ITER The iterable isn’t range(...) or a persistent-state list / dict.
RC2_FOR_RANGE range() called with the wrong number of arguments.
RC2_BUILTIN_ARG len(...) called with an unsupported argument.
SDK012 A blocked builtin (map, filter, enumerate, …).