/**
* Dynamic Margin Calculation
* calculateDynamicMarginPercentage function
*/
import { Signal, ExternalData } from '../types'
import { TechnicalIndicators } from '../technical-indicators/aggregator'
export function calculateDynamicMarginPercentage(
indicators: TechnicalIndicators | null | undefined,
externalData: ExternalData | null | undefined,
signal: Signal,
entryPrice: number
): number {
// Base margin: 25% (minimum)
let marginPercent = 25
if (!indicators || !entryPrice || entryPrice <= 0) {
return marginPercent // Return minimum if no data
}
// 1. Volatility (ATR) - Lower volatility = higher margin (can be more aggressive)
const atr = indicators.atr || 0
if (atr > 0 && entryPrice > 0) {
const atrPercent = (atr / entryPrice) * 100
if (atrPercent < 1.0) {
marginPercent += 25 // Very low volatility: +25% margin
} else if (atrPercent < 2.0) {
marginPercent += 20 // Low volatility: +20% margin
} else if (atrPercent < 3.0) {
marginPercent += 15 // Medium volatility: +15% margin
} else {
marginPercent += 10 // High volatility: +10% margin
}
}
// 2. Trend Strength (ADX) - Stronger trend = higher margin
const adx = indicators.adx || 0
if (adx > 0) {
if (adx > 50) {
marginPercent += 20 // Very strong trend: +20% margin
} else if (adx >= 40) {
marginPercent += 15 // Strong trend: +15% margin
} else if (adx >= 25) {
marginPercent += 10 // Moderate trend: +10% margin
} else {
marginPercent += 5 // Weak trend: +5% margin
}
}
// 3. Confidence Score - Higher confidence = higher margin
const confidence = signal.confidence || 0
if (confidence > 0.7) {
marginPercent += 15 // Very high confidence: +15% margin
} else if (confidence >= 0.6) {
marginPercent += 10 // High confidence: +10% margin
} else if (confidence >= 0.5) {
marginPercent += 5 // Moderate confidence: +5% margin
}
// 4. Risk/Reward Ratio - Better R:R = higher margin
if (signal.take_profit && signal.stop_loss && entryPrice > 0) {
const profitDistance = Math.abs(signal.take_profit - entryPrice)
const lossDistance = Math.abs(entryPrice - signal.stop_loss)
if (lossDistance > 0) {
const riskRewardRatio = profitDistance / lossDistance
if (riskRewardRatio > 3.0) {
marginPercent += 15 // Excellent R:R (>3:1): +15% margin
} else if (riskRewardRatio >= 2.0) {
marginPercent += 10 // Good R:R (2-3:1): +10% margin
} else if (riskRewardRatio >= 1.5) {
marginPercent += 5 // Decent R:R (1.5-2:1): +5% margin
}
}
}
// 5. Market Structure (COC) - Clear structure = higher margin
const marketStructure = (externalData as any)?.marketStructure
if (marketStructure && marketStructure.coc) {
const coc = marketStructure.coc
if (coc.reversalSignal && coc.structureStrength > 70) {
marginPercent += 10 // Strong reversal signal: +10% margin
} else if (coc.structureStrength > 50) {
marginPercent += 5 // Clear structure: +5% margin
}
}
// 6. Volume Profile - Price at POC = higher margin
const volumeProfile = (externalData as any)?.volumeProfile
if (volumeProfile && volumeProfile.session && entryPrice > 0) {
const svp = volumeProfile.session
if (svp.poc && svp.poc > 0) {
const priceToPoc = Math.abs((entryPrice - svp.poc) / svp.poc) * 100
if (priceToPoc < 1.0) {
marginPercent += 10 // Price at POC: +10% margin
} else if (priceToPoc < 2.0) {
marginPercent += 5 // Price at VAH/VAL: +5% margin
}
}
}
// Clamp margin between 25% (minimum) and 100% (maximum)
return Math.max(25, Math.min(100, marginPercent))
}