Risk Management
Risk Management
Overview
INTUE's risk management framework provides comprehensive tools for protecting capital while maximizing return potential. This system operates at multiple levels to identify, measure, mitigate, and monitor trading risks.
Position Sizing Algorithms
Standard Position Sizing
// Risk-based position sizing
function calculatePositionSize({
accountSize,
riskPerTrade,
entryPrice,
stopLossPrice,
leverageMultiplier = 1
}) {
// Calculate risk amount in absolute terms
const riskAmount = accountSize * riskPerTrade;
// Calculate risk per unit
const riskPerUnit = Math.abs(entryPrice - stopLossPrice);
// Calculate raw position size
let positionSize = riskAmount / riskPerUnit;
// Apply leverage if using leverage products
positionSize = positionSize * leverageMultiplier;
return positionSize;
}
// Example usage
const positionSize = calculatePositionSize({
accountSize: 10000, // $10,000
riskPerTrade: 0.01, // 1% risk per trade
entryPrice: 28500,
stopLossPrice: 27075, // 5% stop loss
leverageMultiplier: 1 // No leverage
});
console.log(`Position size: ${positionSize} units`);
Kelly Criterion Sizing
// Kelly Criterion position sizing
function calculateKellyPositionSize({
accountSize,
winRate,
averageWin,
averageLoss,
maxKellyFraction = 0.5 // Kelly fraction limit to reduce volatility
}) {
// Calculate full Kelly Criterion
const kellyFraction = (winRate / averageLoss) - ((1 - winRate) / averageWin);
// Limit Kelly fraction to reduce volatility (Half Kelly)
const adjustedKellyFraction = Math.min(kellyFraction, maxKellyFraction);
// Ensure non-negative position size
const finalKellyFraction = Math.max(adjustedKellyFraction, 0);
// Calculate position size
const positionSize = accountSize * finalKellyFraction;
return positionSize;
}
// Example usage
const kellySize = calculateKellyPositionSize({
accountSize: 10000, // $10,000
winRate: 0.65, // 65% win rate
averageWin: 0.15, // 15% average win
averageLoss: 0.05, // 5% average loss
maxKellyFraction: 0.5 // Half Kelly
});
console.log(`Kelly position size: ${kellySize}`);
Volatility-Adjusted Sizing
// Volatility-adjusted position sizing
function calculateVolatilityAdjustedSize({
accountSize,
riskPerTrade,
assetVolatility, // Historical volatility (e.g., ATR)
volatilityMultiplier = 1,
referenceVolatility // Baseline volatility for normalization
}) {
// Calculate base risk amount
const riskAmount = accountSize * riskPerTrade;
// Calculate volatility adjustment factor
const volatilityRatio = referenceVolatility / assetVolatility;
const adjustmentFactor = Math.pow(volatilityRatio, volatilityMultiplier);
// Calculate adjusted position size
const positionSize = riskAmount * adjustmentFactor;
return positionSize;
}
// Example usage
const volatilitySize = calculateVolatilityAdjustedSize({
accountSize: 10000, // $10,000
riskPerTrade: 0.01, // 1% risk per trade
assetVolatility: 0.042, // 4.2% historical volatility
volatilityMultiplier: 1.5, // Overweight volatility adjustment
referenceVolatility: 0.03 // 3% reference volatility
});
console.log(`Volatility-adjusted position size: ${volatilitySize}`);
Drawdown Protection
Progressive Risk Reduction
// Progressive risk reduction based on drawdown
function calculateDrawdownAdjustedRisk({
baseRiskPerTrade,
currentDrawdown,
drawdownThreshold = 0.1, // 10% drawdown threshold
recoveryRate = 0.5 // Recovery rate coefficient
}) {
// If drawdown is below threshold, use base risk
if (currentDrawdown < drawdownThreshold) {
return baseRiskPerTrade;
}
// Calculate drawdown ratio beyond threshold
const excessDrawdown = currentDrawdown - drawdownThreshold;
// Calculate risk reduction factor (exponential reduction)
const reductionFactor = Math.exp(-recoveryRate * excessDrawdown);
// Apply reduction to base risk
const adjustedRisk = baseRiskPerTrade * reductionFactor;
return adjustedRisk;
}
// Example usage
const adjustedRisk = calculateDrawdownAdjustedRisk({
baseRiskPerTrade: 0.01, // 1% base risk
currentDrawdown: 0.15, // 15% current drawdown
drawdownThreshold: 0.1, // 10% threshold
recoveryRate: 0.5
});
console.log(`Adjusted risk per trade: ${adjustedRisk * 100}%`);
Circuit Breakers
// Trading circuit breaker implementation
function checkCircuitBreakers({
consecutiveLosses,
dailyLoss,
weeklyLoss,
maxConsecutiveLosses = 5,
maxDailyLoss = 0.05, // 5% max daily loss
maxWeeklyLoss = 0.1 // 10% max weekly loss
}) {
const breakers = {
consecutiveLossBreaker: consecutiveLosses >= maxConsecutiveLosses,
dailyLossBreaker: dailyLoss >= maxDailyLoss,
weeklyLossBreaker: weeklyLoss >= maxWeeklyLoss,
anyBreakerTriggered: false
};
// Check if any breaker is triggered
breakers.anyBreakerTriggered = breakers.consecutiveLossBreaker ||
breakers.dailyLossBreaker ||
breakers.weeklyLossBreaker;
return breakers;
}
// Example usage
const b
Recovery Mode
// Trading recovery mode parameters
function calculateRecoveryParameters({
currentDrawdown,
baseParameters,
recoveryThresholds = {
mild: 0.1, // 10% drawdown
moderate: 0.2, // 20% drawdown
severe: 0.3 // 30% drawdown
}
}) {
let recoveryMode = 'none';
let parameters = { ...baseParameters };
// Determine recovery mode based on drawdown
if (currentDrawdown >= recoveryThresholds.severe) {
recoveryMode = 'severe';
parameters.riskPerTrade = baseParameters.riskPerTrade * 0.25;
parameters.positionLimit = Math.floor(baseParameters.positionLimit * 0.3);
parameters.requiredConfidence = 0.9;
} else if (currentDrawdown >= recoveryThresholds.moderate) {
recoveryMode = 'moderate';
parameters.riskPerTrade = baseParameters.riskPerTrade * 0.5;
parameters.positionLimit = Math.floor(baseParameters.positionLimit * 0.5);
parameters.requiredConfidence = 0.8;
} else if (currentDrawdown >= recoveryThreshold
Correlation-Based Risk Adjustment
Portfolio Correlation Matrix
// Generate correlation matrix for assets
function generateCorrelationMatrix(assetReturns) {
const assets = Object.keys(assetReturns);
const matrix = {};
// Calculate correlation between each asset pair
for (const asset1 of assets) {
matrix[asset1] = {};
for (const asset2 of assets) {
// For the same asset, correlation is 1
if (asset1 === asset2) {
matrix[asset1][asset2] = 1;
continue;
}
// Calculate correlation coefficient
const returns1 = assetReturns[asset1];
const returns2 = assetReturns[asset2];
matrix[asset1][asset2] = calculateCorrelation(returns1, returns2);
}
}
return matrix;
}
// Calculate Pearson correlation coefficient
function calculateCorrelation(series1, series2) {
// Implementation of correlation calculation
// ...
return correlationCoefficient;
}
// Example usage
const correlationMatrix = generateCorrelationMatrix({
'BTC': [0.05, -0.02, 0.01, 0.03, -0.01],
'ETH': [0.06, -0.01, 0.02, 0.02, -0.02],
'SOL': [0.03, 0.01, 0.04, 0.02, -0.03],
'AVAX': [0.02, 0.01, 0.01, 0.05, -0.02]
});
console.log('Correlation matrix:', correlationMatrix);
Exposure Adjustment
// Adjust position sizing based on correlations
function adjustForCorrelation({
targetAsset,
proposedPositionSize,
currentPositions,
correlationMatrix,
correlationThreshold = 0.7, // Correlation threshold for adjustment
maxExposureMultiple = 1.5 // Maximum exposure multiple for correlated assets
}) {
// Calculate total correlated exposure
let correlatedExposure = 0;
for (const [asset, position] of Object.entries(currentPositions)) {
// Skip if same asset or correlation below threshold
if (asset === targetAsset ||
!correlationMatrix[targetAsset] ||
!correlationMatrix[targetAsset][asset] ||
Math.abs(correlationMatrix[targetAsset][asset]) < correlationThreshold) {
continue;
}
// Add to correlated exposure
correlatedExposure += position.size * correlationMatrix[targetAsset][asset];
}
// Calculate exposure ratio (correlated exposure / account size)
const exposureRatio = correlatedExposure / getAccountSize();
// Calculate adjustment factor
const adjustmentFactor = Math.max(0, 1 - (exposureRatio / maxExposureMultiple));
// Adjust position size
const adjustedPositionSize = proposedPositionSize * adjustmentFactor;
return adjustedPositionSize;
}
// Example usage
const adjustedSize = adjustForCorrelation({
targetAsset: 'SOL',
proposedPositionSize: 0.5, // 0.5 SOL
currentPositions: {
'BTC': { size: 0.02 },
'ETH': { size: 0.5 }
},
correlationMatrix: correlationMatrix,
correlationThreshold: 0.7,
maxExposureMultiple: 1.5
});
console.log(`Correlation-adjusted position size: ${adjustedSize}`);
Sector Diversification
// Calculate sector exposure
function calculateSectorExposure({
currentPositions,
assetSectors,
accountSize
}) {
const sectorExposure = {};
// Initialize sector exposure
for (const sector of new Set(Object.values(assetSectors))) {
sectorExposure[sector] = {
absoluteExposure: 0,
relativeExposure: 0,
assets: []
};
}
// Calculate exposure by sector
for (const [asset, position] of Object.entries(currentPositions)) {
const sector = assetSectors[asset] || 'unknown';
const exposure = position.value;
sectorExposure[sector].absoluteExposure += exposure;
sectorExposure[sector].assets.push(asset);
}
// Calculate relative exposure
for (const sector in sectorExposure) {
sectorExposure[sector].relativeExposure = sectorExposure[sector].absoluteExposure / accountSize;
}
return sectorExposure;
}
// Check sector limits
function checkSectorLimits({
targetAsset,
proposedPositionValue,
currentPositions,
assetSectors,
accountSize,
sectorLimits = {
'defi': 0.3, // 30% max exposure
'layer1': 0.4,
'gaming': 0.2,
'ai': 0.25
},
defaultLimit = 0.3 // Default limit for unlisted sectors
}) {
// Get asset sector
const sector = assetSectors[targetAsset] || 'unknown';
// Calculate current sector exposure
const exposure = calculateSectorExposure({
currentPositions,
assetSectors,
accountSize
});
// Get sector limit
const limit = s
Black Swan Event Protection
Volatility Outlier Detection
// Detect volatility outliers that could indicate black swan events
function detectVolatilityOutliers({
currentVolatility,
historicalVolatility,
lookbackPeriods = 30,
standardDeviations = 3,
minimumSamples = 10
}) {
// Ensure sufficient historical data
if (historicalVolatility.length < minimumSamples) {
return {
isOutlier: false,
message: 'Insufficient historical data'
};
}
// Calculate mean and standard deviation of historical volatility
const mean = calculateMean(historicalVolatility);
const stdDev = calculateStandardDeviation(historicalVolatility, mean);
// Calculate z-score for current volatility
const zScore = (currentVolatility - mean) / stdDev;
// Determine if current volatility is an outlier
const isOutlier = zScore > standardDeviations;
return {
isOutlier,
zScore,
threshold: standardDeviations,
currentVolatility,
mean,
stdDev,
message: isOutlier ? 'Volatility outlier detected' : 'Normal volatility levels'
};
}
// Helper functions for statistical calculations
function calculateMean(values) {
return values.reduce((sum, value) => sum + value, 0) / values.length;
}
function calculateStandardDeviation(values, mean) {
const squaredDifferences = values.map(value => Math.pow(value - mean, 2));
const variance = calculateMean(squaredDifferences);
return Math.sqrt(variance);
}
// Example usage
const volatilityCheck = detectVolatilityOutliers({
currentVolatility: 0.08, // 8% current volatility
historicalVolatility: [0.02, 0.025, 0.022, 0.03, 0.026, 0.024, 0.028, 0.027, 0.025, 0.023],
standardDeviations: 3
});
if (volatilityCheck.isOutlier) {
console.log(`WARNING: ${volatilityCheck.message}`);
Liquidity Monitoring
// Monitor market liquidity to detect potential issues
function assessMarketLiquidity({
currentLiquidity,
averageLiquidity,
bidAskSpread,
averageBidAskSpread,
orderBookDepth,
averageOrderBookDepth,
thresholds = {
liquidityRatio: 0.5, // 50% of average
spreadRatio: 2.0, // 2x average spread
depthRatio: 0.5 // 50% of average depth
}
}) {
// Calculate liquidity metrics
const liquidityRatio = currentLiquidity / averageLiquidity;
const spreadRatio = bidAskSpread / averageBidAskSpread;
const depthRatio = orderBookDepth / averageOrderBookDepth;
// Check for liquidity issues
const issues = {
lowLiquidity: liquidityRatio < thresholds.liquidityRatio,
wideBidAskSpread: spreadRatio > thresholds.spreadRatio,
lowOrderBookDepth: depthRatio < thresholds.depthRatio,
hasLiquidityIssue: false
};
// Determine if there's a liquidity issue
issues.hasLiquidityIssue = issues.lowLiquidity ||
issues.wideBidAskSpread ||
issues.lowOrderBookDepth;
// Calculate overall liquidity score (0-100)
const liquidityScore = calculateLiquidityScore(liquidityRatio, spreadRatio, depthRatio);
return {
issues,
metrics: {
liquidityRatio,
spreadRatio,
depthRatio
},
liquidityScore,
message: issues.hasLiquidityIssue ?
'Liquidity issues detected - adjust risk accordingly' :
'Normal liquidity conditions'
};
}
// Calculate liquidity score on a scale of 0-100
function calculateLiquidityScore(liquidityRatio, spreadRatio, depthRatio) {
// Normalize ratios to 0-100 scale
const normalizedLiquidity = Math.min(100, liquidityRatio * 100);
const normalizedSpread = Math.max(0, 100 - ((spreadRatio - 1) * 50));
const normalizedDepth = Math.min(100, depthRatio * 100);
// Weight the components
return (normalizedLiquidity * 0.4) + (normalizedSpread * 0.3) + (normalizedDepth * 0.3);
}
// Example usage
const liquidityAssessment = assessMarketLiquidity({
currentLiquidity: 2500000, // $2.5M
averageLiquidity: 5000000, // $5M average
bidAskSpread: 0.15, // 0.15%
averageBidAskSpread: 0.05, // 0.05% average
orderBookDepth: 1500000, // $1.5M
averageOrderBookDepth: 4000000 // $4M average
});
console.log(`Liquidity score: ${liquidityAssessment.liquidityScore.toFixed(2)}/100`);
console.log(`Assessment: ${liquidityAssessment.message}`);
if (liquidityAssessment.issues.hasLiquidityIssue) {
console.log('Specific issues:',
Object.entries(liquidityAssessment.issues)
.filter(([key, value]) => value === true && key !== 'hasLiquidityIssue')
.map(([key]) => key)
);
}
Tail Risk Hedging
// Implement tail risk hedging strategies
function implementTailRiskHedging({
portfolioValue,
riskAssessment,
volatilityIndex, // Market volatility index
volatilityAverage,
hedgingStrategies = {
options: true,
inverseFunds: true,
stablecoinAllocation: true
},
thresholds = {
volatilityRatio: 1.5,
riskScore: 75
}
}) {
// Determine if hedging is needed
const volatilityRatio = volatilityIndex / volatilityAverage;
const hedgingNeeded = volatilityRatio > thresholds.volatilityRatio ||
riskAssessment.score > thresholds.riskScore;
if (!hedgingNeeded) {
return {
hedgingNeeded: false,
message: 'No additional hedging required',
recommendations: []
};
}
// Calculate hedging allocations
const hedgingPercentage = calculateHedgingPercentage(volatilityRatio, riskAssessment.score);
const hedgingValue = portfolioValue * hedgingPercentage;
// Generate hedging recommendations
const recommendations = [];
if (hedgingStrategies.options) {
recommendations.push({
strategy: 'options',
type: 'put_options',
allocation: hedgingValue * 0.4,
details: `Purchase put options with strike price 10% below current market prices`
});
}
if (hedgingStrategies.inverseFunds) {
recommendations.push({
strategy: 'inverse_funds',
allocation: hedgingValue * 0.3,
details: `Allocate to inverse market ETFs or futures`
});
}
if (hedgingStrategies.stablecoinAllocation) {
recommendations.push({
strategy: 'stablecoin_allocation',
allocation: hedgingValue * 0.3,
details: `Increase stablecoin position to reduce market exposure`
});
}
return {
hedgingNeeded: true,
hedgingPercentage,
hedgingValue,
volatilityRatio,
riskScore: riskAssessment.score,
recommendations,
message: `Tail risk hedging recommended for ${(hedgingPercentage * 100).toFixed(2)}% of portfolio`
};
}
// Calculate appropriate hedging percentage
function calculateHedgingPercentage(volatilityRatio, riskScore) {
// Base hedging on greater of the two factors
const basePercentage = Math.max(
0.1 * (volatilityRatio - 1), // 10% per 1.0 volatility ratio above normal
0.005 * (riskScore - 50) // 0.5% per risk score point above 50
);
// Cap at 40% maximum hedging allocation
return Math.min(0.4, Math.max(0, basePercentage));
}
// Example usage
const hedgingPlan = implementTailRiskHedging({
portfolioValue: 100000, // $100,000
riskAssessment: {
score: 82 // High risk score
},
volatilityIndex: 30, // Current volatility
volatilityAverage: 18 // Average volatility
});
if (hedgingPlan.hedgingNeeded) {
console.log(hedgingPlan.message);
console.log('Recommended hedging strategies:');
hedgingPlan.recommendations.forEach(rec => {
console.log(`- ${rec.strategy}: $${rec.allocation.toFixed(2)}`);
console.log(` ${rec.details}`);
});
}
Integration with Agent Framework
// Integrate risk management with agent system
function integrateRiskManagement(agent, riskConfig) {
// Configure risk parameters
agent.setRiskParameters({
positionSizing: {
method: riskConfig.positionSizingMethod || 'fixed_risk',
riskPerTrade: riskConfig.riskPerTrade || 0.01,
maxPositionSize: riskConfig.maxPositionSize || 0.1
},
drawdownProtection: {
enabled: riskConfig.drawdownProtectionEnabled !== false,
thresholds: riskConfig.drawdownThresholds || {
moderate: 0.1,
severe: 0.2
},
recoveryRates: riskConfig.recoveryRates || {
moderate: 0.5,
severe: 0.25
}
},
correlationControl: {
enabled: riskConfig.correlationControlEnabled !== false,
threshold: riskConfig.correlationThreshold || 0.7,
maxExposure: riskConfig.maxCorrelatedExposure || 1.5
},
blackSwanProtection: {
enabled: riskConfig.blackSwanProtectionEnabled !== false,
volatilityMultiplier: riskConfig.volatilityMultiplier || 3,
liquidityMonitoring: riskConfig.liquidityMonitoringEnabled !== false
},
circuitBreakers: {
enabled: riskConfig.circuitBreakersEnabled !== false,
maxConsecutiveLosses: riskConfig.maxConsecutiveLosses || 5,
maxDailyLoss: riskConfig.maxDailyLoss || 0.05,
maxWeeklyLoss: riskConfig.maxWeeklyLoss || 0.1
}
});
// Hook into agent's trade execution pipeline
agent.registerTradeProcessor(async (trade, context) => {
// Apply risk management to trade
return applyRiskManagement(trade, context, agent.getRiskParameters());
});
// Set up regular risk assessment
agent.scheduleTask('risk-assessment', '1h', async () => {
const riskAssessment = await performRiskAssessment(agent);
agent.setRiskAssessment(riskAssessment);
if (riskAssessment.requiresAction) {
await implementRiskMitigations(agent, riskAssessment);
}
});
// Monitor for black swan events
agent.scheduleTask('black-swan-detection', '15m', async () => {
const volatilityCheck = await checkMarketVolatility(agent);
const liquidityCheck = await checkMarketLiquidity(agent);
if (volatilityCheck.isOutlier || liquidityCheck.hasLiquidityIssue) {
await implementEmergencyProtection(agent, {
volatilityEvent: volatilityCheck.isOutlier,
liquidityEvent: liquidityCheck.hasLiquidityIssue
});
}
});
// Log risk management integration
agent.log('info', 'Risk management system integrated', {
positionSizingMethod: agent.getRiskParameters().positionSizing.method,
circuitBreakersEnabled: agent.getRiskParameters().circuitBreakers.enabled
});
return {
status: 'integrated',
riskParameters: agent.getRiskParameters()
};
}
// Apply risk management to trade
async function applyRiskManagement(trade, context, riskParameters) {
// Implement risk management logic
// ...
return modifiedTrade;
}
// Perform risk assessment
async function performRiskAssessment(agent) {
// Implement risk assessment logic
// ...
return riskAssessment;
}
// Implement risk mitigations based on assessment
async function implementRiskMitigations(agent, riskAssessment) {
// Implement mitigation strategies
// ...
return mitigationResults;
}
// Check for black swan events
async function checkMarketVolatility(agent) {
// Implement volatility monitoring
// ...
return volatilityCheck;
}
// Check market liquidity
async function checkMarketLiquidity(agent) {
// Implement liquidity monitoring
// ...
return liquidityCheck;
}
// Implement emergency protection
async function implementEmergencyProtection(agent, eventData) {
// Implement emergency protection
// ...
return protectionResults;
}
Last updated