Getting Started#

Installation

First, install QuantScript dependencies:

bash
npm install

Build the Project

Compile the QuantScript language package:

bash
npm run build

Running Scripts

You can run QuantScript scripts using the CLI:

bash
# Using the built CLI
quantscript run your-script.qs

# Or during development, use tsx directly
npm run dev -- run your-script.qs

The CLI automatically provides sample OHLCV data (100 bars of simulated price data) when you run a script.

Hello World#

Create a file called hello.qs:

QuantScript
indicator("Hello World");

console.log("Hello, World!");

Run it:

bash
quantscript run hello.qs

Output:

text
── QuantScript Indicator ──
Hello, World!
Execution complete.

What's happening:

  • indicator("Hello World") declares this as an indicator script with a title
  • console.log() prints text to the console
  • The script runs once in global scope

Running Your First Script#

Script Structure

Every QuantScript script follows this pattern:

QuantScript
// 1. Declaration (required)
indicator("My Script Name");
// OR
strategy("My Strategy Name");

// 2. Global code (executed once)
let myVariable = 10;

// 3. DataFrame iteration (executed per bar)
df.forEach((frame) => {
    // Process each bar
});

Variables and Math

Create math-example.qs:

QuantScript
indicator("Math Example");

let x = 10;
const PI = 3.14159;

let sum = x + 5;
let product = x * 2;
let power = 2 ** 8;

console.log("Sum: " + tostring(sum));
console.log("Product: " + tostring(product));
console.log("Power: " + tostring(power));

Working with OHLCV Data#

QuantScript uses a DataFrame to represent market data. The CLI automatically provides sample OHLCV (Open, High, Low, Close, Volume) data.

Accessing Bar Data

Use df.forEach() to iterate through each bar:

QuantScript
indicator("OHLCV Display");

df.forEach((frame) => {
    let openPrice = frame.open;
    let highPrice = frame.high;
    let lowPrice = frame.low;
    let closePrice = frame.close;
    let volume = frame.volume;

    if (bar_index < 5) {
        console.log("Bar " + tostring(bar_index));
        console.log("  Close: " + tostring(closePrice));
    }
});

Derived Bar Variables

QuantScript provides pre-computed derived bar values:

QuantScript
df.forEach((frame) => {
    let midpoint = frame.hl2;     // (high + low) / 2
    let avgThree = frame.hlc3;    // (high + low + close) / 3
    let avgFour  = frame.ohlc4;   // (open + high + low + close) / 4
});

Available: frame.hl2, frame.hlc3, frame.hlcc4, frame.ohlc4.

Historical Data Access

Access previous bars using bracket notation:

QuantScript
df.forEach((frame) => {
    let currentClose = frame.close;
    let previousClose = close[1];  // 1 bar ago
    let twoBarsAgo = close[2];     // 2 bars ago
});

Building a Simple Indicator#

Simple Moving Average

QuantScript
indicator("SMA Indicator");

const SMA_LENGTH = 20;

df.forEach((frame) => {
    let sma = ta.sma(frame.close, SMA_LENGTH);
    chart.plot(sma, "SMA", "#FF0000");
});

Multiple Indicators

QuantScript
indicator("Multiple Indicators");

df.forEach((frame) => {
    let fastSMA = ta.sma(frame.close, 10);
    let slowSMA = ta.sma(frame.close, 20);
    let ema = ta.ema(frame.close, 20);

    chart.plot(fastSMA, "Fast SMA", "#00FF00");
    chart.plot(slowSMA, "Slow SMA", "#FF0000");
    chart.plot(ema, "EMA", "#0000FF");

    if (ta.crossover(fastSMA, slowSMA)) {
        console.log("BULLISH CROSSOVER");
    }
});

Creating a Trading Strategy#

SMA Crossover Strategy

QuantScript
strategy("SMA Crossover",
    initial_capital: 100000,
    default_qty_type: "fixed",
    default_qty_value: 100
);

df.forEach((frame) => {
    let fastSMA = ta.sma(frame.close, 10);
    let slowSMA = ta.sma(frame.close, 20);

    let crossUp = ta.crossover(fastSMA, slowSMA);
    let crossDown = ta.crossunder(fastSMA, slowSMA);

    if (crossUp) {
        strategy.entry("Long", "long");
    }
    if (crossDown) {
        strategy.close("Long");
    }
});

RSI Strategy

QuantScript
strategy("RSI Strategy",
    initial_capital: 50000
);

const RSI_LENGTH = 14;

df.forEach((frame) => {
    let rsi = ta.rsi(frame.close, RSI_LENGTH);

    if (rsi < 30 && strategy.position_size == 0) {
        strategy.entry("RSI Long", "long");
    }
    if (rsi > 70 && strategy.position_size > 0) {
        strategy.close("RSI Long");
    }
});

Strategy with Exit Orders

QuantScript
strategy("Strategy with Exits",
    initial_capital: 100000
);

df.forEach((frame) => {
    let sma = ta.sma(frame.close, 20);
    let crossUp = ta.crossover(frame.close, sma);

    if (crossUp && strategy.position_size == 0) {
        strategy.entry("Breakout", "long");
        let entryPrice = frame.close;
        strategy.exit("Exit", "Breakout",
            stop: entryPrice * 0.98,
            limit: entryPrice * 1.04
        );
    }
});

Pine Script to QuantScript#

If you're familiar with Pine Script, here's how to translate common patterns.

Basic Structure

Pine Script:

Pine Script
//@version=5
indicator("My Indicator")
plot(close)

QuantScript:

QuantScript
indicator("My Indicator");
df.forEach((frame) => {
    chart.plot(frame.close, "Close");
});

SMA Comparison

Pine Script:

Pine Script
smaValue = ta.sma(close, 20)
plot(smaValue, "SMA", color.blue)

QuantScript:

QuantScript
df.forEach((frame) => {
    let smaValue = ta.sma(frame.close, 20);
    chart.plot(smaValue, "SMA", "#0000FF");
});

Key Translation Notes

  1. Frame iteration: Pine Script iterates bar-by-bar automatically. QuantScript requires explicit df.forEach((frame) => { ... }).
  2. Variable access: Pine uses close directly. QuantScript uses frame.close inside the loop.
  3. Historical references: Both use close[1] syntax.
  4. Colors: Pine uses color.blue. QuantScript uses hex: "#0000FF".
  5. Function namespaces: Both use ta. for technical analysis.
  6. Semicolons: Optional in QuantScript but recommended.

For a full comparison, see the Coming from Pine Script page.

Next Steps

Now that you understand the basics:

  1. Explore the Language Reference — See all available functions and syntax
  2. Try the Examples — Run example scripts from this guide
  3. Build your own indicators and strategies
  4. Check backtest results and analyze performance