Multi-Timeframe Analysis
TradeStaq supports multi-timeframe (MTF) analysis, allowing your strategies to access indicators and price data from multiple timeframes simultaneously.
Overview
Multi-timeframe analysis enables:
- Higher timeframe confirmation - Confirm entries with longer-term trends
- Multiple perspectives - See market structure across timeframes
- Better entries - Time entries on lower timeframes
- Reduced noise - Filter signals with higher timeframe context
Enabling Multi-Timeframe
Bot Configuration
When creating or editing a bot, enable MTF in settings:
{
"mtfConfig": {
"enabled": true,
"timeframes": ["4h", "1d"],
"includeIndicators": true
}
}
Configuration Options
| Option | Type | Description |
|---|---|---|
enabled | boolean | Enable MTF data loading |
timeframes | string[] | Additional timeframes to load |
includeIndicators | boolean | Pre-calculate indicators for each timeframe |
candleLimit | number | Number of candles per timeframe (default: 200) |
Available Timeframes
1m,5m,15m,30m- Intraday1h,4h- Short-term1d,1w- Long-term
The td.mtf Object
Access multi-timeframe data through td.mtf:
td.mtf = {
// Get indicators for a specific timeframe
indicators(timeframe: string): IndicatorValues | null;
// Get OHLCV candles for a specific timeframe
candles(timeframe: string): OHLCV[];
// Get ticker data (last candle OHLC)
ticker(timeframe: string): { high, low, open, close } | null;
// List available timeframes
available(): string[];
// Check if timeframe is loaded
has(timeframe: string): boolean;
// The primary (bot configured) timeframe
primary: string;
// Raw MTF data for advanced access
data: Record<string, MTFData>;
}
Accessing MTF Indicators
Basic Usage
// Your primary timeframe indicators (e.g., 1h)
const rsi1h = td.indicators.rsi;
const macd1h = td.indicators.macd;
// 4-hour timeframe indicators
const rsi4h = td.mtf.indicators('4h')?.rsi;
const macd4h = td.mtf.indicators('4h')?.macd;
// Daily timeframe indicators
const rsiDaily = td.mtf.indicators('1d')?.rsi;
const adxDaily = td.mtf.indicators('1d')?.adx;
Safe Access Pattern
// Always check if timeframe is available
if (td.mtf.has('4h')) {
const htfIndicators = td.mtf.indicators('4h');
if (htfIndicators) {
const rsi4h = htfIndicators.rsi;
const trend4h = htfIndicators.macd.trend;
// Use indicators...
}
}
All Available Indicators per Timeframe
Each timeframe has the full indicator set:
const htf = td.mtf.indicators('4h');
// All these are available:
htf.rsi // RSI value
htf.rsiArray // RSI history
htf.macd // { line, signal, histogram, trend }
htf.atr // ATR value
htf.atrArray // ATR history
htf.bbands // { upper, middle, lower, width, percentB }
htf.adx // { value, diPlus, diMinus, trend }
htf.stochastic // { k, d, zone }
htf.pivots // { pivot, r1, r2, r3, s1, s2, s3 }
htf.mfi // Money Flow Index
// Custom indicators - use helper function for safe access
function getHtfIndicator(htf, key) {
const val = htf?.custom?.[key];
if (val === undefined || val === null) return 0;
if (Array.isArray(val)) return val[val.length - 1];
return val;
}
getHtfIndicator(htf, 'ema_20') // EMA with period 20
getHtfIndicator(htf, 'sma_50') // SMA with period 50
Accessing MTF Candles
// Get candles for higher timeframe
const candles4h = td.mtf.candles('4h');
const candlesDaily = td.mtf.candles('1d');
// Latest candle
const last4hCandle = candles4h[candles4h.length - 1];
const lastDailyCandle = candlesDaily[candlesDaily.length - 1];
// Use ticker for quick access to last candle OHLC
const ticker4h = td.mtf.ticker('4h');
if (ticker4h) {
const { high, low, open, close } = ticker4h;
}
MTF Strategy Patterns
Pattern 1: Higher Timeframe Trend Filter
Only trade in direction of higher timeframe trend.
// Check 4h trend
const htfIndicators = td.mtf.indicators('4h');
const htfTrend = htfIndicators?.macd.trend;
const htfAdx = htfIndicators?.adx;
// Only long if 4h is bullish with strong trend
const bullishHTF = htfTrend === 'bullish' && htfAdx?.trend === 'strong';
const bearishHTF = htfTrend === 'bearish' && htfAdx?.trend === 'strong';
// Primary timeframe entry signal
const rsi = td.indicators.rsi;
const oversold = rsi < 30;
const overbought = rsi > 70;
// Trade with HTF confirmation
if (!td.position.hasPosition) {
if (oversold && bullishHTF) {
td.trade.buy({
amountPercent: 50,
reason: 'RSI oversold + 4h bullish trend'
});
}
if (overbought && bearishHTF) {
td.trade.sell({
amountPercent: 50,
reason: 'RSI overbought + 4h bearish trend'
});
}
}
Pattern 2: Multi-Timeframe RSI Confluence
Enter when RSI is oversold on multiple timeframes.
const rsi1h = td.indicators.rsi;
const rsi4h = td.mtf.indicators('4h')?.rsi || 50;
const rsiDaily = td.mtf.indicators('1d')?.rsi || 50;
// Count oversold timeframes
let oversoldCount = 0;
if (rsi1h < 30) oversoldCount++;
if (rsi4h < 35) oversoldCount++;
if (rsiDaily < 40) oversoldCount++;
// Strong buy signal when multiple timeframes oversold
if (!td.position.hasPosition && oversoldCount >= 2) {
td.trade.buy({
amountPercent: 50,
stopLoss: td.market.price * 0.97,
reason: `${oversoldCount} timeframes oversold`
});
}
// Log confluence
td.utils.log('RSI Confluence', {
rsi1h,
rsi4h,
rsiDaily,
oversoldCount
});
Pattern 3: Timeframe Alignment Entry
Entry when trend aligns across all timeframes.
// Get trends from multiple timeframes
const trend1h = td.indicators.macd.trend;
const trend4h = td.mtf.indicators('4h')?.macd.trend;
const trendDaily = td.mtf.indicators('1d')?.macd.trend;
// Check alignment
const allBullish = trend1h === 'bullish' &&
trend4h === 'bullish' &&
trendDaily === 'bullish';
const allBearish = trend1h === 'bearish' &&
trend4h === 'bearish' &&
trendDaily === 'bearish';
// Only trade when fully aligned
if (!td.position.hasPosition) {
if (allBullish && td.indicators.rsi < 50) {
td.trade.buy({
amountPercent: 75, // Higher confidence = bigger size
reason: 'All timeframes bullish aligned'
});
}
if (allBearish && td.indicators.rsi > 50) {
td.trade.sell({
amountPercent: 75,
reason: 'All timeframes bearish aligned'
});
}
}
Pattern 4: Daily Support/Resistance
Use daily pivot points for entry/exit levels.
// Get daily pivots
const dailyPivots = td.mtf.indicators('1d')?.pivots;
const currentPrice = td.market.price;
if (dailyPivots && !td.position.hasPosition) {
const { pivot, s1, s2, r1, r2 } = dailyPivots;
// Long near support
if (currentPrice <= s1 * 1.005 && td.indicators.rsi < 35) {
td.trade.buy({
amountPercent: 50,
stopLoss: s2 * 0.995,
takeProfit: pivot,
reason: `Long at daily S1 (${s1.toFixed(2)})`
});
}
// Short near resistance
if (currentPrice >= r1 * 0.995 && td.indicators.rsi > 65) {
td.trade.sell({
amountPercent: 50,
stopLoss: r2 * 1.005,
takeProfit: pivot,
reason: `Short at daily R1 (${r1.toFixed(2)})`
});
}
}
Pattern 5: ATR-Based Position Sizing with HTF
Use higher timeframe ATR for volatility-adjusted sizing.
// Use 4h ATR for more stable volatility reading
const atr4h = td.mtf.indicators('4h')?.atr || td.indicators.atr;
const entryPrice = td.market.price;
// Calculate stop based on 4h ATR
const stopDistance = atr4h * 1.5;
const stopLoss = entryPrice - stopDistance;
const takeProfit = entryPrice + (stopDistance * 2);
// Risk-based entry
if (!td.position.hasPosition && td.indicators.rsi < 30) {
td.trade.buyRisk({
riskPercent: 2,
stopLoss,
takeProfit,
reason: 'Risk entry with 4h ATR stops'
});
}
Complete MTF Strategy
// ═══════════════════════════════════════════════════════════════
// Multi-Timeframe Trend Following Strategy
// Primary: 1h | Confirmation: 4h | Bias: Daily
// ═══════════════════════════════════════════════════════════════
// ─── Configuration ───────────────────────────────────────────────
const RSI_OVERSOLD = td.config.getNumber('RSI_OVERSOLD', 30);
const RSI_OVERBOUGHT = td.config.getNumber('RSI_OVERBOUGHT', 70);
const RISK_PERCENT = td.config.getNumber('RISK_PERCENT', 2);
// ─── Helper for custom indicators ────────────────────────────────
function getIndicator(key) {
const val = td.indicators.custom[key];
if (val === undefined || val === null) return 0;
if (Array.isArray(val)) return val[val.length - 1];
return val;
}
// ─── Get Multi-Timeframe Data ────────────────────────────────────
const primary = {
rsi: td.indicators.rsi,
macd: td.indicators.macd,
atr: td.indicators.atr,
ema9: getIndicator('ema_9'),
ema21: getIndicator('ema_21'),
openGraph: { title: 'Multi-Timeframe Analysis', description: 'How to use multiple timeframes in custom strategies.' },
};
const htf4h = td.mtf.indicators('4h');
const htfDaily = td.mtf.indicators('1d');
// Ensure MTF data is available
if (!htf4h || !htfDaily) {
td.utils.log('MTF data not available, skipping');
return;
}
// ─── Define Trend Bias ───────────────────────────────────────────
const dailyTrend = htfDaily.macd.trend;
const htfTrend = htf4h.macd.trend;
const htfTrendStrong = htf4h.adx.trend === 'strong';
const bullishBias = dailyTrend === 'bullish' || htfTrend === 'bullish';
const bearishBias = dailyTrend === 'bearish' || htfTrend === 'bearish';
// ─── Entry Logic ─────────────────────────────────────────────────
if (!td.position.hasPosition) {
// EMA crossover on primary timeframe
const ema9 = getIndicator('ema_9');
const ema21 = getIndicator('ema_21');
const prevEma9 = td.state.get('prevEma9', ema9);
const prevEma21 = td.state.get('prevEma21', ema21);
const emaCrossUp = prevEma9 <= prevEma21 && ema9 > ema21;
const emaCrossDown = prevEma9 >= prevEma21 && ema9 < ema21;
// Store for next spin
td.state.set('prevEma9', ema9);
td.state.set('prevEma21', ema21);
// Long entry
if (emaCrossUp && bullishBias && primary.rsi < 60) {
const atrStop = primary.atr * 1.5;
td.trade.buyRisk({
riskPercent: RISK_PERCENT,
stopLoss: td.market.price - atrStop,
takeProfit: td.market.price + (atrStop * 2),
reason: `Long: EMA cross + ${dailyTrend} daily + ${htfTrend} 4h`
});
td.utils.log('Long Entry', {
rsi: primary.rsi,
dailyTrend,
htfTrend,
htfTrendStrong
});
}
// Short entry
if (emaCrossDown && bearishBias && primary.rsi > 40) {
const atrStop = primary.atr * 1.5;
td.trade.sellRisk({
riskPercent: RISK_PERCENT,
stopLoss: td.market.price + atrStop,
takeProfit: td.market.price - (atrStop * 2),
reason: `Short: EMA cross + ${dailyTrend} daily + ${htfTrend} 4h`
});
}
}
// ─── Position Management ─────────────────────────────────────────
if (td.position.hasPosition) {
const profit = td.position.pnlPercent;
const side = td.position.side;
// Exit if higher timeframe trend reverses
const trendReversed =
(side === 'long' && htfTrend === 'bearish' && htfTrendStrong) ||
(side === 'short' && htfTrend === 'bullish' && htfTrendStrong);
if (trendReversed && profit > 0) {
td.trade.close('HTF trend reversed');
}
// Move to breakeven at 2% profit
if (profit >= 2 && !td.state.get('breakeven')) {
td.trade.breakeven({ breakevenOffset: 0.1 });
td.state.set('breakeven', true);
}
// Scale out at profit targets
if (profit >= 3 && !td.state.get('scaled1')) {
td.trade.close('Scale out 33% at 3%');
td.state.set('scaled1', true);
}
}
// ─── Logging ─────────────────────────────────────────────────────
td.utils.log('MTF Analysis', {
primary: {
rsi: primary.rsi.toFixed(2),
macdTrend: primary.macd.trend,
},
htf4h: {
rsi: htf4h.rsi.toFixed(2),
macdTrend: htf4h.macd.trend,
adxTrend: htf4h.adx.trend,
},
daily: {
rsi: htfDaily.rsi.toFixed(2),
macdTrend: htfDaily.macd.trend,
},
bias: bullishBias ? 'BULLISH' : bearishBias ? 'BEARISH' : 'NEUTRAL'
});
Best Practices
1. Don't Over-Complicate
// Good: 2-3 timeframes
const timeframes = ['4h', '1d'];
// Avoid: Too many timeframes causes confusion
const timeframes = ['5m', '15m', '30m', '1h', '4h', '1d', '1w'];
2. Use HTF for Direction, LTF for Timing
// Daily/4h for trend direction
const trendDirection = htfDaily.macd.trend;
// 1h/15m for entry timing
const entrySignal = td.indicators.rsi < 30;
// Combine both
if (trendDirection === 'bullish' && entrySignal) {
td.trade.buy();
}
3. Confirm with Multiple Indicators
// Don't rely on single HTF indicator
const htfBullish =
htf4h.macd.trend === 'bullish' &&
htf4h.rsi > 50 &&
htf4h.adx.value > 25;
4. Handle Missing Data
// Always check for null
const htfRsi = td.mtf.indicators('4h')?.rsi;
if (htfRsi === undefined || htfRsi === null) {
td.utils.log('HTF data missing, using default');
return; // or use fallback
}
Troubleshooting
MTF Data Not Available
Cause: MTF not enabled in bot config or timeframes not specified.
Solution: Check bot settings:
{
"mtfConfig": {
"enabled": true,
"timeframes": ["4h", "1d"],
"includeIndicators": true
}
}
Indicators Returning null
Cause: Insufficient candle data for indicator calculation.
Solution: Use safe access with fallbacks:
const htfRsi = td.mtf.indicators('4h')?.rsi ?? 50;
Performance Issues
Cause: Too many timeframes or indicators.
Solution: Limit to 2-3 additional timeframes and use includeIndicators: false if you only need candle data.
S/R Zone Analysis (td.zones)
In addition to MTF indicators, TradeStaq offers automatic multi-timeframe support and resistance zone analysis. When enabled in the Multi-Timeframe Setup step, the platform:
- Dynamically selects 3 candle timeframes (short, medium, long) from your exchange
- Generates up to 20 time intervals spanning from intraday to yearly windows
- Computes classic pivot points (P, S1-S3, R1-R3) for each interval
- Checks if the current price is near any S/R level
Enabling Zones
Enable S/R Zone Analysis in the strategy wizard's Multi-Timeframe Setup step (same step as MTF configuration). Configure:
- Proximity Type:
atr(volatility-based),percentage(fixed %), orboth - ATR Multiplier: How close price must be to count as "near" (uses primary TF ATR)
- % Threshold: Fixed percentage proximity threshold
Quick Example
const zones = td.zones;
if (!zones) return; // Not enabled
const supportDepth = zones.withinSupportCount; // 0 to zones.totalIntervals
const resistanceDepth = zones.withinResistanceCount;
// Buy near strong multi-timeframe support confluence
if (!td.position.hasPosition && supportDepth >= 5 && td.indicators.rsi < 40) {
td.trade.buy({
amountPercent: 5,
stopLoss: zones.strongestSupport * 0.99,
takeProfit: zones.strongestResistance,
reason: `Support confluence: ${supportDepth}/${zones.totalIntervals}`
});
}
For full details on td.zones properties, see the TD API Reference.
Next Steps
- Advanced Signals - DCA, trailing, grid
- Indicators Reference - All available indicators
- Best Practices - Strategy guidelines
- Backtesting - Test your MTF strategies