Appearance

Personalize your experience

Mode
Accent Color
Direction
The Backtest Engine

The Backtest Engine

Backtesting

One service backtests every kind of strategy on Quatick. Each source type runs on the engine built for it, and every result is measured with the same statistics, so a builder strategy, a QuaScript script and a Python file can be compared number for number.

Which engine runs your strategy

The engine is chosen by what you backtest, not by a setting. Open a on ( → ) and it goes to the matching engine:

You backtestLanguageRuns on
A built in the dslThe C++ DSL engine, the same engine that runs it
A .qs scriptquascriptThe QuaScript engine, with the script’s own broker (orders, brackets, risk rules)
A .py file or Python projectpythonPython, with the importable
A .ts / .js file or projecttypescript / javascriptNode.js (TypeScript is compiled first)
A .cpp file or C++ projectcppCompiled with C++20 against the quatick headers
A rule written as SQL expressionssqlDuckDB, vectorized: a whole parameter grid in one query
★
Pro tip:Multi-file projects work in every coded language. The folder layout is reproduced on the server, so from indicators. import rsi, import { sma } from './utils/series' and #include "signals/rules.hpp" resolve exactly as they do on your machine.

One set of rules for every language

Coded strategies (Python, TypeScript, JavaScript, C++, SQL) only decide what position to hold. A shared simulator those decisions into , costs and an . The builder DSL and QuaScript engines simulate their own orders, because stops, targets and brackets inside them. Either way, the , and are computed once, by the same code.

  • happen at the next bar’s open by default, so a made on a bar’s close is never at that close (no lookahead). You can choose the signal bar’s close instead.
  • Costs: percent of , per unit, per order, Indian statutory schedules (STT, duty, exchange and SEBI charges, GST) or crypto maker / taker fees.
  • Slippage: , ticks, or square-root that grows with your share of the bar’s volume.
  • Delay, and a volume- cap model , contract sizes and liquidity.

The same SMA written in five languages produces the same , bar for bar. The engine’s test suite checks this on every change.

Market data

VenueSource
NSE, BSE, NFO, BFO, MCX, CDSQuatick historical service (stored candles with broker backfill)
BINANCE (spot), BINANCE_FUTURES (USD-M)Binance public klines
DELTA (Delta India), DELTA_GLOBALDelta Exchange public candles

Pick the broker and symbol on and the venue follows from it. Through the API, pass exchange (or broker), symbol, interval and a . A bar that has not closed yet is never included, and up to 500,000 bars fit in one run.

Writing a coded strategy

Return a target position for every bar: signed units (10 = long ten, −10 = short ten, 0 = flat), or a fraction of equity with : "fraction". Signal lists are accepted too.

strategy.py: positions
from quatick import ta

def strategy(bars, params):
    fast = ta.ema(bars.close, params.get("fast", 12))
    slow = ta.ema(bars.close, params.get("slow", 26))
    return [0 if ta.is_na(s) else (1 if f > s else -1) for f, s in zip(fast, slow)]
main.ts: signals
export function calculate(bars: Array<{ time: number; close: number }>, params: { n?: number }) {
  const n = params.n ?? 20, out = [];
  for (let i = n; i < bars.length; i++) {
    const mean = bars.slice(i - n, i).reduce((s, b) => s + b.close, 0) / n;
    if (bars[i - 1].close <= mean && bars[i].close > mean) out.push({ time: bars[i].time, type: 'LONG_ENTRY' });
    if (bars[i - 1].close >= mean && bars[i].close < mean) out.push({ time: bars[i].time, type: 'LONG_EXIT' });
  }
  return out;
}
Entry pointReturns
strategy(bars, params)one target position per bar
run / calculate / runStrategy (bars, params)signals: LONG_ENTRY, LONG_EXIT, SHORT_ENTRY, SHORT_EXIT, BUY, SELL, EXIT (optional qty, price)
init(params) + onBar(history, state, params)per bar { signal, state }
a program with its own mainreads QUATICK_INPUT_JSON / QUATICK_BARS_CSV, writes QUATICK_OUTPUT_JSON
!
Caution:Position i may only use bars up to and including i. The lookahead probe (API route lookahead) re-runs your on shorter histories and fails it if past positions change when bars are .

The API

Every route is POST /backtest/engine/<route> with your Quatick token, and costs one backtest credit (refunded if the job fails). check is free.

RouteWhat it does
runone backtest, with monthly returns, trade breakdowns and episodes
sweepa parameter grid, ranked by (or another metric)
monte-carlotrade / shuffle and market- re-runs
walk-forward or anchored re-optimization, scored out of sample
overfitting and probability of backtest overfitting
lookaheadchecks that the does not read bars
compare2 to 10 strategies, in any languages, on the same bars
hft and quote replay with , and maker / taker fees
checkcompile / validate without running
POST /backtest/engine/run
{
  "data": { "kind": "historical", "exchange": "BINANCE", "symbol": "BTCUSDT", "interval": "1h",
            "from": "2025-01-01", "to": "2025-06-30" },
  "strategy": { "language": "python", "files": [{ "path": "main.py", "content": "..." }] },
  "execution": { "capital": 100000, "costs": { "kind": "percent", "value": 0.02 },
                 "slippage": { "kind": "bps", "value": 1 } }
}

See also

Related articles

  • QuaScript C++ Engine & Quant DSL

    Coding / QuaScript

    Sub-microsecond quantitative algorithmic scripting engine powered by C++20 bytecode VM, SIMD AVX2 acceleration, cache-aligned columnar memory, and direct…

  • Backtesting in Python and C++

    Backtesting / SDKs

    The quatick Python package and the header-only C++ library let you import indicators, backtest on your own machine and send the same file to Quatick.…

  • Engines — Python vs C++

    Automation / Predefined Strategies

    Two independent implementations of the same grid semantics, consuming the same config and the same command channel. The choice is a runtime choice, not a…

  • C++ SDK Reference

    Backtesting / SDKs / C++

    Header-only C++20 (packages/quatick-backtest-cpp): the position simulator, an event-driven engine with the same order rules as Python, analytics, a parallel…

  • Python: Event-Driven Strategies

    Backtesting / SDKs / Python

    Subclass quatick.Strategy to trade bar by bar with real orders: brackets, trailing stops, limits, risk-based sizing and a drawdown kill switch. The same…

  • Python: Research Toolkit

    Backtesting / SDKs / Python

    Everything after the first backtest: tearsheet analytics, multi-asset portfolios, position sizing, optimization and walk-forward, overfitting tests, Monte…

  • Cumulative Delta (CVD)

    Charts / Chart Types / Volume Charts

    Candles of the running total of buy volume minus sell volume, with divergence detection against price.

  • DOM Ladder

    Charts / Chart Types / Volume Charts

    Depth of market on the chart's price scale: resting bids and asks, your orders, traded volume and delta at every price, with recent candles beside it.

  • Order Flow

    Trading / Order Book / Views

    Size added and pulled at every level, live, over a slowly decaying history.

Browse all knowledge base articles →