Workflows

This page walks through four complete strategy configurations — from simple to complex — using only default tokens and custom tokens you connect from standard indicators. Each example includes all required YAML fields...

Written By Axiom Admin

Last updated About 1 month ago

Workflows

This page walks through four complete strategy configurations — from simple to complex — using only default tokens and custom tokens you connect from standard indicators. Each example includes all required YAML fields and can be pasted directly into the strategy inputs (assuming the listed custom tokens are connected). None of them are trading recommendations. They are teaching tools designed to show how the YAML and expression system work together at increasing levels of depth.

Start at the level that matches where you are. If you are new to the tool, start with Beginner and work forward. Each level builds on the concepts from the previous one.

For the complete list of available tokens, see Default Tokens. For expression syntax, see Expression Reference. For every YAML field and its purpose, see YAML Reference.


Beginner — Single crossover with fixed exits

What this teaches: The simplest possible working strategy. One entry, one take profit, one stop loss. No setups (uses GLOBAL). Market orders only. This is your first honest run — the goal is to confirm the engine is reading your rules, not to produce a profitable backtest.

Custom tokens needed:

Token name

Type

Source

EMA_50

Number

50-period EMA indicator on your chart

Long Entries

Example
- entry_name: EMA_CROSS_LONG entry_gate_condition: PRICE_CLOSE > 0 entry_trigger_when: CROSSOVER(PRICE_CLOSE, EMA_50) entry_order_type: MARKET entry_allocation_percent: 100

Long Take Profits

Example
- take_profit_name: TP_FIXED take_profit_gate_condition: PRICE_CLOSE > 0 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE * 1.03 take_profit_lock_prices: true

Long Stop Losses

Example
- stop_loss_name: SL_FIXED stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE * 0.98 stop_loss_lock_prices: true

What is happening

The entry fires when price crosses above the 50 EMA. The gate is always-true (PRICE_CLOSE > 0), which satisfies the required field without adding a real filter. It belongs to GLOBAL (no belongs_to_setup), so it evaluates every bar without any setup gating. The allocation is 100% — the full Properties tab default position size. One-shot is the default, so it fires once and then waits for a position cycle reset before it can fire again.

The take profit places a limit order at 3% above the average entry price. The stop loss places a stop order at 2% below entry. Both prices are latched — they are calculated once when the orders are placed and held constant.

This produces a 1.5:1 reward-to-risk ratio (3% target vs. 2% stop). That ratio is a design choice — it means the strategy can be profitable with a win rate below 50% if the winners are consistently larger than the losers. Whether that holds depends entirely on the market and the EMA's ability to identify favorable crossover points.

What to verify

  1. Set direction to Long Only and check the consent box.

  2. Enable the schema summary table. You should see: 0 setups, 1 entry, 1 take profit, 1 stop loss under Long.

  3. Enable expression diagnostics. Look for EMA_CROSS_LONG trigger showing EVAL status.

  4. Check the trade list. Trades should appear with entries at crossover points and exits at the TP or SL level.

  5. Run the slippage sensitivity test (0, 5, 10, 15 ticks). If the strategy is only profitable at 0 slippage, the edge is in the fill model, not in the rules.

What to explore next

  • Change the EMA period (swap EMA_50 for a different indicator) and observe how trade frequency and win rate change.

  • Adjust the TP and SL percentages. A tighter stop (1%) with a wider target (5%) changes the character of the strategy entirely.

  • Add a volume condition to the entry trigger: CROSSOVER(PRICE_CLOSE, EMA_50) && VOLUME > VOLUME[1].


Intermediate — Trend-gated entries with scaled exits

What this teaches: Named setups with confirmation. Entry gating on a confirmed regime. A two-leg take profit ladder. Entry-level confirmation. This is where the tool starts showing its depth.

Custom tokens needed:

Token name

Type

Source

EMA_200

Number

200-period EMA

EMA_20

Number

20-period EMA

RSI_K

Number

14-period RSI

Long Setups

Example
- setup_name: UPTREND setup_gate_condition: BAR_INDEX > 200 setup_active_when: PRICE_CLOSE > EMA_200 setup_confirm_count: 3 setup_cancel_when: PRICE_CLOSE < EMA_200 setup_cancel_confirm_count: 2 setup_cooldown_bars: 5

