DocsExamples

TDR Strategy (Trend Direction & Risk)

A sophisticated strategy combining trend detection with risk-based position management.

Overview

TDR generates multiple signal types for nuanced position management:

SignalTypeTrigger
buySignalFull EntryEMA crosses above Donchian baseline
sellSignalFull ExitEMA crosses below Donchian baseline
preEntryPartial EntryPrice crosses short baseline (early positioning)
takeProfitPartial ExitPrice crosses below short baseline in profit
lowRiskEntryPartial EntryExtended time in low-risk PPO zone
highRiskTPPartial ExitExtended time in high-risk PPO zone

Key Concepts

Donchian Channel Baseline

The Donchian channel provides a dynamic baseline (midpoint of highest high and lowest low):

ctx.indicator('baseline', 'DONCHIAN', { period: 50 }); // Access the middle line (baseline) const baseline = ctx.ind.baseline_middle; // EMA crossing above/below baseline defines trend if (q.crossOver(ema, baseline, i)) { // Bullish trend confirmed }

PPO Risk Zones

The PPO (Percent Price Oscillator) measures momentum on a -100 to +100 scale:

ctx.indicator('ppo', 'PPO', { shortGamma: 0.4, // Fast Laguerre filter longGamma: 0.8, // Slow Laguerre filter accuracy: 10 // Calculation precision }); // Define risk zones const ppoValue = ctx.ind.ppo[i]; if (ppoValue < -85) { // Low risk zone: good for entries } else if (ppoValue > 85) { // High risk zone: consider taking profits }

Zone Duration Signals

LowRiskEntry and HighRiskTP fire when the market stays in a risk zone for an extended period (average zone length):

function checkLowRiskEntry(riskState) { // Fire when current zone length equals average if (riskState.inLowRisk && riskState.avgLowRiskLength > 0) { return riskState.lowRiskLength === Math.round(riskState.avgLowRiskLength); } return false; }

Trading Modes

TDR supports all three trading modes: Long-only, Short-only, and Bidirectional. The mode is accessed via ctx.p.tradingMode and the strategy branches its order logic accordingly. This is what allows TDR to be used in any direction from the UI.

For a complete guide on implementing trading modes in your own strategies, including code examples for each mode, partial positions, and common mistakes, see the Trading Modes guide under Best Practices.

Signal Delay Pattern

TDR uses 1-bar delayed execution for realistic backtesting:

// Store raw signal for next bar ctx.state.delayed.prevBuy = rawBuySignal; // Execute delayed signal from previous bar const buySignal = ctx.state.delayed.prevBuy; if (buySignal) { ctx.order.market('ASSET', 1, { signal: 'buy' }); }

Partial Position Sizing

Use partial entries and exits for sophisticated position management:

// Partial entry (5% of portfolio) if (preEntry && ctx.state.tradeState === 'flat') { ctx.order.market('ASSET', 0.05, { signal: 'preEntry' }); } // Partial exit (reduce position by 5%) if (highRiskTP && ctx.state.tradeState === 'long') { ctx.order.reduce('ASSET', 0.05, { signal: 'highRiskTP' }); }

Performance Notes

  • Best on 4h and daily timeframes
  • Strong in trending markets with pullbacks
  • PPO zones help avoid chasing extended moves
  • Partial signals allow gradual position building/reduction

Related

exampleadvancedtdrdonchianpporisktrendpartialqsl