Skip to content
ChartRiderDocs
Docs/WickScript/Writing strategies in WickScript
WickScript WickScript

Writing strategies in WickScript

How to write WickScript strategies you can backtest – entries, stops and targets in R, exits, partial exits, breakeven, trailing stops, tags, metrics and the Trade Setup conversion.

Updated ·Markdown

A strategy script is an indicator script that also trades. It starts with strategy "Name" instead of indicator "Name", and its enter, stop at, target at and exit statements become the trades of the backtest. Everything from the Language guide and the Indicators page works in strategies too – show, mark, level, hud, inputs and functions.

WickScript
wickscript 1
strategy "EMA cross" risk 1%
fast = ema(close, input 9 "Fast")
slow = ema(close, input 21 "Slow")
show fast as line "Fast" color amber
show slow as line "Slow" color blue
when fast crosses above slow
    tag "cross long"
    enter long at market
    stop at lowest(low, 10) - 2 * tick
    target at 2R
end
when fast crosses below slow
    tag "cross short"
    enter short at market
    stop at highest(high, 10) + 2 * tick
    target at 2R
end

The strategy line

strategy "Name" [risk <percent>] [leverage <number> | leverage auto] [cooldown <N> bars] [minR <N>R]
OptionMeaningWithout it
risk 1%share of the capital risked per trade; the position size follows from the distance between entry and stop1 %
leverage 5fixed leverage for every tradeleverage auto: the leverage of the strategy settings, otherwise the smallest leverage that allows the risk
cooldown 5 barscandles without new entries after a trade has closedno cooldown
minR 1.5Rskips entries whose target is closer than 1.5 × the riskno minimum

The options can come in any order. A leverage chosen as Step 1 / Step 2 parameter takes precedence over leverage. The checker also accepts fees … and capital …, but they currently have no effect – fees and starting capital are those of the backtest.

WickScript
wickscript 1
strategy "Options" risk 0.5% leverage 3 cooldown 5 bars minR 1.5R
when close crosses above ema(close, 50)
    enter long at market
    stop at lowest(low, 20)
    target at 3R
end

How the backtest trades a script

The script and the backtest run together, candle by candle. For each candle:

  1. Open position (from the candle after its entry): the stop is checked first, then the partial targets (the one closest to the entry first), then the target. If the stop and the target are both inside the candle, the stop counts.
  2. Pending limit or stop order (from the candle after it was placed): it fills when the price reaches it, expires after its valid candles, or – a limit order – is cancelled when the target is reached before the fill. In the fill candle the stop counts, the target doesn't.
  3. The script runs for this candle and sees the position as it stands after steps 1 and 2.
  4. At the candle's close: exits (exit … when …) close the position at the close price, stop moves (breakeven, trailing) are applied, and new entries are placed.

Further rules:

  • One position at a time. An entry while a position or a pending order exists, or during the cooldown, is skipped.
  • If a long and a short entry fire on the same candle, neither is taken.
  • Decisions are made only on closed candles; the still forming last candle never trades.
  • An entry is skipped when its levels are on the wrong side: a long needs stop < entry < target, a short the reverse.
  • The position size comes from risk and the stop distance, limited by the leverage. Entries whose stop is too tight for the leverage are skipped.
  • All prices of an entry – limit or stop price, stop-loss, target, partial targets, trailing distance – are calculated on the signal candle.

Entries

enter long|short [at market]
enter long|short at limit <price> [valid <N> bars]
enter long|short at stop <price> [valid <N> bars]
OrderFillsRules
at market (also just enter long)at the close of the signal candlestop and target are checked from the next candle
at limit <price>at the price, when the market reaches it, from the next candlea long limit must be below the close, a short limit above; cancelled if the target is reached first
at stop <price>at the price, when the market reaches it, from the next candlea long stop entry must be above the close, a short one below – for breakouts

valid N bars sets how many candles a limit or stop order waits; without it, 10 candles. enter signals an entry on every candle on which its statement runs – while no position is open, that is a new trade on each of those candles – so put it inside a when … end block (the checker warns otherwise). The block that contains enter must also contain stop at.

