Strategy Parameters

Learn how to make your strategies configurable using parameters.

Overview

Hard-coding values in your strategy limits flexibility. Parameters allow users to customize strategy behavior without modifying code, making your strategies more reusable and adaptable to different market conditions.

Tip: Prefer file-based setup? You can define parameters in a JSON file and import them into the UI. See Strategy Parameters Template for the complete workflow.

Two Approaches

UI-Based Parameters

Define parameters through the strategy wizard interface. This approach is ideal for:

  • Quick prototyping
  • Non-technical users
  • Simple strategies

JSON File Parameters

Define parameters in a JSON file and import them. This approach is ideal for:

  • Batch parameter setup
  • Version control with Git
  • Sharing parameter presets as files

See Strategy Parameters Template for the JSON format.

Accessing Parameters

Parameters are accessed through the td.config object:

// String parameters
const mode = td.config.get('TRADING_MODE', 'conservative');

// Numeric parameters
const rsiPeriod = td.config.getNumber('RSI_PERIOD', 14);

// Boolean parameters
const useStopLoss = td.config.getBoolean('USE_STOP_LOSS', true);

Defining Parameters

When creating a strategy, you define parameters with their types, defaults, and constraints.

Parameter Types

TypeMethodExample
Stringget()Trading mode, pair name
NumbergetNumber()RSI period, stop loss %
BooleangetBoolean()Enable/disable features

Parameter Groups

Parameters can be organized into logical groups:

  • Indicators: RSI period, MACD settings, etc.
  • Risk Management: Stop loss, take profit, position size
  • Entry/Exit: Overbought/oversold levels, confirmation rules
  • Advanced: Experimental or power-user settings

Importing Parameters from JSON

You can define parameters in a JSON file and import them into the UI:

  1. Create a JSON file with your parameter definitions
  2. Click Import JSON in the Parameters step
  3. Upload your .json file or paste the JSON content
  4. Review and apply the extracted parameters
{
  "rsiPeriod": {
    "type": "number",
    "default": 14,
    "min": 2,
    "max": 100,
    "label": "RSI Period",
    "description": "Periods for RSI calculation"
  },
  "useStopLoss": {
    "type": "boolean",
    "default": true,
    "label": "Use Stop Loss"
  }
}

You can also Download Template to get a complete example JSON file.

For the full JSON schema, see Strategy Parameters Template.

Example: Configurable RSI Strategy

// ============================================
// PARAMETERS
// ============================================
const RSI_PERIOD = td.config.getNumber('RSI_PERIOD', 14);
const RSI_OVERSOLD = td.config.getNumber('RSI_OVERSOLD', 30);
const RSI_OVERBOUGHT = td.config.getNumber('RSI_OVERBOUGHT', 70);
const USE_STOP_LOSS = td.config.getBoolean('USE_STOP_LOSS', true);
const STOP_LOSS_PCT = td.config.getNumber('STOP_LOSS_PCT', 2);
const USE_TAKE_PROFIT = td.config.getBoolean('USE_TAKE_PROFIT', true);
const TAKE_PROFIT_PCT = td.config.getNumber('TAKE_PROFIT_PCT', 4);
const POSITION_SIZE_PCT = td.config.getNumber('POSITION_SIZE_PCT', 100);

// ============================================
// STRATEGY LOGIC
// ============================================
// Note: Custom RSI periods require custom indicator configured in bot settings
// For standard RSI (14), use td.indicators.rsi
// For custom periods, configure "rsi_X" custom indicator (e.g., rsi_21)
const rsi = RSI_PERIOD === 14 ? td.indicators.rsi : td.indicators.custom['rsi_' + RSI_PERIOD];
const price = td.market.price;

// Build trade options
const tradeOptions = {
    amountPercent: POSITION_SIZE_PCT,
    reason: `RSI ${rsi.toFixed(2)}`
    openGraph: { title: 'Strategy Parameters', description: 'How to define configurable parameters for strategies.' },
};

if (USE_STOP_LOSS) {
    tradeOptions.stopLoss = price * (1 - STOP_LOSS_PCT / 100);
}

if (USE_TAKE_PROFIT) {
    tradeOptions.takeProfit = price * (1 + TAKE_PROFIT_PCT / 100);
}

// Entry logic
if (!td.position.hasPosition && rsi < RSI_OVERSOLD) {
    td.trade.buy(tradeOptions);
}

// Exit logic
if (td.position.hasPosition && rsi > RSI_OVERBOUGHT) {
    td.trade.close(`RSI overbought at ${rsi.toFixed(2)}`);
}

Parameter Validation

Always validate parameters to prevent invalid configurations:

// Validate RSI period
const rsiPeriod = td.config.getNumber('RSI_PERIOD', 14);
if (rsiPeriod < 2 || rsiPeriod > 100) {
    td.utils.log('ERROR: RSI_PERIOD must be between 2 and 100');
    return;
}

// Validate percentage values
const stopLossPct = td.config.getNumber('STOP_LOSS_PCT', 2);
if (stopLossPct <= 0 || stopLossPct > 50) {
    td.utils.log('ERROR: STOP_LOSS_PCT must be between 0 and 50');
    return;
}

