DocsBest Practices

Risk Management

Effective risk management prevents catastrophic losses. QSL strategies implement risk rules directly in onBar() logic.

ATR-Based Stop Loss

ATR (Average True Range) adapts your stop to current volatility:

function init(ctx) { ctx.addIndicator('atr', 'ATR', { period: 14 }); ctx.addIndicator('ema', 'EMA', { period: 20 }); } function onBar(ctx, i) { const pos = ctx.position('ASSET'); const close = ctx.series.close[i]; const atr = ctx.ind.atr[i]; if (q.isNaN(atr)) return; // Entry if (pos.qty === 0 && q.crossOver(ctx.series.close, ctx.ind.ema, i)) { ctx.order.market('ASSET', 1, { signal: 'buy', stopPrice: close - atr * 2 // Store stop level in metadata }); } // Stop loss: exit if price drops 2x ATR below entry if (pos.qty > 0) { const stopLevel = pos.avgPrice - atr * 2; if (close <= stopLevel) { ctx.order.close('ASSET', { signal: 'stopLoss' }); } } }

Percentage-Based Stop and Target

Simple fixed-percentage rules:

function onBar(ctx, i) { const pos = ctx.position('ASSET'); const close = ctx.series.close[i]; if (pos.qty > 0) { const pnlPct = (close - pos.avgPrice) / pos.avgPrice; // Stop loss at -3% if (pnlPct <= -0.03) { ctx.order.close('ASSET', { signal: 'stopLoss' }); return; } // Take profit at +6% (2:1 reward-risk) if (pnlPct >= 0.06) { ctx.order.close('ASSET', { signal: 'takeProfit' }); return; } } }

Trailing Stop

Lock in profits as the trade moves in your favor:

function onBar(ctx, i) { const pos = ctx.position('ASSET'); const high = ctx.series.high[i]; const close = ctx.series.close[i]; if (pos.qty > 0) { // Track the highest price since entry using lookback const barsSinceEntry = 20; // Or track via metadata const highestSinceEntry = q.highest(ctx.series.high, barsSinceEntry, i); // Trail stop 3% below the peak const trailingStop = highestSinceEntry * 0.97; if (close <= trailingStop) { ctx.order.close('ASSET', { signal: 'trailingStop' }); } } }

Tiered Profit Taking

Reduce risk progressively as the trade succeeds:

function onBar(ctx, i) { const pos = ctx.position('ASSET'); if (pos.qty <= 0) return; const close = ctx.series.close[i]; const gain = (close - pos.avgPrice) / pos.avgPrice; // Take 1/3 at +3% if (gain >= 0.03 && pos.qty > 0.6) { ctx.order.reduce('ASSET', 0.33, { signal: 'tp1' }); } // Take 1/3 at +6% if (gain >= 0.06 && pos.qty > 0.3) { ctx.order.reduce('ASSET', 0.5, { signal: 'tp2' }); } // Close remainder at +10% if (gain >= 0.10) { ctx.order.close('ASSET', { signal: 'tp3' }); } }

Risk-Reward Filtering

Only take trades where reward potential exceeds risk:

function onBar(ctx, i) { const close = ctx.series.close[i]; const atr = ctx.ind.atr[i]; const pos = ctx.position('ASSET'); if (pos.qty !== 0 || q.isNaN(atr)) return; const stopDistance = atr * 2; const targetDistance = atr * 4; // 2:1 R:R ratio // Only enter if there's room to run const resistance = q.highest(ctx.series.high, 50, i); const upside = resistance - close; if (upside > stopDistance * 2) { ctx.order.market('ASSET', 1, { signal: 'buy' }); } }

Key Principles

  1. Always have an exit plan — every entry should have a defined stop loss
  2. Size positions relative to stop distance — wider stops need smaller positions
  3. Use ATR over fixed percentages — adapts to changing market conditions
  4. Consider fees — tight stops with frequent trading erode capital through commissions (default 0.1% per side)

Related

riskstop-losstake-profitdrawdownrisk-rewardtrailing