WickScript
wickscript 1
strategy "Entry types" risk 1%
fast = ema(close, 9)
slow = ema(close, 30)
when fast crosses above slow
    tag "pullback"
    enter long at limit fast + 0.05% valid 4 bars
    stop at slow - 0.4%
    target at 2R
end
when fast crosses below slow
    tag "breakdown"
    enter short at stop lowest(low, 5) - 2 * tick valid 3 bars
    stop at highest(high, 10)
    target at 2R
end

Stop and target

stop at <price>
target at <price>
target at <N>R
  • stop at is required in every block with an enter: it sets the position size. Typical stops: lowest(low, 10) - 2 * tick, low - 0.2%, close - 2 * atr(14) (a market entry fills at the close).
  • target at takes a price or an R multiple. target at 2R is the entry plus twice the distance to the stop (minus for shorts).
  • The target is optional when the script has an exit for that side (exit long when …, exit all when …, exit half when …). Without a target and without an exit, the entry is skipped.
  • stop at and target at belong to the last enter of their block.
  • stop and target are only keywords when followed by at; stop = low is a normal variable.

Tags

tag "Name" names the entries of its block. The name is shown in the chart's trade signals and in the statistics, so you can compare the setups of one strategy. Without a tag, an entry is named after its line, like "line 9".

Exits

exit long|short|all [at market] when <condition>
exit long|short|all
  • exit long when <condition> closes a long position at the close of the candle on which the condition becomes true (it was false on the previous candle), checked from the candle after the entry. If the condition was already true before the entry, it fires only after it has been false once.
  • exit short closes shorts, exit all either side. at market is optional; exits always fill at the close.
  • Without when, inside a block: the exit fires on every candle on which the block runs. Use this to exit while a condition holds.
  • At the top level, an exit without when would exit on every candle; the checker warns.
WickScript
wickscript 1
strategy "Exits" risk 1%
trend = ema(close, 50)
when close crosses above trend
    enter long at market
    stop at close - 2 * atr(14)
end
exit long when close crosses below trend
exit long when bars since entry >= 48 bars
if position.long and rsi(close, 14) > 80 then
    exit long
end

Partial exits

exit half at <price>        exit half at <N>R          # in the block with enter
exit 30% at <price>         exit 30% at <N>R
exit half when <condition>  exit 30% when <condition>  # anywhere, for any open position
  • exit … at belongs to the entry of its block and takes the share at a price or at N R, like a partial take-profit. The share is a share of the initial size; all partial exits of a block must add up to less than 100 % (the rest closes at the target, the stop or an exit).
  • In one candle the stop comes first, then the partial targets (closest to the entry first), then the target. A partial target at or beyond the target never fills.
  • exit … when closes the share at the close of the candle on which the condition becomes true. A full exit on the same candle takes precedence. If nothing is left after a partial exit, the trade ends.
  • half is 50 %. The share must be between 0 % and 100 %, written with %.
WickScript
wickscript 1
strategy "Scale out" risk 1%
when close crosses above ema(close, 20)
    enter long at market
    stop at lowest(low, 10)
    exit 30% at 1R
    exit 30% at 2R
    target at 4R
end
exit half when rsi(close, 14) crosses above 75

Breakeven: move stop

move stop to entry after <N>R
move stop to <price> after <N>R

In the block with enter. As soon as the best price since the entry (the high for longs, the low for shorts) has reached N R, the stop moves to the entry price (or the given price) at the close of that candle and applies from the next candle. The stop only moves in the profitable direction, and only when the new stop is below the close (longs) or above it (shorts); otherwise it waits for a later candle.

Trailing stop: trail stop

trail stop by <distance> [after <N>R]

In the block with enter. The stop follows the best price since the entry at a fixed distance, adjusted at each candle's close, only in the profitable direction and only while it stays on the right side of the close. The distance is a price (2 * atr(14), 50 * tick) or a percentage of the best price (1%), fixed on the signal candle. With after 1.5R, trailing starts once the best price has reached 1.5 R.

