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

Quickstart

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

Build, backtest, and read the results of your first RaamCode strategy. Five minutes end to end.

1. The strategy

We’ll write a moving-average crossover — buys when a fast moving average crosses above a slow one, exits when it crosses back below. The classic “golden cross.”

class MACross(Strategy):
"""Golden-cross trend follower."""
fast = Param(7, min=2, max=50)
slow = Param(21, min=10, max=200)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
fast = SMA(self.fast, on=self.trade)
slow = SMA(self.slow, on=self.trade)
self.stop_loss(2.0)
if fast.crossed_above(slow) and self.trade.is_flat:
self.buy(self.trade, reason="Bullish crossover")
if fast.crossed_below(slow) and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="Bearish crossover")

2. Line by line

Class header

class MACross(Strategy):
"""Golden-cross trend follower."""

Every strategy is a class that inherits from Strategy. The class name is what appears in the strategy catalog. The docstring is the catalog description — keep it short and human.

Parameters

fast = Param(7, min=2, max=50)
slow = Param(21, min=10, max=200)

Each Param() is a tunable value with a default and a valid range. min/max are hard bounds — the platform rejects anything outside them at compile time. These same params drive the optimizer: it sweeps fast from 2–50 and slow from 10–200 to find the configuration with the best fit.

More on Param() →

Symbol slot

trade = Symbol()

A Symbol() is a placeholder for “the instrument the subscriber will pick.” When somebody deploys this strategy, they bind a real ticker (SPY, AAPL, TA35) to trade. The strategy itself doesn’t know or care.

More on Symbol() →

Sizing model

sizing = FixedCapital()

How each self.buy() sizes its position. FixedCapital() means “use 100% of starting capital.” Other options: FixedQuantity(n) (always n contracts) or Compounding() (use 100% of current equity, so winners grow your position).

sizing is required — every strategy must declare one.

More on sizing models →

Per-bar logic

def execute(self):
fast = SMA(self.fast, on=self.trade)
slow = SMA(self.slow, on=self.trade)
...

execute() runs once per bar after warmup completes. Inside, you declare your indicators at the top — the transpiler hoists them so they receive every bar’s data, not just the ones where your if branch fires.

More on indicators →

Exit rule

self.stop_loss(2.0)

A 2% stop loss on every position. Exit rules are function calls, not assignments. They’re checked tick-by-tick, not just on bar boundaries — your stop fires the moment the price touches it.

More on exit rules →

Entry signal

if fast.crossed_above(slow) and self.trade.is_flat:
self.buy(self.trade, reason="Bullish crossover")

Two conditions both have to be true: the fast SMA just crossed above the slow one on this bar, and you’re not already in a position. If they are, place a market buy. The first argument is always the symbol slot. The reason string is saved with the order and shows up in your trade log.

Exit signal

if fast.crossed_below(slow) and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="Bearish crossover")

Exit verbs (sell, buy_to_cover) require an explicit quantity. self.trade.position is “everything I currently hold.” You can also exit half (self.trade.position / 2) or a fixed number (50).

3. Run it

In Raamtrade:

  1. Open Workspaces → New strategy.
  2. Paste the code above into the editor. Diagnostics light up the moment you stop typing — green means the strategy is ready.
  3. Pick a ticker (try SPY) and a date range (try the last two years).
  4. Click Backtest.

The result appears as an equity curve, a list of every trade, and summary metrics (return, drawdown, Sharpe).

4. Try the optimizer

Once a baseline backtest succeeds, click Optimize. The platform sweeps fast and slow across their min–max ranges and returns the best-performing combinations. Because fast and slow are already Param() declarations, no extra setup is needed.