Configuration Files

Configuration Files

Configuration files enable repeatable, complex backtesting setups in a JSON format.

Why use configuration files?

  • Store complex multi-symbol setups for repeatable execution
  • Run multiple strategies in a single batch
  • Define per-symbol overrides without long command lines
  • Generate portfolio reports automatically
  • Share configurations with other users

Basic structure

{
  "global": {
    "strategy": "macrossover",
    "bar-interval": "daily",
    "date-from": "2015-01-01",
    "date-to": "2024-12-31",
    "output-mode": "summary"
  },
  "runs": [
    { "symbol": "@ES" },
    { "symbol": "@NQ" },
    { "symbol": "@CL" }
  ]
}

The global section defines defaults; the runs array defines individual backtests that can override any global setting.

Running a configuration

algo run --config myconfig.json

# Validate without running
algo run --config myconfig.json --verify

Config files without a path are loaded from ~/.algolang/configs/.

Comments

Although standard JSON does not support comments, Algolang config files allow line comments starting with // (outside of string literals). These are stripped before JSON parsing:

{
  "global": {
    // Mean reversion strategy on daily bars
    "strategy": "meanrevert",
    "bar-interval": "daily"
  }
}

Per-run overrides

Each run can override any global setting:

{
  "global": {
    "strategy": "kbt",
    "bar-interval": "daily"
  },
  "runs": [
    { "symbol": "@ES" },
    {
      "symbol": "@NQ",
      "bar-interval": "60m",
      "session-hours": "9:30am-4:00pm"
    }
  ]
}

Symbol templates

The symbols section defines symbol lists for template expansion:

{
  "global": { "strategy": "kbt" },
  "symbols": {
    "symbol": ["@ES", "@NQ", "@CL", "@GC"]
  },
  "runs": [
    {
      "series": [
        { "symbol": "{symbol}", "bar-interval": "daily" }
      ]
    }
  ]
}

This creates one run per symbol.

Loading symbols from files

Symbols can be loaded from external files in two ways:

Portfolio file reference (recommended): Use the < prefix to reference a portfolio file from ~/.algolang/portfolios/:

{
  "symbols": {
    "symbol": "<metals"
  }
}

This loads all symbols from the metals portfolio file (see Portfolio files in Chapter 4 for the full list of available portfolios and their aliases). Portfolio names are resolved case-insensitively, and aliases are supported (e.g., <metals and <metal both work).

Relative file path: You can also specify a path relative to ~/.algolang/:

{
  "symbols": {
    "symbol": "portfolios/bp24.txt"
  }
}

Both approaches support the same file format: one symbol per line, space-separated, or comma-separated. Lines starting with # are comments and empty lines are ignored.

Example portfolio file (~/.algolang/portfolios/metals):

@GC
@HG
@PA
@PL
@SI

The < prefix syntax works anywhere a symbol is accepted in config files, including in series arrays and in the global section:

{
  "global": {
    "symbol": "<div24",
    "bar-interval": "daily"
  }
}
{
  "series": [
    { "symbol": "<metals", "bar-interval": "60m" }
  ]
}

Multiple symbol sources

For strategies that need multiple symbols per run (e.g., pairs trading), define multiple symbol sources using symbol1, symbol2, etc.:

{
  "global": {
    "strategy": "pairs"
  },
  "symbols": {
    "symbol1": ["@ES", "@NQ", "@YM"],
    "symbol2": ["@CL", "@GC", "@SI"]
  },
  "runs": [
    {
      "series": [
        { "symbol": "{symbol1}", "bar-interval": "daily" },
        { "symbol": "{symbol2}", "bar-interval": "daily" }
      ]
    }
  ]
}

This creates three runs: @ES paired with @CL, @NQ paired with @GC, and @YM paired with @SI.

The available template variables are:

VariableAliasSource
{symbol}{symbol1}Value of symbol or symbol1 key
{symbol2}Value of symbol2 key
{symbol3}Value of symbol3 key

Important: When using multiple sources, all sources must have the same number of symbols (paired iteration, not cartesian product). You can mix file paths and inline lists:

{
  "symbols": {
    "symbol1": "portfolios/primary.txt",
    "symbol2": ["@SPY", "@QQQ", "@IWM"]
  }
}

Multi-symbol series

For strategies that need multiple data series per run:

{
  "runs": [
    {
      "strategy": "pairs",
      "series": [
        { "symbol": "@ES", "bar-interval": "60m" },
        { "symbol": "@NQ", "bar-interval": "60m" }
      ]
    }
  ]
}

Per-series settings

