← Back to Blog
RISK MANAGEMENT

Portfolio Risk Management for Algorithmic Traders on LMEX

May 27, 2026 · 6 min read · LMEX.AI

Risk management for an algorithmic trading portfolio isn't the same as risk management for a single strategy. When you run multiple strategies across multiple markets, new failure modes emerge — correlation spikes, simultaneous drawdowns, exposure aggregation that nobody planned for. Single-strategy thinking doesn't catch these.


This article walks through how to think about portfolio-level risk, what limits to set, and how to detect when something's going wrong before it becomes a disaster.


The portfolio vs the individual strategy


A trader running a trend-following bot on BTC-PERP knows what to monitor: position size, drawdown, parameter stability. A trader running 5 trend bots across BTC, ETH, SOL, BNB, AVAX has the same metrics per bot, plus new metrics across the portfolio:


  • **Total exposure**: aggregate notional across all positions
  • **Net direction**: aggregate long vs short
  • **Effective leverage**: total exposure divided by account equity
  • **Correlation-adjusted risk**: real diversification benefit, not just count of positions

  • These portfolio metrics drive risk decisions that individual strategy metrics can't capture. A trader who only watches individual strategies might be carrying 5× leverage in aggregate without knowing it — because each individual strategy looks fine at 1× margin.


    The correlation trap


    The biggest portfolio-level failure mode: assumed diversification that doesn't actually exist.


    Run trend bots on BTC, ETH, SOL, BNB, AVAX. In normal markets, these correlate at 0.5-0.7 — decent diversification. During stress events, correlation jumps to 0.9+. Your 5-position "diversified" portfolio behaves like 5 bets on the same thing.


    The math: at 0.7 correlation, 5 positions have the risk of about 3 independent positions. At 0.9 correlation, 5 positions have the risk of about 1.5 independent positions. At 1.0 correlation, you have 1 position with bigger size.


    Practical implication: monitor real-time correlation. When correlations spike (typically during volatility events), reduce position sizes across all bots simultaneously. The portfolio you have is not the portfolio you thought you had.


    Position sizing for a portfolio


    A simple approach: divide your account into "risk units" and allocate them across strategies and markets.


    Example with \$100,000 account:

  • Risk per unit: \$1,000 (1% of account)
  • Total risk units available: 10 (10% of account at risk simultaneously)
  • Per-strategy limit: 4 risk units
  • Per-market limit: 4 risk units (regardless of strategies running)

  • This gives flexibility — you can put more risk on one strategy or one market temporarily — but with hard caps that prevent any single concentration.


    A more sophisticated approach uses inverse-volatility weighting: more capital to lower-volatility strategies, less to higher-volatility ones. This produces more stable portfolio equity curves but is harder to maintain.


    Setting portfolio-level limits


    A few limits that should be hard-coded in your portfolio risk system:


    **Max total leverage.** Effective leverage across all positions and margin requirements. For most retail portfolios, 2-3x is plenty. Higher leverage compounds normal drawdowns into catastrophic ones.


    **Max single-market exposure.** No more than X% of account in any one market, regardless of how many strategies are trading it.


    **Max aggregate directional exposure.** If running 5 trend bots and all are long crypto majors, you have a single directional bet. Cap aggregate long or short exposure at some fraction of account.


    **Daily loss limit.** When portfolio drawdown for a single day exceeds X% (typically 3-5%), pause new entries until the next day. Prevents single bad days from compounding.


    **Weekly loss limit.** Similar but for the week. Typically 7-10%. When hit, reduce all position sizes by 50% until back to peak.


    These limits should fire automatically. Manual override during drawdowns is the single most common mistake — humans rationalise "this is different" exactly when they shouldn't.


    A Python implementation


    A simple portfolio risk monitor:


    import ccxt
    from collections import defaultdict
    
    exchange = ccxt.lmex({'apiKey': '...', 'secret': '...'})
    
    class PortfolioRisk:
        def __init__(self, account_value, max_leverage=3, max_per_market_pct=0.2,
                     daily_loss_limit_pct=0.04, weekly_loss_limit_pct=0.08):
            self.account_value = account_value
            self.max_leverage = max_leverage
            self.max_per_market_pct = max_per_market_pct
            self.daily_loss_limit_pct = daily_loss_limit_pct
            self.weekly_loss_limit_pct = weekly_loss_limit_pct
            self.peak_equity = account_value
        
        def get_current_state(self):
            positions = exchange.fetch_positions()
            balance = exchange.fetch_balance()
            
            total_exposure = sum(abs(p['notional']) for p in positions if p['notional'])
            per_market_exposure = defaultdict(float)
            net_directional = 0
            
            for p in positions:
                if not p['notional']:
                    continue
                per_market_exposure[p['symbol']] += abs(p['notional'])
                net_directional += p['notional'] if p['side'] == 'long' else -p['notional']
            
            current_equity = balance['total']['USDT']
            self.peak_equity = max(self.peak_equity, current_equity)
            drawdown = (current_equity - self.peak_equity) / self.peak_equity
            
            return {
                'equity': current_equity,
                'total_exposure': total_exposure,
                'leverage': total_exposure / current_equity if current_equity > 0 else 0,
                'per_market_exposure': dict(per_market_exposure),
                'net_directional': net_directional,
                'drawdown_pct': drawdown,
            }
        
        def can_open_new_position(self, symbol, notional):
            state = self.get_current_state()
            
            # Check leverage limit
            new_leverage = (state['total_exposure'] + notional) / state['equity']
            if new_leverage > self.max_leverage:
                return False, f"Would exceed max leverage {self.max_leverage}"
            
            # Check per-market limit
            current_market = state['per_market_exposure'].get(symbol, 0)
            new_market_exposure = current_market + notional
            if new_market_exposure / state['equity'] > self.max_per_market_pct:
                return False, f"Would exceed per-market limit for {symbol}"
            
            # Check daily loss limit
            if state['drawdown_pct'] < -self.daily_loss_limit_pct:
                return False, f"Daily loss limit hit: {state['drawdown_pct']*100:.1f}%"
            
            return True, "OK"

    Every order request goes through `can_open_new_position()` first. If it returns False, the order is rejected with a reason. This protects you from yourself during drawdowns.


    Detecting strategy degradation


    A new failure mode at the portfolio level: strategies that worked degrading silently while other strategies continue to work, masking the issue in aggregate metrics.


    Detection: track per-strategy P&L over time. If one strategy's rolling 30-day return turns negative while the rest stay positive, that strategy may have stopped working. Reduce its allocation or shut it down.


    Don't wait for portfolio-level drawdown — by then you've lost meaningful capital to a strategy you should have killed earlier.


    What to do when limits hit


    Hitting risk limits isn't a failure — it's the system working as designed. The discipline is in responding correctly:


    **Daily limit hit:** Pause new entries for the rest of the day. Existing positions continue with their normal exit logic. Resume normally next day.


    **Weekly limit hit:** Reduce position sizes by 50%. Continue at reduced size until equity recovers to within 3% of previous peak.


    **Strategy-specific degradation:** Reduce that strategy's allocation by 50%. If it continues to underperform for another 30 days, shut it down entirely.


    The hardest part is psychological: actually following the rules when emotion says to keep pushing. Build the rules into automated systems so the human can't override them in the heat of the moment.


    Frequently Asked Questions


    Q: How many strategies should I run in parallel?

    Start with 1-2 to understand individual behaviour. Expand to 3-5 once you have stable systems. Beyond 5-7, marginal benefit diminishes and operational complexity increases sharply.


    Q: Should all strategies have the same risk allocation?

    No. Higher-confidence strategies (longer track record, stronger statistical edge) get larger allocations. New strategies get smaller allocations until proven. Re-allocate quarterly based on rolling performance.


    Q: What's a reasonable max portfolio drawdown to plan for?

    25-30% as the realistic worst case for most retail portfolios. If you can't psychologically survive a 30% drawdown, reduce position sizes until you can. Drawdowns happen; the question is whether you stay in the game through them.


    Q: How do I handle correlated markets?

    Two ways: (1) cap aggregate exposure across correlated markets, (2) use smaller per-market allocations when running multiple correlated markets. Don't pretend 5 long crypto positions is diversified — it isn't during stress events.


    Related Articles


    → Why Most Trading Bots Fail (And What the Survivors Get Right)
    → The Math of Drawdown Recovery (And Why It Should Terrify You)
    → Kelly Criterion: Mathematically Optimal Position Sizing for LMEX Traders
    ← All ArticlesBuild a Bot →