# Rule-card strategies

> Every Strategy node in the workflow editor, field by field: the universe, indicators, rules, sizing, filters, the Program node, the Output and run parameters.

Source: https://orbitalaip.com/docs/backtesting/rule-card-strategies

> [!IMPORTANT] Disclaimer
> Backtest results are hypothetical and do not predict future performance. Nothing here is investment advice: Orbital computes the rules you supplied and recommends nothing. Orbital is not a registered investment adviser or broker-dealer. Costs are as modelled by the chosen cost profile and may differ from live trading.

## What a Rules strategy is

A Rules strategy is a workflow built from Strategy nodes: indicators feed rules, the rules chain into sizing, and the chain ends at an **Output**.

A graph with an **Entry Rule** or **Program** and an **Output** declaring symbol, action and asOf is a strategy once saved; see [Saving a strategy](https://orbitalaip.com/docs/backtesting/overview#saving-a-strategy-enrols-it).

[Your first strategy](https://orbitalaip.com/docs/getting-started/your-first-strategy) walks through a golden cross node by node.

## Where the nodes are

In the workflow editor's **Nodes** panel, the [rule cards](https://orbitalaip.com/docs/glossary#rule-cards) and **Program** sit in the **Strategy** section, **Input** under **Data Sources** and **Output** under **Core**.

Wire the chain **Entry Rule**, **Exit Rules**, **Position Sizing**, then **Output**. A backtest finds the **Input** and every rule, sizing and filter node by type. Only the first **Input**, **Position Sizing**, **Regime Filter** or **Risk Guard** node applies, and the run names any it ignored.

## Universe: the Input node

The **Input** node names what the strategy trades. Set **Source** to **Universe** (a screener candidate pool). A [universe](https://orbitalaip.com/docs/glossary#universe) holds at most 500 symbols.

- **Universe preset**: the list to trade. Two S&P 500 lists: the full index slice of 499 names, which is the default, and the top 129 by market cap, marked faster. Then **NASDAQ 100**, **Dow 30** and **Custom list (use field below)**. Orbital maintains the lists by hand, so they can lag recent index changes.

- **Custom tickers (preset = "Custom")**: your own tickers, separated by commas, read only with the custom list.

- **Exclude tickers already on watchlist (optional)**: a backtest ignores it and trades every ticker in the preset or custom list.

**Source** can instead be **Asset**, **Watchlist** or **Book**, and a backtest ignores **Subject source**; see [Set what a run works on](https://orbitalaip.com/docs/workflows/build-a-workflow#set-what-a-run-works-on).

## Indicator

An **Indicator** node computes one series over the bars you pick. Wire it into the rules that read it, or give it a **Reference name** and name it in a condition. An **Indicator** no rule reads is not computed, and the run says so.

- **Indicator**: the kind of series, **SMA** by default:

  - **SMA**, **EMA** (seeded with an SMA), **RSI** (with Wilder smoothing) and **ATR**, on any bars.

  - **Avg volume** (mean shares traded), **Rel volume** (today's shares divided by the average) and **Return over N bars** (percent change over the period), on daily bars only.

  - **Rel vol at time**: relative volume against this minute's own baseline, on 1-minute bars only. The period is fixed at 20 sessions.

- **Timeframe**: the bars it reads. **Daily bars** is the default. **Hourly bars**, **3-minute bars**, **2-minute bars** and **1-minute bars** are intraday.

- **Period (bars)**: the lookback window, in bars of the chosen timeframe, from 1 to 500. The default is 20.

- **Reference name**: the handle a condition uses, such as rsi14: a letter, then letters, numbers, underscores and hyphens, up to 32 characters. Leave it blank if the indicator is only wired.

An intraday [timeframe](https://orbitalaip.com/docs/glossary#timeframe) on any **Indicator** makes the whole strategy intraday. It then backtests on the minute tape and cannot be deployed to alerts.

## The Entry Rule node

An **Entry Rule** opens a position when its conditions hold at a bar close, and by default the order fills at the next bar's open; see [When trades happen](https://orbitalaip.com/docs/backtesting/when-trades-happen#one-bar-of-delay). Several **Entry Rule** nodes are alternatives: any one of them can open a position.

Wire **Indicator A** when the first value is the wired indicator, and **Indicator B** when the rule compares against a second indicator.

- **Rule name**: names the rule. Each trade records it, and the connector's [get_backtest_trades](https://orbitalaip.com/docs/claude-and-chatgpt/tools/get_backtest_trades) returns it as `source`, but the **Trades** tab has no column for it.

- **Direction**: **Buy (long)**, the default, or **Sell short**. A strategy that sells short needs **Margin account** on in the Run dialog, or the run is refused.

- **First value**: what the condition tests: **The wired indicator (input A)**, **The price** or **A fixed value**. The price adds a choice of **Close**, **Open**, **High** or **Low**.

- **Fires when the first value…**: **Crosses above**, **Crosses below**, **Is greater than**, **Is at or above**, **Is less than** or **Is at or below**.

- **Compare against**: **The second indicator (input B)**, **The price** or **A fixed value**. The price adds a **Price field**; a fixed value adds **Value**, the threshold, such as 30 for an RSI floor.

- **Fires when this is NOT true**: wraps the condition in a NOT. Not above the 200-day differs from below it on a bar sitting on the line, and on any bar the indicator has no value for.

- **The conditions below…**: how the rule joins all its conditions, the first one included: **ALL of them must hold**, the default, or **ANY one of them is enough**. **ANY** keeps the alternatives on one node under one **Rule name**.

- **And also…**: extra conditions. **Add condition** adds a row: a **NOT** toggle, what to test (an indicator by its **Reference name**, the price or a fixed number), a trigger and what to compare against. A row is saved once it is complete.

The panel reads the rule back as a sentence, such as **Buys when RSI(14) crosses below 30.**

## The Exit Rules node

An **Exit Rules** node says how positions close, with any combination of the exits below. Several **Exit Rules** nodes are alternatives: any one of them closes the position. A signal exit needs its indicators wired as an **Entry Rule** does; a stop, target or time stop needs none.

- **Signal exit** (the label goes on: **fires when the first value…**): **No signal exit** is the default. Its triggers and its other fields work as on the **Entry Rule**.

- **Stop loss**: **No stop loss**, **Percent below entry** or **ATR multiple below entry**.

- **Stop distance (%)**: with a percent stop, 10 by default.

- **ATR multiple** and **ATR period (bars)**: with an ATR stop, 2 and 14 by default. The distance is fixed at entry and does not widen as volatility moves.

- **Profit target (%)**, **Trailing stop (%)** and **Time stop (bars)**: blank for none. A trailing stop trails the best price seen; a time stop exits at the open after this many completed bars.

A strategy has one stop loss, one profit target, one trailing stop and one time stop. Two **Exit Rules** nodes that both set one are refused; keep it on one node. A strategy with no exits at all keeps every position open to the end of the run, and the run warns you. [When trades happen](https://orbitalaip.com/docs/backtesting/when-trades-happen#daily-strategies) covers how stops fill.

## The Position Sizing node

**Position Sizing** sets how big each position is; see [position sizing](https://orbitalaip.com/docs/glossary#position-sizing). The **Sizing method** decides what **Amount** means:

- **Percent of equity**, the default: percent of equity per position, 10 by default.

- **Risk percent (needs a stop)**: percent of equity risked per trade, against the stop distance. It needs a stop loss on **Exit Rules**; a trailing stop does not count.

- **Fixed share count** or **Fixed dollar amount**: shares or dollars per position.

- **The program decides, within a range (Code strategies)**: for a **Program** only. **Amount** gives way to **Smallest position (% of equity)**, default 25, and **Largest position (% of equity)**, default 100.

A strategy with no **Position Sizing** node sizes every position at 10% of equity, and the run warns you. The program-chosen range on a Rules strategy is refused.

## The Session Filter node

**Session Filter** has one field, **Session**, with one option: **Regular hours only (09:30–16:00 ET)**. Every backtest already trades regular hours only, so the node states the intent without changing the run.

## The Regime Filter node

**Regime Filter** gates every entry on a trend test of the symbol being traded: its own price against its own moving average of daily closes. It reads no index such as SPY, and needs no wires.

- **Only trade when**: **Price is above the moving average (uptrend)**, the default, or **Price is below the moving average (downtrend)**.

- **Moving average period (bars)**: a whole number from 2 to 500. The default is 200.

With a **Program** the filter does not apply, and the run says the node was ignored.

## The Risk Guard node

**Risk Guard** caps how many times one symbol may be entered on the same side. Its one field is **Max entries per symbol**: a whole number from 1 to 10, default 1. The value 1 opens once and never adds; 3 allows two adds. With a **Program** the guard does not apply.

## Program

A **Program** node replaces the **Entry Rule** and **Exit Rules** nodes with compiled Rust code; see [Program strategies](https://orbitalaip.com/docs/backtesting/program-strategies#the-program-card).

## The Output node

The **Output** node ends the chain and declares the signal columns.

1. **Wire it**
   
   Wire **Position Sizing** into the **Output**'s **Data** input.

2. **Untick the schema**
   
   In its settings, untick **Use upstream schema**.

3. **Add the columns**
   
   Click **Add column** three times. Name the columns symbol, action and asOf, with the types **string**, **string** and **timestamp**.

On the canvas the node then reads **Produces trade signals**. Orbital checks the three names, not their types.

## Parameters a run can vary

A parameter is one setting a backtest may change without editing the strategy. The same idea tested on daily bars and on 1-minute bars stays one strategy with one history. A strategy may declare up to 20.

The choices a parameter offers come from the last saved version of the graph. The workflow must already be a strategy, and the Backtesting app must be on in the project. Only project editors and above can add, edit or remove a parameter.

1. **Open the settings**
   
   Click **Workflow settings** (the gear) in the editor, then find **Parameters** in the **Workflow Settings** dialog.

2. **Pick a kind**
   
   Click **A bar to test on** or **A number to vary**. A strategy can have one bar parameter.

3. **Name it**
   
   **Name** is how runs and reports refer to it. **Label** is what the Run dialog calls it.

4. **Set its range**
   
   For a bar: **The bar this strategy is written in** (the indicators reading it are the ones a run retimes) and **Bars it may be tested on**. For a number: **The setting it changes**, **Lowest**, **Highest**, **Starting value** and **Whole numbers only**.

5. **Save it**
   
   Click **Add parameter**. The row shows its kind, **Bar** or **Number**, with **Edit** and **Remove**.

A number parameter offers only the settings its node currently uses. If the graph changes under a parameter, its row reads **No longer matches the graph** and offers **Fix**.

In the Run dialog, declared parameters appear under **This strategy’s settings**. Through the Orbital AI connector, Claude declares parameters when it saves a strategy and supplies values with [run_backtest](https://orbitalaip.com/docs/claude-and-chatgpt/tools/run_backtest). It can also declare a **Choice** parameter, a list of allowed values, which the editor lists with **Remove** but no **Edit**. See [Run a backtest](https://orbitalaip.com/docs/backtesting/run-a-backtest#the-strategys-settings) and [Versions and configurations](https://orbitalaip.com/docs/backtesting/versions#versions-and-configurations).
