Multi-Indicator Confluence Strategy
A robust strategy that requires multiple indicator confirmations before entering trades.
Strategy Overview
| Aspect | Details |
|---|---|
| Type | Confluence / Multi-Factor |
| Indicators | RSI, MACD, ADX, Bollinger Bands |
| Timeframes | 1h, 4h, 1d |
| Markets | All (Spot & Futures) |
| Difficulty | Advanced |
How It Works
- Scoring System: Each indicator contributes a bullish or bearish signal
- Confluence Threshold: Only trade when multiple indicators agree
- Dynamic Exits: Exit when signals reverse or threshold drops
This approach significantly reduces false signals by requiring multiple confirmations.
Complete Code
// ============================================
// MULTI-INDICATOR CONFLUENCE STRATEGY
// ============================================
// Requires multiple indicator confirmations
// before entering trades. Uses a scoring system
// to measure market conviction.
// ============================================
// ============================================
// PARAMETERS
// ============================================
const MIN_CONFLUENCE = td.config.getNumber('MIN_CONFLUENCE', 3);
const EXIT_CONFLUENCE = td.config.getNumber('EXIT_CONFLUENCE', 2);
const USE_RSI = td.config.getBoolean('USE_RSI', true);
const USE_MACD = td.config.getBoolean('USE_MACD', true);
const USE_ADX = td.config.getBoolean('USE_ADX', true);
const USE_BB = td.config.getBoolean('USE_BB', true);
const USE_EMA = td.config.getBoolean('USE_EMA', true);
const STOP_LOSS_PCT = td.config.getNumber('STOP_LOSS_PCT', 2);
const TAKE_PROFIT_PCT = td.config.getNumber('TAKE_PROFIT_PCT', 6);
const POSITION_SIZE = td.config.getNumber('POSITION_SIZE', 100);
const ENABLE_SHORTS = td.config.getBoolean('ENABLE_SHORTS', false);
// ============================================
// VALIDATION
// ============================================
if (td.market.candles.length < 50) {
td.utils.log('Waiting for sufficient data');
return;
}
// Count enabled indicators
const enabledIndicators = [USE_RSI, USE_MACD, USE_ADX, USE_BB, USE_EMA]
.filter(Boolean).length;
if (MIN_CONFLUENCE > enabledIndicators) {
td.utils.log('ERROR: MIN_CONFLUENCE exceeds enabled indicators');
return;
}
// ============================================
// HELPER FUNCTION
// ============================================
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;
}
// ============================================
// CALCULATE INDICATORS
// ============================================
const rsi = td.indicators.rsi;
const macd = td.indicators.macd;
const adx = td.indicators.adx;
const bb = td.indicators.bbands;
const ema50 = getIndicator('ema_50');
const ema200 = getIndicator('ema_200');
const price = td.market.price;
// ============================================
// SCORING SYSTEM
// ============================================
let bullScore = 0;
let bearScore = 0;
const signals = [];
// RSI Signals
if (USE_RSI) {
if (rsi < 35) {
bullScore++;
signals.push('RSI oversold');
} else if (rsi > 65) {
bearScore++;
signals.push('RSI overbought');
}
}
// MACD Signals
if (USE_MACD) {
if (macd.histogram > 0 && macd.trend === 'bullish') {
bullScore++;
signals.push('MACD bullish');
} else if (macd.histogram < 0 && macd.trend === 'bearish') {
bearScore++;
signals.push('MACD bearish');
}
}
// ADX Trend Strength & Direction
if (USE_ADX) {
if (adx.value > 25) {
if (adx.diPlus > adx.diMinus) {
bullScore++;
signals.push('ADX bullish trend');
} else {
bearScore++;
signals.push('ADX bearish trend');
}
}
}
// Bollinger Band Position
if (USE_BB) {
if (bb.percentB < 0.2) {
bullScore++;
signals.push('BB oversold');
} else if (bb.percentB > 0.8) {
bearScore++;
signals.push('BB overbought');
}
}
// EMA Trend
if (USE_EMA) {
if (price > ema50 && ema50 > ema200) {
bullScore++;
signals.push('EMA bullish alignment');
} else if (price < ema50 && ema50 < ema200) {
bearScore++;
signals.push('EMA bearish alignment');
}
}
// ============================================
// ENTRY LOGIC
// ============================================
if (!td.position.hasPosition) {
// LONG ENTRY
if (bullScore >= MIN_CONFLUENCE) {
const stopLoss = td.utils.round(price * (1 - STOP_LOSS_PCT / 100), 2);
const takeProfit = td.utils.round(price * (1 + TAKE_PROFIT_PCT / 100), 2);
td.trade.buy({
amountPercent: POSITION_SIZE,
stopLoss: stopLoss,
takeProfit: takeProfit,
reason: `Bull confluence: ${bullScore}/${enabledIndicators}`
});
td.utils.log('LONG ENTRY', {
bullScore: bullScore,
signals: signals,
price: price
});
td.state.set('entryScore', bullScore);
td.state.set('entrySide', 'long');
}
// SHORT ENTRY
if (ENABLE_SHORTS && bearScore >= MIN_CONFLUENCE) {
const stopLoss = td.utils.round(price * (1 + STOP_LOSS_PCT / 100), 2);
const takeProfit = td.utils.round(price * (1 - TAKE_PROFIT_PCT / 100), 2);
td.trade.sell({
amountPercent: POSITION_SIZE,
stopLoss: stopLoss,
takeProfit: takeProfit,
reason: `Bear confluence: ${bearScore}/${enabledIndicators}`
});
td.utils.log('SHORT ENTRY', {
bearScore: bearScore,
signals: signals,
price: price
});
td.state.set('entryScore', bearScore);
td.state.set('entrySide', 'short');
}
}
// ============================================
// EXIT LOGIC
// ============================================
if (td.position.hasPosition) {
const entrySide = td.state.get('entrySide');
// Exit long when bear signals strengthen
if (entrySide === 'long' && bearScore >= EXIT_CONFLUENCE) {
td.trade.close(`Bear confluence reached: ${bearScore}`);
td.utils.log('EXIT LONG', {
bearScore: bearScore,
pnl: td.position.pnl,
signals: signals
});
}
// Exit short when bull signals strengthen
if (entrySide === 'short' && bullScore >= EXIT_CONFLUENCE) {
td.trade.close(`Bull confluence reached: ${bullScore}`);
td.utils.log('EXIT SHORT', {
bullScore: bullScore,
pnl: td.position.pnl,
signals: signals
});
}
// Trailing stop based on score degradation
const entryScore = td.state.get('entryScore', MIN_CONFLUENCE);
const currentScore = entrySide === 'long' ? bullScore : bearScore;
if (currentScore < entryScore - 1 && td.position.pnlPercent > 0) {
td.trade.close('Confluence weakening with profit');
td.utils.log('EXIT - Score degradation', {
entryScore: entryScore,
currentScore: currentScore,
pnl: td.position.pnl
});
}
}
// ============================================
// DEBUG LOGGING
// ============================================
const DEBUG = td.config.getBoolean('DEBUG_MODE', false);
if (DEBUG) {
td.utils.log('Confluence Scores', {
bullScore: bullScore,
bearScore: bearScore,
minRequired: MIN_CONFLUENCE,
signals: signals,
indicators: {
rsi: rsi.toFixed(2),
macdHistogram: macd.histogram.toFixed(4),
adx: adx.value.toFixed(2),
bbPercentB: bb.percentB.toFixed(3),
priceVsEma50: price > ema50 ? 'above' : 'below'
}
});
}
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| MIN_CONFLUENCE | Number | 3 | Minimum signals to enter |
| EXIT_CONFLUENCE | Number | 2 | Opposite signals to exit |
| USE_RSI | Boolean | true | Include RSI signals |
| USE_MACD | Boolean | true | Include MACD signals |
| USE_ADX | Boolean | true | Include ADX signals |
| USE_BB | Boolean | true | Include Bollinger Band signals |
| USE_EMA | Boolean | true | Include EMA trend signals |
| STOP_LOSS_PCT | Number | 2 | Stop loss percentage |
| TAKE_PROFIT_PCT | Number | 6 | Take profit percentage |
| ENABLE_SHORTS | Boolean | false | Allow short positions |
Scoring System Explained
Each indicator can add one point to bull or bear score:
| Indicator | Bullish Signal | Bearish Signal |
|---|---|---|
| RSI | RSI < 35 | RSI > 65 |
| MACD | Histogram > 0, bullish | Histogram < 0, bearish |
| ADX | DI+ > DI- (trending up) | DI- > DI+ (trending down) |
| BB | %B < 0.2 (near lower) | %B > 0.8 (near upper) |
| EMA | Price > EMA50 > EMA200 | Price < EMA50 < EMA200 |
Maximum score: 5 (if all indicators enabled)
Recommended Settings
Conservative (High Confluence)
MIN_CONFLUENCE: 4
EXIT_CONFLUENCE: 2
STOP_LOSS_PCT: 1.5
TAKE_PROFIT_PCT: 4
ENABLE_SHORTS: false
Moderate
MIN_CONFLUENCE: 3
EXIT_CONFLUENCE: 2
STOP_LOSS_PCT: 2
TAKE_PROFIT_PCT: 6
Aggressive (More Trades)
MIN_CONFLUENCE: 2
EXIT_CONFLUENCE: 2
ENABLE_SHORTS: true
Performance Tips
- Higher confluence = fewer trades but higher quality
- Lower confluence = more trades but more noise
- ADX filter is crucial - prevents trading in choppy markets
- EMA alignment - ensures you trade with the major trend
- Test on higher timeframes first (4h, 1d)
Customization Ideas
Add Volume Confirmation
// Add volume to scoring
const avgVolume = td.market.candles.slice(-20)
.reduce((s, c) => s + c.volume, 0) / 20;
const currentVol = td.market.candles.slice(-1)[0].volume;
if (currentVol > avgVolume * 1.5) {
// High volume confirms the move
if (bullScore > 0) bullScore++;
if (bearScore > 0) bearScore++;
signals.push('High volume confirmation');
}
Weighted Scoring
// Give more weight to certain indicators
const weights = {
rsi: 1,
macd: 1.5, // MACD is more important
adx: 2, // Trend confirmation is critical
bb: 1,
ema: 1.5
openGraph: { title: 'Multi-Indicator Example', description: 'Example multi-indicator custom trading strategy.' },
};
// In RSI section:
if (rsi < 35) bullScore += weights.rsi;
// In MACD section:
if (macd.histogram > 0) bullScore += weights.macd;
// Adjust MIN_CONFLUENCE accordingly (e.g., 4.5 instead of 3)
Next Steps
- Advanced Patterns - Complex strategies
- Best Practices - Guidelines
- Publishing - Share your strategy