Each series entry can override the following settings independently. Settings not specified inherit from the run level, then global level, then system defaults:

  • bar-building-mode
  • bar-interval
  • session-days
  • session-hours
  • timezone
{
  "series": [
    {
      "symbol": "@ES",
      "session-hours": "9:30am-4:00pm",
      "timezone": "America/New_York"
    },
    {
      "symbol": "@NQ",
      "session-hours": "9:30am-4:00pm",
      "bar-interval": "30m"
    }
  ],
  "strategy": "pairs",
  "bar-interval": "60m"
}

In this example, both series default to 60m bars (from the run level), but @NQ overrides to use 30m bars. Each series has its session hours specified individually.

Output redirection (tty)

The tty setting redirects console output to a file instead of the terminal. This is useful for logging results or running batch jobs. The setting supports the same template variables as export.

By default, the file is overwritten each time:

{
  "tty": "logs/{strat}-{sym}.log"
}

Prefix the path with >> to append to an existing file:

{
  "tty": ">>logs/{yyyy}{mm}{dd}.log"
}

Each run can have its own output file, and per-run tty settings override the global value.

Template variables

The export, portfolio, and tty paths support template variables:

VariableDescription
{strat}Strategy name
{sym}Symbol name
{bar}Bar interval
{from}, {to}Date range
{yyyy}, {mm}, {dd}Date components
{hh}, {mi}, {ss}Time components
{datetime}Full timestamp
{date}Full date (YYYY-MM-DD)
{batchfile}Config filename without extension
{configfile}Alias for {batchfile}
{inputs}Input values (e.g., Period=20,Mult=1.5)
{$Name}Value of strategy input Name

Portfolio generation

The portfolio setting in the config generates a combined HTML report:

{
  "global": {
    "strategy": "kbt",
    "export": "trades/{strat}-{sym}.json",
    "portfolio": "portfolio-{datetime}.html"
  },
  "runs": [
    { "symbol": "@ES" },
    { "symbol": "@NQ" }
  ]
}

If portfolio is set without export, trade files are created in a temporary directory and cleaned up after the report is generated.

Command-line overrides

When running with --config, any command-line flag that corresponds to a global config setting will override that setting when explicitly specified. This allows you to quickly test variations without modifying the config file.

Date Range and Capital:

CLI FlagConfig SettingDescription
--date-fromdate-fromStart date for backtest
--date-todate-toEnd date for backtest
--initial-capitalinitial-capitalStarting capital with optional currency
--base-currencybase-currencyBase currency for reports

Series Defaults (applied to all runs that don’t specify their own):

CLI FlagConfig SettingDescription
--symbolssymbolDefault symbol for runs without their own
--bar-intervalbar-intervalBar interval size
--bar-building-modebar-building-modeHow bars are constructed
--session-hourssession-hoursTrading session hours
--session-dayssession-daysTrading session days
--timezonetimezoneTimezone for the session

Engine Options:

CLI FlagConfig SettingDescription
--max-bars-backmax-bars-backMaximum lookback period
--risk-free-raterisk-free-rateRisk-free rate for Sharpe
--position-sizeposition-sizeDefault position size
--no-look-inside-barno-look-inside-barDisable intra-bar simulation
--no-pyramidingno-pyramidingDisable position pyramiding
--no-out-of-session-executionno-out-of-session-executionDisable out-of-session execution
--dir-long-onlydir-long-onlyAllow only long positions
--dir-short-onlydir-short-onlyAllow only short positions

Cost Model:

CLI FlagConfig SettingDescription
--slippage-modeslippage-modeSlippage calculation mode
--slippage-ticksslippage-ticksSlippage in ticks
--commission-modecommission-modeCommission calculation mode
--commission-amountcommission-amountCommission amount
--commission-percentagecommission-percentageCommission percentage

Output and Execution:

CLI FlagConfig SettingDescription
--portfolioportfolioPortfolio output path
--exportexportTrade export path
--audit-trailaudit-trailAudit trail output path
--execution-modeexecution-modeExecution mode (auto/parallel/sequential)
--workersparallel-workersNumber of parallel workers

Filtering:

CLI FlagConfig SettingDescription
--symbols-excludesymbols-excludeSymbols to exclude (additive with config value)
--filterfiltersFilter name (replaces config filters)
--market-suitabilityFilter runs by market suitability

Override behavior

  • Global settings only: CLI overrides apply exclusively to the global section. To change run-specific settings, edit the config file directly.
  • Explicit flags only: Only flags explicitly specified on the command line override config values. Default flag values do not override config settings.
  • Series defaults propagation: CLI overrides to series-level settings (like --bar-interval) are applied to the global defaults before they propagate to individual runs. Runs that already define their own series-level settings are not affected.
  • Symbols-exclude is additive: The --symbols-exclude flag is combined with any symbols-exclude value in the config, rather than replacing it.
  • Verify effective config: Use --verify to display the final config after CLI overrides, without running the backtest.
