Loading…

Pain Metrics Toolkit

Maximum drawdown answers "how bad was the single worst dip", but says nothing about how long or how often an account actually sat under water. Two equity curves with an identical max drawdown can feel completely different to hold - one recovering within days, the other languishing for months at a shallower but more persistent loss. Peter Martin's Ulcer Index (1987) fixes this by taking the root-mean-square of the drawdown percentage at every sampled point, so both the depth and the duration of every underwater stretch contribute to the score - a curve that sits moderately down for a long time scores worse than one with a single sharp, quickly-recovered dip of the same maximum depth, which matches how it actually feels to hold the position. PmtUlcerIndex() implements the formula directly: sqrt(mean(drawdown%^2)). PmtPainIndex() is its simpler linear cousin, mean(drawdown%), which weighs a long shallow drawdown more heavily relative to a short sharp one than the squared Ulcer Index does. PmtMartinRatio() is the Sharpe-style reward-to-pain figure Martin built on top of his own index: annualised return minus a risk-free rate, divided by the Ulcer Index instead of standard deviation. The whole toolkit is incremental - PmtUpdate() folds one new equity reading into a small running-state struct (current peak, running sum of drawdown and drawdown-squared, sample count) with no stored history array, so the cost of updating it does not grow with how long the series has run. Notes and limitations - The sampling cadence is entirely the caller's choice (per trade, per bar, per day) and materially changes what the resulting index measures - an intraday-sampled Ulcer Index and a daily-sampled one on the same underlying equity are not directly comparable to each other or to a published figure sampled differently. - PmtAnnualizedReturnPct() returns 0.0 for a series spanning under one day (annualising a sub-day sample is not meaningful) and -100.0 if equity went to zero or below. - PmtMartinRatio() returns 0.0 when the Ulcer Index itself is exactly 0 (no drawdown recorded at all) rather than dividing by zero - reward-to- pain is genuinely undefined with no pain to divide by, not infinite. - These are population statistics over whatever samples PmtUpdate() has been fed so far; restarting PmtInit() mid-series resets the running peak and discards prior history, by design, for starting a fresh measurement window.

Script · MT5 · v1.0 · Free

About Pain Metrics Toolkit

Pain Metrics Toolkit is a script for MetaTrader 5. MQL source code included.

Files in the download: PainMetricsToolkit.mq5.mqh, PainMetricsToolkit.txt, PainMetricsToolkitDemo.ex5, PainMetricsToolkitDemo.mq5.

How to install

  1. Download the ZIP from your PolyMaria library and unzip it.
  2. In MetaTrader 5 open File → Open Data Folder, then go to MQL5 → Scripts.
  3. Copy the .mq5 file(s) there. Put any .mqh files in MQL5 → Include.
  4. Open the .mq5 file in MetaEditor and press Compile (F7) if MetaTrader does not show it.
  5. Drag the script onto a chart to run it once.

Download the PDF guide

Tags: Martingale · MT5 Script · MQL5 Source Code

MQL4 & MQL5 scripts · PolyMaria