WickScript
wickscript 1
strategy "Breakout" risk 1%
# buy the break of the recent high, take half at 1R, then let the rest run
len = input 20 "Range"
top = highest(high, len)
bottom = lowest(low, len)
show top as line "Top" color green
show bottom as line "Bottom" color red
when close crosses above ema(close, 50) and not position.open
    tag "breakout"
    enter long at stop top + 2 * tick valid 5 bars
    stop at bottom
    exit half at 1R
    move stop to entry after 1R
    trail stop by 2 * atr(14) after 1.5R
    target at 4R
end
exit long when bars since entry >= 100 bars

The open position

ValueMeaningWithout a position
position.opena position is openfalse
position.long, position.shortits sidefalse
position.entryentry pricena
position.stopcurrent stop (after breakeven or trailing)na
position.targettarget pricena
position.sizeopen share of the initial size, in % (100 until a partial exit)0
position.ropen result in R at the candle's closena
position.barscandles since the entryna
bars since entrythe same as position.barsna

The script sees the position at the close of each candle, after stops, partial targets, targets and orders of that candle, and before its own decisions. A market entry made on a candle is visible from the next candle on (position.bars is 1 there). entry alone is not a value; write position.entry or bars since entry. position and bars since entry only work in strategies and not inside functions.

WickScript
wickscript 1
strategy "Position" risk 1%
fast = ema(close, 9)
slow = ema(close, 30)
when fast crosses above slow and not position.open
    enter long at market
    stop at lowest(low, 10)
end
exit long when position.r >= 1R or position.bars >= 15 bars
show position.stop as line "Current stop" color red

Metrics

metric "Name" = <expression>

metric stores the value of the expression on each trade's signal candle. In the strategy statistics, every metric becomes a dimension to group the results by: numbers in five ranges (quintiles such as "≤ 32.1", "32.1 – 45" … "> 70.2", "n/a" without a value), or the values themselves when there are at most five different ones. A metric needs a number or a yes/no value, and each name may be used once. Write metrics at the top level of the script.

WickScript
wickscript 1
strategy "Metrics" risk 1%
r = rsi(close, 14)
when close crosses above ema(close, 20)
    enter long at market
    stop at lowest(low, 10)
    target at 2R
end
metric "RSI at entry" = r
metric "ATR %" = pct(close + atr(14), close)
metric "London" = session is London

Reading other indicators of the strategy: use

use <TechName> as <alias>