Long Entries

Example
- entry_name: PULLBACK_ENTRY entry_belongs_to_setup: UPTREND entry_gate_condition: RSI_K < 40 entry_trigger_when: CROSSOVER(PRICE_CLOSE, EMA_20) entry_confirm_count: 1 entry_order_type: MARKET entry_allocation_percent: 100

Long Take Profits

Example
- take_profit_name: TP_PARTIAL take_profit_belongs_to_setup: UPTREND take_profit_gate_condition: POSITION_PROFIT_PERCENT > 1 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE * 1.03 take_profit_lock_prices: true take_profit_allocation_percent: 50 - take_profit_name: TP_RUNNER take_profit_belongs_to_setup: UPTREND take_profit_gate_condition: POSITION_PROFIT_PERCENT > 2 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE * 1.06 take_profit_lock_prices: true take_profit_allocation_percent: 50

Long Stop Losses

Example
- stop_loss_name: SL_INITIAL stop_loss_belongs_to_setup: UPTREND stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE * 0.97 stop_loss_lock_prices: true

What is happening

The setup creates a trading window called UPTREND. It requires price to hold above the 200 EMA for 3 consecutive bars before confirming. The gate condition BAR_INDEX > 200 prevents evaluation on the first 200 bars, giving the EMA enough history to warm up. When price drops below the 200 EMA for 2 bars, the setup cancels and enters a 5-bar cooldown.

The entry only evaluates when UPTREND is CONFIRMED. Within that window, it waits for RSI to pull back below 40 (gate), then triggers on a crossover above the 20 EMA with 1-bar confirmation. Allocation is 100% — the full Properties default position size. This is a classic pullback entry: enter the trend after a dip, not at the first sign of strength.

The exits form a two-leg ladder. TP_PARTIAL closes 50% of the position at 3% profit. TP_RUNNER closes the remaining 50% at 6% profit. Both use gate_condition to require the position to be in profit before their orders activate. The stop loss sits at 3% below entry. All exits set belongs_to_setup: UPTREND so they target only entries from this setup.

The combined exit profile: risk 3% to make 3% on half and 6% on the other half. The blended TP is 4.5%. The reward-to-risk is 1.5:1 on the blended profile.

What to verify

  1. Schema summary should show: 1 setup, 1 entry, 2 take profits, 1 stop loss under Long.

  2. Expression diagnostics should show UPTREND-related conditions. Watch for the setup state tokens: UPTREND_INACTIVE, UPTREND_ACTIVE, UPTREND_CONFIRMED.

  3. Scroll to a bar where the 200 EMA is trending up. Confirm the setup reaches CONFIRMED after 3 bars above the EMA.

  4. Find a pullback where RSI drops below 40 and then price crosses back above the 20 EMA. That should be an entry point.

  5. Check the trade list: partial exits at 3% and runner exits at 6% (or stop exits at 3% for losing trades).

The key concept

The setup separates "is the environment right?" from "should I enter now?" This is the most important structural lesson in the tool. Without the setup, the pullback entry would fire in downtrends, sideways markets, and during the first 200 bars when the EMA has not stabilized. The setup filters all of that away, leaving only entries in confirmed uptrends after pullbacks.


Advanced — Multi-setup, multi-entry with OCA groups

What this teaches: Multiple setups running simultaneously. Two alternative entry strategies in an OCA group (first one wins). Entry pyramiding. Exit targeting by entry ID. Setup cross-referencing in entry gates.

Custom tokens needed:

Token name

Type

Source

EMA_200

Number

200-period EMA

EMA_50

Number

50-period EMA

BB_UPPER

Number

Bollinger Band upper (20-period, 2 std dev)

BB_LOWER

Number

Bollinger Band lower

RSI_K

Number

14-period RSI

ATR_14

Number

14-period ATR

Long Setups

Example
- setup_name: MACRO_TREND setup_gate_condition: BAR_INDEX > 200 setup_active_when: PRICE_CLOSE > EMA_200 && EMA_50 > EMA_200 setup_confirm_count: 5 setup_cancel_when: PRICE_CLOSE < EMA_200 && EMA_50 < EMA_200 setup_cancel_confirm_count: 3 setup_close_on_cancel: true setup_cooldown_bars: 10 - setup_name: VOLATILITY_EXPANSION setup_active_when: ATR_14 > ATR_14[20] * 1.2 setup_confirm_count: 2 setup_cancel_when: ATR_14 < ATR_14[20] * 0.8