# Override date range to test a shorter period
algo run --config portfolio.json --date-from 2023-01-01 --date-to 2024-01-01

# Override bar interval for all runs
algo run --config portfolio.json --bar-interval 60m

# Test with different capital and slippage
algo run --config portfolio.json --initial-capital USD50000 --slippage-ticks 5

# Inspect effective config after overrides
algo run --config portfolio.json --bar-interval 60m --verify

Multi-strategy configuration

For portfolios with multiple strategies, use the strategies array instead of runs:

{
  "global": {
    "date-from": "2015-01-01",
    "initial-capital": "USD1000000",
    "portfolio": "multi-{datetime}.html"
  },
  "symbols": {
    "symbol": ["@ES", "@NQ", "@CL", "@GC"]
  },
  "strategies": [
    {
      "strategy": "kbt",
      "runs": [
        { "series": [{ "symbol": "{symbol}", "bar-interval": "daily" }] }
      ]
    },
    {
      "strategy": "meanrevert",
      "symbols": { "symbol": ["@ES", "@NQ"] },
      "runs": [
        { "series": [{ "symbol": "{symbol}", "bar-interval": "daily" }] }
      ]
    }
  ]
}

In multi-strategy mode, each strategy can optionally override the global symbol list.

Strategy entry structure

Each entry in the strategies array contains:

FieldRequiredDescription
strategyYesStrategy name
runsYesArray of run configurations (same as single-strategy)
inputsNoStrategy-specific input parameters
symbolsNoOverride global symbols for this strategy
Other settingsNoAny global setting can be overridden at strategy level

Key differences from single-strategy mode

AspectSingle-StrategyMulti-Strategy
Top-level arrayrunsstrategies
Strategy locationglobal.strategyEach strategies[].strategy
Inputs locationglobal.inputsEach strategies[].inputs
SymbolsGlobal onlyGlobal with per-strategy override

Multi-strategy validation rules

  1. You cannot have both strategies and runs at the top level
  2. The strategy field must not appear in global (it belongs in each strategy entry)
  3. The inputs field must not appear in global (it belongs in each strategy entry)
  4. Each strategy entry must have a strategy field and a runs array with at least one run
  5. Each strategy’s runs are validated against its effective symbols (strategy-level or global)

Run entry format

Each entry in the runs array supports three formats for specifying symbols:

  1. series array (preferred): Full control over each data series:

    { "series": [{ "symbol": "@ES", "bar-interval": "60m" }] }
  2. symbol field: Shorthand that creates a series automatically:

    { "symbol": "@ES" }
  3. symbols field: An alias for symbol (both are accepted):

    { "symbols": "@ES/@NQ" }

When using symbol or symbols with slash-separated symbols (e.g., "@ES/@NQ"), each symbol is automatically split into its own series entry.

Global settings reference

The global section supports the following settings (all are optional):

SettingTypeDefaultDescription
strategystringStrategy name
symbolstringDefault symbol (e.g., "@ES", "<div24")
seriesarrayDefault series array
bar-intervalstring"daily"Bar interval size
bar-building-modestring"natural""natural" or "session"
date-fromstring"2010-01-01"Start date (YYYY-MM-DD)
date-tostringTodayEnd date (YYYY-MM-DD)
initial-capitalstring"1000000"Initial capital with optional currency prefix
session-hoursstringTrading session hours
session-daysstringTrading session days
timezonestringIANA timezone
slippage-modestring"per-unit""per-unit", "per-trade", or "percentage"
slippage-ticksnumber0Slippage in ticks
commission-modestring"per-unit""per-unit", "per-trade", or "percentage"
commission-amountstring"0"Commission amount
commission-percentagenumber0Commission as percentage (0-100)
max-bars-backnumber263Maximum lookback period
bouncing-ticksnumber0Bouncing ticks percentage (0-100)
no-look-inside-barboolfalseDisable intra-bar order evaluation
no-pyramidingboolfalseDisable pyramiding
no-out-of-session-executionboolfalseDisable shadow bar evaluation
dir-long-onlyboolfalseAllow only long positions
dir-short-onlyboolfalseAllow only short positions
risk-free-ratenumber0.05Risk-free rate for Sharpe calculations
output-modestring"silent"Output verbosity
inputsobjectStrategy input overrides
exportstringTrade export file path (supports template variables)
portfoliostringPortfolio HTML report path (supports template variables)
ttystringRedirect output to file (prefix with >> to append)
descriptionstringDescription for portfolio sub-title (supports {$Name} input variables)
notesstringFree-form notes or comments
use-firststringUse first N% of data (e.g., "70" or "70%")
use-laststringUse last N% of data (e.g., "30" or "30%")
base-currencystringBase currency for reports
execution-modestring"auto"Execution mode: "auto", "parallel", "sequential"
parallel-workersnumber64Number of parallel workers (parallel mode only)

