Risk Management for Algorithmic Trading

Position sizing formulas, maximum drawdown limits, correlation risk, and building risk controls into your EAs.

Why Risk Management is Everything

A strategy with a 90% win rate can still blow up an account if risk management is wrong. Conversely, a strategy with only a 40% win rate can be consistently profitable with proper position sizing. Risk management is not optional — it is the single most important factor in long-term trading survival.

As an algorithmic trader, you have an advantage: you can hardcode risk rules into your EA, making them impossible to override in the heat of the moment.

The 1-2% Rule

Never risk more than 1-2% of your account on a single trade. This ensures that a string of losses (which is inevitable) does not destroy your account:

// With 1% risk, you can survive 100 consecutive losses
// and still have 36.6% of your account left
// With 5% risk, 100 losses leaves you with 0.59%

input double RiskPercent = 1.0;  // Risk Per Trade (%)

Position Sizing Formula

Calculate lot size based on your risk percentage and stop-loss distance:

double CalculatePositionSize(double stopLossPoints)
{
    double balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double riskAmount = balance * RiskPercent / 100.0;

    // Get tick value (profit per 1 point movement per 1 lot)
    double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double tickSize  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

    if(tickValue == 0 || stopLossPoints == 0) return 0;

    double pointValue = tickValue / tickSize * _Point;
    double lotSize = riskAmount / (stopLossPoints * pointValue);

    // Normalize to broker's lot step
    double minLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double maxLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

    lotSize = MathFloor(lotSize / lotStep) * lotStep;
    lotSize = MathMax(lotSize, minLot);
    lotSize = MathMin(lotSize, maxLot);

    return NormalizeDouble(lotSize, 2);
}

Maximum Drawdown Protection

Automatically stop trading if the account drawdown exceeds a threshold:

input double MaxDrawdownPercent = 15.0;  // Max Drawdown (%)

double peakBalance = 0;

bool IsDrawdownExceeded()
{
    double balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double equity  = AccountInfoDouble(ACCOUNT_EQUITY);

    // Track peak balance
    if(balance > peakBalance) peakBalance = balance;

    // Calculate current drawdown
    double drawdown = (peakBalance - equity) / peakBalance * 100.0;

    if(drawdown >= MaxDrawdownPercent)
    {
        Print("MAX DRAWDOWN REACHED: ", DoubleToString(drawdown, 1),
              "% - Trading paused");
        return true;
    }
    return false;
}

void OnTick()
{
    if(IsDrawdownExceeded()) return;  // stop all trading

    // ... normal trading logic
}

Daily Loss Limit

input double MaxDailyLossPercent = 3.0;  // Max Daily Loss (%)

double dailyStartBalance = 0;
datetime lastDayChecked = 0;

bool IsDailyLossExceeded()
{
    // Reset at the start of each day
    MqlDateTime dt;
    TimeCurrent(dt);
    datetime today = StringToTime(IntegerToString(dt.year) + "." +
                     IntegerToString(dt.mon) + "." +
                     IntegerToString(dt.day));

    if(today != lastDayChecked)
    {
        dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
        lastDayChecked = today;
    }

    double equity = AccountInfoDouble(ACCOUNT_EQUITY);
    double dailyLoss = (dailyStartBalance - equity) / dailyStartBalance * 100;

    return (dailyLoss >= MaxDailyLossPercent);
}

Correlation Risk

If your EA trades multiple correlated pairs (e.g., EURUSD and GBPUSD), a loss on one is likely to coincide with a loss on the other. This effectively doubles your risk.

  • Reduce position size when trading correlated instruments
  • Set a maximum total exposure across all positions
  • Consider using a portfolio-level risk budget rather than per-trade risk

Risk Management Checklist for EAs

  • Every trade has a stop-loss — no exceptions
  • Position size is calculated from risk percentage, never hardcoded
  • Maximum drawdown kill switch is implemented
  • Daily loss limit is enforced
  • Maximum number of concurrent positions is limited
  • Maximum number of trades per day is limited (prevents overtrading)
  • Slippage protection: maximum deviation from requested price
  • Spread filter: do not trade when spread is abnormally wide
💡
Professional risk management

The risk controls shown here are the minimum. Production EAs used by professional traders include additional safeguards: equity curve tracking, regime detection, news filters, and dynamic risk adjustment. Building these systems is part of what makes professional EA development a specialized skill.