Long Entries

Example
- entry_name: BB_BOUNCE entry_belongs_to_setup: MACRO_TREND entry_gate_condition: VOLATILITY_EXPANSION_CONFIRMED && RSI_K < 35 entry_trigger_when: CROSSOVER(PRICE_CLOSE, BB_LOWER) entry_order_type: MARKET entry_allocation_percent: 40 entry_id: MEAN_REVERT entry_oca_group: PRIMARY_ENTRY - entry_name: BREAKOUT_LONG entry_belongs_to_setup: MACRO_TREND entry_gate_condition: VOLATILITY_EXPANSION_CONFIRMED && RSI_K > 50 entry_trigger_when: PRICE_HIGH > HIGHEST(PRICE_HIGH[1], 20) entry_order_type: MARKET entry_allocation_percent: 40 entry_id: BREAKOUT entry_oca_group: PRIMARY_ENTRY - entry_name: CONTINUATION_ADD entry_belongs_to_setup: MACRO_TREND entry_gate_condition: POSITION_ACTIVE && POSITION_PROFIT_PERCENT > 1 entry_trigger_when: CROSSOVER(PRICE_CLOSE, EMA_50) entry_order_type: MARKET entry_allocation_percent: 20 entry_one_shot: false entry_pyramiding_max_adds: 2 entry_id: CONTINUATION

Long Take Profits

Example
- take_profit_name: TP_MEAN_REVERT take_profit_belongs_to_setup: MACRO_TREND take_profit_from_entry_id: MEAN_REVERT take_profit_gate_condition: PRICE_CLOSE > 0 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 2 take_profit_lock_prices: true take_profit_allocation_percent: 100 - take_profit_name: TP_BREAKOUT_PARTIAL take_profit_belongs_to_setup: MACRO_TREND take_profit_from_entry_id: BREAKOUT take_profit_gate_condition: POSITION_PROFIT_PERCENT > 2 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 3 take_profit_lock_prices: true take_profit_allocation_percent: 60 - take_profit_name: TP_BREAKOUT_RUNNER take_profit_belongs_to_setup: MACRO_TREND take_profit_from_entry_id: BREAKOUT take_profit_gate_condition: POSITION_PROFIT_PERCENT > 3 take_profit_trigger_when: CROSSUNDER(RSI_K, 65) take_profit_order_type: MARKET take_profit_allocation_percent: 40 - take_profit_name: TP_CONTINUATION take_profit_belongs_to_setup: MACRO_TREND take_profit_from_entry_id: CONTINUATION take_profit_gate_condition: PRICE_CLOSE > 0 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 1.5 take_profit_lock_prices: true

Long Stop Losses

Example
- stop_loss_name: SL_MEAN_REVERT stop_loss_belongs_to_setup: MACRO_TREND stop_loss_from_entry_id: MEAN_REVERT stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 1.5 stop_loss_lock_prices: true - stop_loss_name: SL_BREAKOUT stop_loss_belongs_to_setup: MACRO_TREND stop_loss_from_entry_id: BREAKOUT stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 2 stop_loss_lock_prices: true - stop_loss_name: SL_CONTINUATION stop_loss_belongs_to_setup: MACRO_TREND stop_loss_from_entry_id: CONTINUATION stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 1 stop_loss_lock_prices: true

What is happening

Two setups run independently. MACRO_TREND confirms when price and the 50 EMA are both above the 200 EMA for 5 bars — a strong structural uptrend. VOLATILITY_EXPANSION confirms when ATR is 20% above its 20-bar average — the market is active enough to trade.