All global settings can be overridden at the run level.

Comprehensive example

The following example demonstrates many config features – global defaults, per-run overrides, different strategies, and multi-symbol runs:

{
  "global": {
    "strategy": "meanrevert",
    "bar-interval": "daily",
    "bar-building-mode": "natural",
    "date-from": "2015-01-01",
    "date-to": "2024-12-31",
    "initial-capital": "USD100000",
    "session-hours": "8:30am-3:15pm",
    "session-days": "Mon-Fri",
    "timezone": "America/New_York",
    "slippage-mode": "per-unit",
    "slippage-ticks": 2,
    "commission-mode": "per-unit",
    "commission-amount": "2.50USD",
    "max-bars-back": 263,
    "no-pyramiding": true,
    "risk-free-rate": 0.05,
    "output-mode": "summary",
    "inputs": {
      "Period": 20,
      "Mult": 1.5
    }
  },
  "runs": [
    {
      // Uses all global defaults
      "symbol": "@ES"
    },
    {
      // Override bar interval and session, plus strategy inputs
      "symbol": "@NQ",
      "bar-interval": "60m",
      "session-hours": "9:30am-4:00pm",
      "inputs": {
        "Period": 15,
        "Mult": 2.0
      }
    },
    {
      // Different capital and timezone
      "symbol": "@CL",
      "initial-capital": "USD50000",
      "slippage-ticks": 1,
      "timezone": "America/Chicago",
      "session-hours": "6:00pm-5:00pm"
    },
    {
      // Different strategy entirely
      "symbol": "@GC",
      "strategy": "trendfollow",
      "dir-long-only": true,
      "inputs": {
        "FastMA": 10,
        "SlowMA": 50
      }
    },
    {
      // Different date range and commission model
      "symbol": "@ZB",
      "date-from": "2018-01-01",
      "commission-mode": "per-trade",
      "commission-amount": "5.00"
    },
    {
      // Multi-symbol pairs strategy using series array
      "strategy": "pairs",
      "series": [
        {
          "symbol": "@ES",
          "bar-interval": "60m",
          "session-hours": "9:30am-4:00pm",
          "timezone": "America/New_York"
        },
        {
          "symbol": "@NQ",
          "bar-interval": "60m",
          "session-hours": "9:30am-4:00pm"
        }
      ]
    }
  ]
}

Validation

Use --verify to validate a config file without running any backtests:

algo run --config myconfig.json --verify

Validation checks include:

  • Type checking: Ensures values are the correct type
  • Range checking: Validates numeric ranges (e.g., bouncing-ticks must be 0-100)
  • Format checking: Validates date formats, time formats, and timezone names
  • Logical checking: Prevents conflicting options (e.g., both dir-long-only and dir-short-only)
  • Series validation: Ensures each run has at least one series with a valid symbol

The standalone algo config -f <file> command can also be used to validate and display the parsed config as formatted JSON.

Example validation errors:

Configuration error: batch.run:15:3: JSON syntax error: invalid character '}' after object key
Configuration error: batch.run: global: invalid bar-building-mode "invalid" (must be one of: natural, session)
Configuration error: batch.run: global: date-from (2020-01-01) must be before date-to (2019-01-01)
Configuration error: batch.run: global: cannot specify both dir-long-only and dir-short-only as true
Configuration error: batch.run: runs[0]: at least one series with a symbol is required
Configuration error: batch.run: runs list cannot be empty
Configuration error: batch.run: symbol template {symbol2} references source 2, but only 1 source(s) defined
Configuration error: batch.run: runs[0] ({symbo}) series[0]: unrecognized template {symbo}

Tips

  1. Start simple: Begin with minimal global settings and add per-run overrides as needed.
  2. Validate before running: Always use algo run --config myconfig.json --verify to check for errors before running full backtests.
  3. Organise by strategy: Group related runs that use the same strategy together for easier maintenance.
  4. Use portfolio files: Reference portfolio files with < prefix rather than listing symbols inline for commonly used groups.
  5. Use template variables: Take advantage of {strat}, {sym}, and {datetime} in export and portfolio paths to generate unique filenames automatically.