Reference

Entry & exit logic

How entries, exits, stops and targets are evaluated.

A trade has two halves: the conditions that open it, and everything that closes it, exit conditions, stops, targets and trailing logic. This page covers both, plus how you size the position and bring in custom data.

Entry & exit conditions#

Entries and exits are built from indicator, price and pattern conditions. Combine them with AND / OR, or run them in sequence with then.

text
Buy when RSI crosses above 50 AND price breaks the swing high, for BTC 1D
text
Buy BTC when the 12 EMA crosses above the 21 EMA, then price retests the 21 EMA, 4H last 90 days
text
Buy BTC when RSI is higher than it was 5 bars ago, exit when it's lower, 4H last 90 days
Sequential entries

The then in the second query makes the entry sequential: the EMA cross must come first and the retest must follow, in that order, not on the same bar. Each step waits up to 50 bars for the next one by default; add within N bars to set the window, or the sequence resets. See combining conditions.

Stops & targets#

ControlExample
Stop lossSL 2%, SL 1.5 ATR, stop 1R, at entry candle low
Take profitTP 5%, TP 3RR, take half at 2%
Trailingtrail by 1.5 ATR, trailing stop 3% (activate at 1%)
Stop planmove to breakeven at 1R, then trail 1 ATR at 2R
Partial in / outpartial exit 50% at 1R, remainder at 2R
Channel exitexit on a new 20-bar low, close on a new N bar high/low (Donchian style)

Position sizing#

ModeExample
Risk basedrisk 1% of equity per trade with a 2% stop
% of equityuse 10% of equity per trade
Fixed units0.05 BTC per trade
Fixed notional$5,000 per trade
Leverage3× leverage
Buy BTC when RSI > 30, SL 2 ATR, TP 3RR, risk 1% per trade, 4H last 120 daysRun in terminal

Order execution#

By default an entry fills at the close of the signal bar (see the execution model). You can also rest a limit order: it waits for price to come to a level and fills on a later bar if it's touched, expiring after a set number of bars. Or rest a stop order: it waits for price to trade through a level, the breakout entry.

ModeExample
Market (default)fills at the signal bar's close
Limitplace a limit buy at the 20 EMA, expire after 5 bars
Stopbuy stop at the high of the signal candle, valid for 3 bars
Three fill models, honestly

The engine models market, limit and stop fills. A limit fills at its price, or at the bar's open when the bar gaps through it in your favour. A stop fills at its level, or at the open when the bar gaps past it, so the gap is paid, never collected, and the fill is charged as a taker. Phrasings that imply a next bar open resolve to the market fill, the docs don't promise an order type the engine doesn't run.

Stop entries#

A buy stop rests above the market and fills when a later bar trades up to it; a sell stop rests below and fills when a bar trades down to it. The level is fixed on the signal bar's close, from data that bar already has.

LevelExample
Signal candlebuy stop at the high of the signal candle, sell stop at its low
Previous candlebuy stop at the previous candle's high
Beyond a candlebuy stop 0.2% above the signal candle high, sell stop 0.5 ATR below the previous candle's low
Off the closebuy stop 1% above the close (a stop at the close needs an offset, it is already touched)
Fixed pricebuy stop at 65000
Moving averagebuy stop at the 20 EMA; an SMA or a VWAP works the same way, with its period
Previous daybuy stop at the previous day's high: on a daily chart that is the previous candle, on an intraday chart the previous day's high
Forex pipsbuy stop 10 pips above 1.0850, pips off a fixed price only

The order is valid for the next bar only. Say valid for 5 bars to keep it working longer, or until cancelled to leave it open until a new signal replaces it. A fresh signal on either side always cancels the resting order and places its own.

Already through the level

If the signal bar closes beyond the stop (a buy stop below the close), the stop has triggered the moment it was placed, so it fills at the next bar's open. The run warns once and counts those orders. A close exactly at the level has not traded through it; that order rests.

What a stop entry refuses
  • A stop at an N bar high or low (buy stop at the 20 day high): there is no rolling window level for a stop to rest at. Write the breakout as the entry condition instead, close crosses above the highest high of the previous 20 bars, which enters at that bar's close.
  • Pips off a candle level (2 pips above the signal candle high): a stop adds only a percent or an ATR multiple to a candle. Say 0.1% above, or use a fixed price.
  • Points, ticks or cents as the offset: the engine knows a pip size for forex pairs only. One tick above a high is read as the high itself.
  • Stop limit orders: the limit a stop turns into once triggered is not modelled.
  • Stop entries with pyramiding adds or a scale in ladder: those legs fill at the bar close, so the combination is refused rather than half applied.
  • A strategy that trades both sides needs the same kind of level on each (both at the signal candle, or both at the previous candle, with the same offset).
The other side's stop is your stop loss

In a long only strategy a sell stop below the entry is read as the trade's stop loss, not as a short entry (and a buy stop above the entry in a short only one). place a sell stop at the swing low gives a stop loss at the swing low. It takes a percent, an ATR multiple, forex pips, the entry or signal candle, the swing, an N bar or previous day level, or a price. A level on the profit side of the entry is refused, since it would close every trade at once.

Event windows#

A single condition can require that something happened recently, not necessarily on this exact bar: "X within the last N bars", optionally "at least / at most K times". This widens when a condition counts as met: distinct from the sequential then within N bars, which orders two separate steps.

text
Buy BTC when RSI crossed above 30 within the last 10 bars, 4H last 90 days

Performance gates#

The strategy's own live performance is available as a condition, just like an indicator. Five runtime metrics are computed bar by bar from the equity curve of the run itself, so a query can gate its entries on how the strategy has been doing:

MetricMeaning
rolling performance% return of the strategy over the last 30 bars
rolling drawdown% of equity below its 30 bar peak (0 at highs, negative under water)
rolling sharpe / rolling sortinoAnnualized risk adjusted return over the last 30 bars
equityCurrent account equity in $
text
Buy BTC when RSI crosses above 50, but only trade if performance is above 0%, 4H last 180 days
text
Buy when price breaks the swing high, only if drawdown is better than -10%, for ETH 1D

For hard cutoffs rather than bar by bar gates, use the risk guards: stop trading if drawdown exceeds 20%, stop after 3 consecutive losses, stop for the day after losing 5%, max 2 trades per day, wait 5 bars between trades.

Gates can lock themselves out

While a gate blocks entries the equity curve goes flat, and after 30 flat bars rolling performance settles at exactly 0. A strictly positive threshold (above 0%) then never rearms and the strategy stays shut off for the rest of the run. Give the gate a way back in: use a slightly negative threshold (above -2%), or gate on drawdown, which rearms as the window rolls past the old peak.

What the metrics measure

Runtime metrics track the strategy's actual equity, including only trades that were really taken. The rolling window is fixed at 30 bars of the query's timeframe. They are not a per signal track record: "only take this signal if it was profitable the last 3 times it fired" is a different concept and isn't part of a gate. To study a single condition's historical outcomes, use the probability scan in analysis.

Custom indicators & @tags#

Bring your own series from CSV columns or Pine. Tag them with @"Column" and align the timeframe in the UI. You can combine several custom series in one query.

text
Long when @"fast" crosses above @"slow", SL 2% TP 3RR, for BTC 4H last 60 days
Strict mode

When strict mode is on, a custom query requires @ tags, a data source, and a parsed custom condition, so a typo can't silently fall back to a built in indicator.