Three entries serve different purposes:

  • BB_BOUNCE is a mean-reversion entry: buy the Bollinger Band lower touch when RSI is oversold and volatility is expanding. This is a counter-move entry within the trend.

  • BREAKOUT_LONG is a momentum entry: buy the 20-bar high breakout when RSI confirms strength and volatility is expanding. This is a with-trend continuation.

  • Both share the OCA group PRIMARY_ENTRY, which means whichever fires first cancels the other. You get one or the other on any given setup activation, not both. This prevents conflicting entries.

  • CONTINUATION_ADD is a pyramid entry that only fires when a position is already open and profitable. It allows up to 2 additional adds at smaller size (20% vs. 40% of the default position size) on EMA crossovers. It is not in the OCA group — it works alongside whichever primary entry won.

All three entry allocations sum to 100% (40% + 40% + 20%), which is required by the validator. Since the OCA entries are mutually exclusive, at most 40% + 20% of the default position size is used in practice (the primary entry plus potential adds).

Targeted exits are the key structural feature. Each entry group has its own exit logic:

  • The mean-reversion entry gets a tight 2 ATR TP (it is a counter-move, so expectations are modest) and a 1.5 ATR stop.

  • The breakout entry gets a wider 3 ATR TP in two legs (60/40 split) and a 2 ATR stop (breakouts need room).

  • The continuation adds get a 1.5 ATR TP and a tight 1 ATR stop (smaller size, tighter control).

The key concept

This strategy demonstrates separation of concerns. Each entry type has different market assumptions, different sizing, and different exit profiles. The OCA group prevents conflicting entries. The from_entry_id fields route exits to the correct trades. The setup cross-reference (VOLATILITY_EXPANSION_CONFIRMED in the entry gates) creates a composite regime requirement without combining everything into one giant setup.


Extreme — Full-spectrum regime engine with dynamic risk

What this teaches: Multiple cooperating setups with cross-references. Conditional stop tightening based on position performance. Time-based exit management. Cancel conditions on exits. Setup-level entry caps. The full depth of what the YAML/expression combination can express.

Custom tokens needed:

Token name

Type

Source

EMA_200

Number

200-period EMA

EMA_50

Number

50-period EMA

EMA_20

Number

20-period EMA

RSI_K

Number

14-period RSI

ATR_14

Number

14-period ATR

VOLUME_SMA

Number

20-period SMA of volume

Long Setups

Example
- setup_name: REGIME_BULL setup_gate_condition: BAR_INDEX > 200 && TF_ISDAILY setup_active_when: PRICE_CLOSE > EMA_200 && EMA_50 > EMA_200 && EMA_20 > EMA_50 setup_confirm_count: 5 setup_cancel_when: EMA_20 < EMA_50 && EMA_50 < EMA_200 setup_cancel_confirm_count: 3 setup_close_on_cancel: true setup_cooldown_bars: 15 setup_max_entries_per_activation: 5 setup_reset_when: STRATEGY_MAX_DRAWDOWN_PERCENT > 15 - setup_name: VOLATILITY_REGIME setup_active_when: ATR_14 > ATR_14[10] * 1.1 && ATR_14 < ATR_14[10] * 3.0 setup_confirm_count: 2 setup_cancel_when: ATR_14 < ATR_14[10] * 0.8 || ATR_14 > ATR_14[10] * 3.0 - setup_name: VOLUME_REGIME setup_active_when: VOLUME > VOLUME_SMA * 1.2 setup_confirm_count: 1 setup_cancel_when: VOLUME < VOLUME_SMA * 0.5 setup_cooldown_bars: 3

Long Entries

Example
- entry_name: PULLBACK_PRIME entry_belongs_to_setup: REGIME_BULL entry_gate_condition: VOLATILITY_REGIME_CONFIRMED && VOLUME_REGIME_CONFIRMED && RSI_K < 40 && STRATEGY_OPENTRADES < 3 entry_trigger_when: CROSSOVER(PRICE_CLOSE, EMA_20) && PRICE_CLOSE > EMA_50 entry_confirm_count: 1 entry_order_type: MARKET entry_allocation_percent: 40 entry_id: PRIME_GROUP entry_oca_group: ALPHA_ENTRY - entry_name: MOMENTUM_PRIME entry_belongs_to_setup: REGIME_BULL entry_gate_condition: VOLATILITY_REGIME_CONFIRMED && VOLUME_REGIME_CONFIRMED && RSI_K > 55 && RSI_K < 75 && STRATEGY_OPENTRADES < 3 entry_trigger_when: PRICE_HIGH > HIGHEST(PRICE_HIGH[1], 15) && VOLUME > VOLUME_SMA * 1.5 entry_order_type: MARKET entry_allocation_percent: 40 entry_id: PRIME_GROUP entry_oca_group: ALPHA_ENTRY - entry_name: ADD_ON_STRENGTH entry_belongs_to_setup: REGIME_BULL entry_gate_condition: POSITION_ACTIVE && POSITION_PROFIT_PERCENT > 1.5 && VOLATILITY_REGIME_CONFIRMED entry_trigger_when: CROSSOVER(PRICE_CLOSE, EMA_20) && RSI_K > 40 && RSI_K < 65 entry_order_type: MARKET entry_allocation_percent: 20 entry_one_shot: false entry_pyramiding_max_adds: 2 entry_id: ADD_GROUP

