Skip to content
ChartDeck ChartScript docs Account Open the terminal

Strategies

Strategies (simulated orders and backtests) are not available in ChartScript yet. Here is what you can build today instead.

A strategy is a script that places simulated orders and reports how they would have performed: entries, exits, position size, profit and drawdown. ChartScript does not have strategies yet. There is no strategy(…) declaration and no strategy.* functions, and ChartScript never places real orders.

A script that tries to use them does not compile:

ChartScriptError: CS2011
//@chartscript 1
indicator("Orders are not available")
if (ta.crossover(close, ta.sma(close, 20))) {
    strategy.entry("Long", strategy.long)
}

When you import a strategy written in another charting script language, ChartDeck converts it into an indicator: its plots, drawings and alert conditions are kept, and the lines that place orders or read strategy results are kept as comments, listed in the import report. See what converts.

#What you can do today

Most of what a strategy shows can be built as an indicator, honestly and on closed bars:

  • Entry and exit signals as markers with plotshape, confirmed on closed bars so they never repaint (see repainting).
  • Stops and targets as lines that follow an open "position" you track yourself in state variables.
  • A results table on the last bar: number of signals, how many reached the target first, average move after a signal.
  • Alert conditions with alert.on, which you can turn into script alerts that ChartDeck checks on its servers.

Keep in mind what such a table is not: it has no fees, no funding, no slippage and no position sizing, so treat it as a quick look at a signal, not as a test of a trading system.

#A whole example: signals with a tracked target and stop

This indicator enters a hypothetical long on a confirmed close above the 20-bar high, then follows it until price reaches a target or a stop (both multiples of the ATR at entry). It draws the levels while a signal is open and counts the outcomes in a small table.

ChartScriptOpen in editor
//@chartscript 1
indicator("Breakout signal tracker", { overlay: true })

const len = input.int(20, "Breakout length", { minval: 2 })
const tgtMult = input.float(2.0, "Target (x ATR)", { minval: 0.1, step: 0.1 })
const stopMult = input.float(1.0, "Stop (x ATR)", { minval: 0.1, step: 0.1 })

const atr = ta.atr(14)
const signal = close > ta.highest(high, len)[1] && barstate.isconfirmed

state target: float = na
state stop: float = na
state wins: int = 0
state losses: int = 0

const inTrade = !na(target)
if (inTrade && barstate.isconfirmed) {
    if (high >= target) {
        wins += 1
        target = na
        stop = na
    } else if (low <= stop) {
        losses += 1
        target = na
        stop = na
    }
}

const startNew = signal && na(target)
if (startNew) {
    target = close + tgtMult * atr
    stop = close - stopMult * atr
}

plotshape(startNew, "Signal", shape.triangleup, location.belowbar, color.up)
plot(target, "Target", color.up, { style: plot.style_linebr })
plot(stop, "Stop", color.down, { style: plot.style_linebr })

state t: table = table.new(position.top_right, 2, 3)
if (barstate.islast) {
    const total = wins + losses
    table.cell(t, 0, 0, "Target first", { text_color: color.text })
    table.cell(t, 1, 0, str.tostring(wins), { text_color: color.up })
    table.cell(t, 0, 1, "Stop first", { text_color: color.text })
    table.cell(t, 1, 1, str.tostring(losses), { text_color: color.down })
    table.cell(t, 0, 2, "Hit rate", { text_color: color.text })
    table.cell(t, 1, 2, total > 0 ? str.tostring(wins / total * 100, "0") + "%" : "-", { text_color: color.text })
}

When a bar reaches both the target and the stop, the script counts the target first; with one bar it cannot know which came first. That is one more reason to read the table as a sketch.

The ChartScript documentation is in English for now; translations will follow.