use reads the outputs of another indicator of the same strategy by its tech name (the name like RSI1, EMA2 or WS1 shown in the strategy's indicator list):

  • alias.value is the main line; other outputs by name: alias.signal, alias["REL kill"]. Names ignore upper/lower case and special characters, so alias.relKill is the same as alias["REL kill"].
  • Values are aligned like the gates of the Trade Setup: the value at each candle's close, indicators on higher timeframes with their delay.
  • use works in strategies (F5, Run strategy, Strategy Lab preview). In the chart, a script with use shows a message, and the values stay na.
  • To create an indicator inside the script instead, use use indicator "Name" with … as … (see Indicators).
WickScript
wickscript 1
strategy "RSI filter" risk 1%
use RSI1 as r
use EMA1 as trend
when close crosses above trend.value and r.value > 50
    enter long at market
    stop at trend.value - 0.5%
    target at 2R
end

Backtesting a script

  • In Strategy Lab → Scripts, a strategy script shows a backtest preview of your draft while you type: trades, short/long, win rate, total R and R per trade, plus any messages.
  • Trade with this script in the Scripts tab makes the strategy trade with the script. From then on, F5 (backtest on the chart) and Run strategy use the applied version. Only the first strategy script of a strategy trades.
  • Trade with this Trade Setup in the Trade Setup tab switches back to the Trade Setup.
  • Inputs can be Step 1 / Step 2 parameters for the heatmap, like the settings of any indicator.

How the backtest simulates fills, fees and position sizes is described in Backtest engine; the statistics and tabs of the Lab in Strategy Lab.

From the Trade Setup: Open as WickScript

Open as WickScript in the Trade Setup writes your setup as a strategy script into the Scripts tab, with the same trades:

  • each trigger becomes a when … end block per side, its filters an if inside it (a filter without a value lets the trade through, like in the Trade Setup: isna(x) or …);
  • the indicator lines are read with use <TechName> as x and x.value or x["Output"];
  • stop and target lines become stop at and target at with the buffer in %, limit entries enter … at limit … valid N bars;
  • exit gates become exit long when … / exit short when …; cooldown and minimum R go into the strategy line;
  • sides without a stop line don't trade, as in the Trade Setup.

From then on the script trades; your Trade Setup stays saved. The conversion works in one direction only – a script can't be turned back into a Trade Setup. A converted setup looks like this:

WickScript
wickscript 1
# from the Trade Setup of "Trend pullback" – the same triggers, filters, exits, stops and targets
strategy "Trend pullback" risk 1% cooldown 3 bars
use EMA1 as ema1
use RSI1 as rsi1

when close >= ema1.value
    tag "Long · EMA"
    if (isna(rsi1.value) or rsi1.value >= number(50)) then
        enter long at market
        stop at ema1.value - 0.4%
    end
end
exit long when close <= ema1.value

More examples

RSI dip in an uptrend with a limit entry and a time exit:

WickScript
wickscript 1
strategy "RSI dip" risk 0.5% cooldown 5 bars
r = rsi(close, input 14 "RSI length")
trend = ema(close, 200)
when r crosses below 30 and close > trend
    tag "RSI dip"
    enter long at limit close - 0.2% valid 3 bars
    stop at lowest(low, 20) - 0.1%
    target at 2R
end
exit long when r crosses above 70
exit long when bars since entry >= 48 bars

Stop and reverse on an EMA cross with trailing stops, filtered by the 4h trend:

WickScript
wickscript 1
strategy "Trend rider" risk 1% leverage 3
fast = ema(close, 20)
slow = ema(close, 50)
up4h = close > ema(close, 50) on 4h
show fast as line "Fast" color amber
show slow as line "Slow" color blue
when fast crosses above slow and up4h
    enter long at market
    stop at close - 2 * atr(14)
    trail stop by 3 * atr(14) after 1R
end
when fast crosses below slow and not up4h
    enter short at market
    stop at close + 2 * atr(14)
    trail stop by 3 * atr(14) after 1R
end
exit long when fast crosses below slow
exit short when fast crosses above slow

Exits run before entries at a candle's close, so the long is closed and the short opened on the same candle.

Asia range breakout in the London session:

WickScript
wickscript 1
strategy "Asia range breakout" risk 1%
inAsia = session is Asia
keep top = na
keep bottom = na
when inAsia
    top = high
    bottom = low
end
if inAsia then
    top = max(top, high)
    bottom = min(bottom, low)
end
show top as line "Asia high" color teal
show bottom as line "Asia low" color teal
when session is London and close crosses above top
    tag "London long"
    enter long at market
    stop at (top + bottom) / 2
    exit half at 1R
    move stop to entry after 1R
    target at 3R
end
when session is London and close crosses below bottom
    tag "London short"
    enter short at market
    stop at (top + bottom) / 2
    exit half at 1R
    move stop to entry after 1R
    target at 3R
end
exit all when session is NewYork

Previous day low sweep in the killzones, with metrics:

WickScript
wickscript 1
strategy "PDL sweep" risk 1%
pdl = low on 1d
swept = low < pdl and close > pdl
when swept and killzone is London or NewYork
    tag "PDL sweep"
    enter long at market
    stop at low - 2 * tick
    target at 2R
end
metric "Sweep depth %" = pct(pdl, low)
metric "Killzone London" = killzone is London

In swept and killzone is London or NewYork, the or NewYork belongs to is: the condition means swept and (killzone is London or killzone is NewYork).

Generated from the ChartRider source code on every release – settings, outputs and the WickScript reference always match the app.

Imprint·Privacy·Contact·Changelog·llms-full.txt

Paper trading uses play money only. Nothing in these docs is investment advice.