// Validate levels make sense
const oversold = td.config.getNumber('RSI_OVERSOLD', 30);
const overbought = td.config.getNumber('RSI_OVERBOUGHT', 70);
if (oversold >= overbought) {
    td.utils.log('ERROR: RSI_OVERSOLD must be less than RSI_OVERBOUGHT');
    return;
}

Common Parameter Patterns

Risk Management Parameters

// Risk parameters with sensible ranges
const RISK_PER_TRADE = td.config.getNumber('RISK_PER_TRADE', 1);     // 1% default
const MAX_DRAWDOWN = td.config.getNumber('MAX_DRAWDOWN', 10);        // 10% max DD
const MAX_POSITIONS = td.config.getNumber('MAX_POSITIONS', 1);       // Single position
const USE_TRAILING_STOP = td.config.getBoolean('USE_TRAILING_STOP', false);
const TRAIL_DISTANCE_PCT = td.config.getNumber('TRAIL_DISTANCE_PCT', 1);

Indicator Parameters

// EMA Crossover parameters
const FAST_EMA = td.config.getNumber('FAST_EMA', 9);
const SLOW_EMA = td.config.getNumber('SLOW_EMA', 21);
const TREND_EMA = td.config.getNumber('TREND_EMA', 50);

// Bollinger Band parameters
const BB_PERIOD = td.config.getNumber('BB_PERIOD', 20);
const BB_STD_DEV = td.config.getNumber('BB_STD_DEV', 2);

Mode Selection

const TRADING_MODE = td.config.get('TRADING_MODE', 'moderate');

let riskMultiplier;
switch (TRADING_MODE) {
    case 'conservative':
        riskMultiplier = 0.5;
        break;
    case 'moderate':
        riskMultiplier = 1.0;
        break;
    case 'aggressive':
        riskMultiplier = 2.0;
        break;
    default:
        riskMultiplier = 1.0;
}

const positionSize = baseSize * riskMultiplier;

Feature Toggles

// Enable/disable features
const USE_RSI_FILTER = td.config.getBoolean('USE_RSI_FILTER', true);
const USE_VOLUME_FILTER = td.config.getBoolean('USE_VOLUME_FILTER', false);
const USE_TREND_FILTER = td.config.getBoolean('USE_TREND_FILTER', true);
const ENABLE_SHORTS = td.config.getBoolean('ENABLE_SHORTS', false);

// Apply filters
let canTrade = true;

if (USE_RSI_FILTER && (td.indicators.rsi > 70 || td.indicators.rsi < 30)) {
    canTrade = false;
}

if (USE_TREND_FILTER && td.indicators.adx.value < 25) {
    canTrade = false;
}

Premium Parameters

For marketplace strategies, certain parameters can be restricted to higher tiers:

// Basic parameters (all tiers)
const RSI_PERIOD = td.config.getNumber('RSI_PERIOD', 14);
const STOP_LOSS_PCT = td.config.getNumber('STOP_LOSS_PCT', 2);

// Premium parameters (Trader+ only)
const USE_ADVANCED_FILTER = td.config.getBoolean('USE_ADVANCED_FILTER', false);
const MULTI_TIMEFRAME = td.config.getBoolean('MULTI_TIMEFRAME', false);

// Check tier for premium features
if (USE_ADVANCED_FILTER && td.account.tier === 'starter') {
    td.utils.log('Advanced filter requires Trader tier');
    // Fall back to basic behavior
}

Best Practices

Use Descriptive Names

// BAD
const x = td.config.getNumber('X', 14);
const y = td.config.getNumber('Y', 30);

// GOOD
const RSI_PERIOD = td.config.getNumber('RSI_PERIOD', 14);
const RSI_OVERSOLD_LEVEL = td.config.getNumber('RSI_OVERSOLD_LEVEL', 30);

Document Parameters

// ============================================
// STRATEGY PARAMETERS
// ============================================
// RSI_PERIOD (number, default: 14)
//   - RSI calculation period
//   - Range: 2-100
//
// RSI_OVERSOLD (number, default: 30)
//   - Buy when RSI drops below this level
//   - Range: 0-50
//
// STOP_LOSS_PCT (number, default: 2)
//   - Stop loss distance from entry (%)
//   - Range: 0.5-10
// ============================================

Provide Sensible Defaults

// Defaults should work reasonably well out of the box
const RSI_PERIOD = td.config.getNumber('RSI_PERIOD', 14);      // Standard RSI
const STOP_LOSS_PCT = td.config.getNumber('STOP_LOSS_PCT', 2); // Conservative SL
const POSITION_SIZE = td.config.getNumber('POSITION_SIZE', 50); // Half of balance

Group Related Parameters

// Entry parameters
const ENTRY_RSI_LEVEL = td.config.getNumber('ENTRY_RSI_LEVEL', 30);
const ENTRY_CONFIRM_CANDLES = td.config.getNumber('ENTRY_CONFIRM_CANDLES', 2);

// Exit parameters
const EXIT_RSI_LEVEL = td.config.getNumber('EXIT_RSI_LEVEL', 70);
const EXIT_PROFIT_TARGET = td.config.getNumber('EXIT_PROFIT_TARGET', 5);

// Risk parameters
const RISK_STOP_LOSS = td.config.getNumber('RISK_STOP_LOSS', 2);
const RISK_MAX_TRADES = td.config.getNumber('RISK_MAX_TRADES', 3);

Next Steps