Long Take Profits

Example
- take_profit_name: TP_PRIME_QUICK take_profit_belongs_to_setup: REGIME_BULL take_profit_from_entry_id: PRIME_GROUP take_profit_gate_condition: POSITION_PROFIT_PERCENT > 1 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 2 take_profit_lock_prices: true take_profit_allocation_percent: 30 - take_profit_name: TP_PRIME_TARGET take_profit_belongs_to_setup: REGIME_BULL take_profit_from_entry_id: PRIME_GROUP take_profit_gate_condition: POSITION_PROFIT_PERCENT > 2 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 4 take_profit_lock_prices: true take_profit_allocation_percent: 40 - take_profit_name: TP_PRIME_RUNNER take_profit_belongs_to_setup: REGIME_BULL take_profit_from_entry_id: PRIME_GROUP take_profit_gate_condition: POSITION_PROFIT_PERCENT > 3 take_profit_trigger_when: CROSSUNDER(RSI_K, 65) take_profit_order_type: MARKET take_profit_allocation_percent: 30 - take_profit_name: TP_ADD_QUICK take_profit_belongs_to_setup: REGIME_BULL take_profit_from_entry_id: ADD_GROUP take_profit_gate_condition: PRICE_CLOSE > 0 take_profit_order_type: LIMIT take_profit_limit_price: POSITION_AVG_PRICE + ATR_14 * 1.5 take_profit_lock_prices: true take_profit_allocation_percent: 100

Long Stop Losses

Example
- stop_loss_name: SL_INITIAL stop_loss_belongs_to_setup: REGIME_BULL stop_loss_from_entry_id: PRIME_GROUP stop_loss_gate_condition: POSITION_PROFIT_PERCENT < 2 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 2.5 stop_loss_lock_prices: true stop_loss_allocation_percent: 100 - stop_loss_name: SL_TIGHTENED stop_loss_belongs_to_setup: REGIME_BULL stop_loss_from_entry_id: PRIME_GROUP stop_loss_gate_condition: POSITION_PROFIT_PERCENT >= 2 stop_loss_trigger_when: TRUE stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 1 stop_loss_lock_prices: true stop_loss_cancel_when: POSITION_PROFIT_PERCENT < 2 stop_loss_allocation_percent: 100 - stop_loss_name: SL_ADD stop_loss_belongs_to_setup: REGIME_BULL stop_loss_from_entry_id: ADD_GROUP stop_loss_gate_condition: PRICE_CLOSE > 0 stop_loss_order_type: STOP stop_loss_stop_price: POSITION_AVG_PRICE - ATR_14 * 1 stop_loss_lock_prices: true

What is happening

Three setups create a layered regime filter:

  1. REGIME_BULL is the structural trend filter — all three EMAs stacked bullish, with a hard reset if strategy drawdown exceeds 15%. The reset is a circuit breaker at the setup level: if the strategy is losing badly, clear all state and start fresh after cooldown. Entry cap of 5 per activation prevents over-trading within a single trend window. The gate requires a daily timeframe — this strategy is not designed for intraday.

  1. VOLATILITY_REGIME confirms that ATR is between 1.1x and 3.0x its recent average. Too low means no movement. Too high means chaos. The sweet spot is elevated but not extreme volatility.

  1. VOLUME_REGIME confirms above-average participation. Volume 20% above its moving average suggests real interest.

The entries require all three setups to be confirmed (REGIME_BULL via belongs_to_setup, the other two via gate cross-references). This means the strategy only enters when structure, volatility, and volume are all aligned.

  • PULLBACK_PRIME and MOMENTUM_PRIME are alternative entries in an OCA group — whichever fires first, the other cancels. One buys pullbacks (RSI oversold + EMA cross), the other buys breakouts (new highs on volume). Each allocates 40% of the Properties default position size.

  • ADD_ON_STRENGTH adds to winners: only fires when position is already profitable, allows 2 adds at 20% each. All three entries sum to 100% (40% + 40% + 20%) as required. Since the OCA entries are mutually exclusive, effective allocation is at most 40% (prime) + 20% + 20% = 80% of the default position size across all fills.

The exits demonstrate dynamic stop management:

  • SL_INITIAL is the wide stop — 2.5 ATR below entry. It is gated on POSITION_PROFIT_PERCENT < 2, meaning it only applies while the open position is still below a 2% unrealized gain.

  • SL_TIGHTENED replaces it once the open position reaches 2% unrealized profit (gated on >= 2). It tightens to 1 ATR below entry. The cancel_when condition hands control back to the wider stop if open profit drops back below that threshold.

  • This creates a graduated stop based on current open profit: wider protection early, tighter protection once the trade is working.

The three-leg TP on the prime entry scales out systematically: 30% at 2 ATR, 40% at 4 ATR, and the final 30% on an RSI signal (market order when RSI drops from above 65). The runner leg is not a fixed price — it is a conditional exit that waits for momentum to fade. This is how you let winners run without a fixed target.

The key concepts

  1. Setup cross-referencing — Entry gates check VOLATILITY_REGIME_CONFIRMED && VOLUME_REGIME_CONFIRMED. The setups run independently, but entries require all of them. This is modular regime composition.

  1. Strategy-aware logicSTRATEGY_OPENTRADES < 3 in the entry gates caps total exposure. STRATEGY_MAX_DRAWDOWN_PERCENT > 15 as a setup reset creates a portfolio-level circuit breaker.

  1. Position-aware exits — Stop tightening based on POSITION_PROFIT_PERCENT creates adaptive risk management. The stop is not fixed — it responds to how the open trade is performing right now.

  1. Conditional runners — The final TP leg uses a market order triggered by RSI rather than a fixed price. This is the difference between a static exit ladder and a dynamic one.

  1. Entry capssetup_max_entries_per_activation: 5 prevents the strategy from over-committing within a single trend window, even if conditions keep firing.

The honest warning

This configuration has many moving parts. Each interaction point — three setups cross-referencing each other, OCA groups, pyramiding, conditional stop tightening, graduated TPs — is a place where behavior can surprise you. Do not deploy something this complex without:

  1. Running the schema summary to confirm all items parsed correctly.

  2. Enabling expression diagnostics and verifying each setup's state transitions.

  3. Walking through individual trades in the trade list to confirm entries and exits are targeting correctly.

  4. Running the slippage sensitivity test.

  5. Testing on at least two different time windows.

Complexity is earned through understanding. If you cannot explain what every field in this configuration does and why it is set to that value, simplify until you can.


Building from here

These four examples demonstrate a progression from a single-condition entry to a full regime engine. The distance between them is not just more YAML — it is more understanding of what the tool can express and what the backtest can honestly evaluate.

A few principles for building your own:

  • Start simple. Every strategy should begin as a Beginner-level configuration. Get the core thesis working before adding complexity.

  • Add one thing at a time. Each new setup, entry, or exit should be tested in isolation before combining it with existing logic. Use the schema summary and expression diagnostics after every change.

  • Name everything clearly. Token-safe, descriptive names make diagnostics readable. TREND_PULLBACK_LONG is better than E1. You will thank yourself when debugging.

  • Test the failure modes. The backtesting checklist in Operating Checklist applies at every level. Slippage sensitivity, trade count, regime dependence — check them all.

  • Read the diagnostics, not just the equity curve. The equity curve is the summary. The diagnostics are the evidence. When the summary surprises you, the evidence will tell you why.

For the full build-test-iterate discipline, see Operating Checklist. For what can go wrong and how to diagnose it, see Troubleshooting.