Strasmore Research
تعلیمی مواد Matt Connorاز Matt Connor · اپ ڈیٹ شدہ 2026-08-08

Maximum Drawdown کیا ہے؟ گہرائی اور Recovery

Maximum drawdown value series میں peak سے trough تک سب سے بڑی گراوٹ ہے۔ جانیں گہری گراوٹ کیا ہوتی ہے اور نئی high تک واپسی میں زیادہ وقت کیوں لگتا ہے۔

Maximum drawdown کسی value series میں peak سے trough تک ہونے والی سب سے بڑی گراوٹ ہوتی ہے، جسے جاری peak کے فیصد کے طور پر ناپا جاتا ہے۔ اگر کوئی account $120,000 تک بڑھنے کے بعد $84,000 تک گر جائے اور پھر recover کر لے، تو اس کا maximum drawdown 30% ہوگا۔ یہ عدد ہمیشہ برقرار رہتا ہے، کیونکہ یہ آج کی صورتِ حال کے بجائے پوری history میں آنے والے بدترین دور کو record کرتا ہے۔ زیادہ تر لوگ صرف گراوٹ کی گہرائی بیان کرتے ہیں اور بات وہیں ختم کر دیتے ہیں۔ لیکن اسی statistic میں دو مزید اعداد بھی شامل ہوتے ہیں: peak سے low تک پہنچنے میں لگا وقت، اور low سے دوبارہ نئی high تک پہنچنے میں لگنے والا کہیں زیادہ طویل وقت۔

زیادہ سے زیادہ drawdown کیسے calculate کیا جاتا ہے؟

اس پورے calculation میں series پر صرف ایک بار عمل ہوتا ہے۔ ہر observation پر running maximum کو update کیا جاتا ہے، موجودہ value کو اس maximum کے مقابل ناپا جاتا ہے، اور اب تک کی سب سے خراب reading محفوظ رکھی جاتی ہے۔

  1. Running peak کو پہلی value کے برابر set کریں۔
  2. ہر نئی value پر، اگر وہ زیادہ ہو تو peak کو بڑھا دیں۔
  3. اس مقام پر drawdown calculate کریں: value کو peak سے divide کریں، پھر one منہا کریں۔
  4. سب سے منفی reading محفوظ رکھیں۔ یہی maximum drawdown ہے۔

اس calculation میں returns series، volatility estimate یا distribution assumption شامل نہیں ہوتی۔ یہ loop Python standard library کے ساتھ numbers کی ایک سادہ list پر چلتا ہے۔ نئی Ubuntu machine پر پہلے interpreter install کریں:

apt-get update && apt-get install -y python3

اس loop کو maxdd.py کے طور پر save کریں۔ نیچے دی گئی prices دس points پر مشتمل ایک فرضی series ہے، جسے اتنا مختصر رکھا گیا ہے کہ ہاتھ سے check کیا جا سکے:

prices = [100.0, 104.0, 98.0, 92.0, 95.0, 88.0, 90.0, 101.0, 99.0, 106.0]

peak = prices[0]
max_dd = 0.0

for price in prices:
    if price > peak:
        peak = price
    drawdown = price / peak - 1.0
    if drawdown < max_dd:
        max_dd = drawdown

print(f"maximum drawdown: {max_dd * 100:.1f}%")

python3 maxdd.py چلائیں، تو یہ maximum drawdown: -15.4% print کرے گا۔ اسے ہاتھ سے check کریں: low سے پہلے peak 104 تھا، low 88 تھا، اور 88 کو 104 سے divide کرنے پر 0.846 آتا ہے۔ اس کے بعد series 106 پر ختم ہوتی ہے، جو all-time high ہے، لیکن 15.4% کا drawdown برقرار رہتا ہے۔ Maximum drawdown sample کے بدترین لمحے کا مستقل record ہوتا ہے، اور یہ نہیں بتاتا کہ series آج کس مقام پر ہے۔ اسی loop میں مزید دو variables timing capture کر سکتے ہیں: وہ index جہاں peak قائم ہوا، اور وہ index جہاں worst reading ریکارڈ ہوئی۔

Drawdown curve کی شکل

Drawdown curve ہر نقطے پر step 3 کو برقرار رکھتی ہے، بجائے اس کے کہ اسے صرف بدترین ایک قدر تک محدود کر دیا جائے۔ جب series نئی بلند ترین سطح بناتی ہے تو line صفر پر رہتی ہے، اور درمیان کے عرصے میں صفر سے نیچے چلی جاتی ہے۔ اسی لیے اس فرق کو “underwater” کہا جاتا ہے۔ یہ جنوری 2016 سے ماہ کے اختتامی closing prices کی بنیاد پر SPY کی curve ہے۔ SPY ایک exchange-traded fund ہے جو S&P 500 کو track کرتا ہے۔

استفسار کریںSPY underwater curve: ماہ کے اختتامی close بمقابلہ running peak، 2016 تا 2026
ہر عدد کے پیچھے موجود درست SQL
WITH monthly AS (
    SELECT toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York'))) AS month_start,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-01-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY month_start
),
runs AS (
    SELECT month_start,
           close_px,
           max(close_px) OVER (ORDER BY month_start
                               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
    FROM monthly
)
SELECT formatDateTime(month_start, '%Y-%m') AS month,
       round(100 * (close_px / running_peak - 1), 2) AS drawdown_pct
FROM runs
ORDER BY month_start
Run this yourself

127 ماہ کے اختتامی readings میں line طویل ادوار تک تقریباً صفر کے قریب رہتی ہے اور چند گہری گراوٹوں میں نیچے جاتی ہے۔ ریکارڈ میں موجود آخری ماہ running peak کے مقابلے میں -1.27% پر ہے۔ اس shape کی دو خصوصیات بنیادی سبق دیتی ہیں۔ Recoveries تیز bounce کے بجائے آہستہ چڑھاؤ کی صورت میں آتی ہیں، اور ہر نئی peak curve کو دوبارہ صفر پر لے آتی ہے، جس سے اس سے پہلے کی گراوٹ کا بصری نشان مٹ جاتا ہے۔

Drawdown سے بحالی میں کتنا وقت لگتا ہے؟

ایک ہی drawdown میں تین الگ اعداد شامل ہوتے ہیں، اور انہیں ایک ہی چیز سمجھنا performance table کی سب سے عام غلط تشریح ہے:

  1. Depth: قدر اپنی بلند ترین سطح سے فیصد کے لحاظ سے کتنی نیچے گری۔
  2. Time to the low: peak سے bottom تک calendar days۔
  3. Recovery time: bottom سے نئی بلند ترین سطح تک پہنچنے میں لگنے والے calendar days۔

تیسرا عرصہ عموماً سب سے طویل ہوتا ہے، لیکن headline number اسے کبھی ظاہر نہیں کرتا۔ ذیل کا panel روزانہ کے closing prices کی بنیاد پر 2016 سے SPY کے ہر مکمل underwater period کو دوبارہ تشکیل دیتا ہے۔ کوئی period اس دن شروع ہوتا ہے جب نیا peak قائم ہوتا ہے، اور اس دن ختم ہوتا ہے جب fund پہلی بار اس سطح سے اوپر close کرتا ہے۔

استفسار کریں2016 کے بعد مکمل SPY drawdowns: گہرائی، گرنے کے دن، بحالی کے دن
ہر عدد کے پیچھے موجود درست SQL
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-01-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY session_date
),
runs AS (
    SELECT session_date,
           close_px,
           max(close_px) OVER (ORDER BY session_date
                               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
    FROM daily
),
episodes AS (
    SELECT running_peak AS peak_px,
           min(session_date) AS peak_date,
           argMin(session_date, close_px) AS trough_date,
           min(close_px) AS trough_px
    FROM runs
    GROUP BY running_peak
),
sequenced AS (
    SELECT peak_px,
           peak_date,
           trough_date,
           trough_px,
           leadInFrame(peak_date, 1) OVER (ORDER BY peak_date
                                           ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS recovery_date
    FROM episodes
)
SELECT formatDateTime(peak_date, '%b %Y') AS episode_label,
       round(100 * (1 - trough_px / peak_px), 1) AS fall_from_peak_pct,
       dateDiff('day', peak_date, trough_date) AS days_to_trough,
       dateDiff('day', trough_date, recovery_date) AS days_to_new_high,
       dateDiff('day', peak_date, recovery_date) AS days_underwater
FROM sequenced
WHERE recovery_date > trough_date
  AND round(100 * (1 - trough_px / peak_px), 1) >= 5
ORDER BY fall_from_peak_pct DESC
LIMIT 8
Run this yourself

فہرست میں سب سے گہرا مکمل period Feb 2020 میں شروع ہوتا ہے اور سابقہ peak سے 34.2% نیچے تک پہنچتا ہے۔ اس میں کمی کا عرصہ 33 calendar days اور واپسی کا عرصہ 148 رہا؛ fund مجموعی طور پر 181 days تک underwater رہا۔ اگلی entry، جو Jan 2022 کی ہے، کم گہری تھی، یعنی 25.4%، اور اس نے fund کو 746 days تک سابقہ high سے نیچے رکھا۔

Depth اور duration ایک دوسرے سے مکمل طور پر الگ ہو سکتے ہیں۔ ایک شدید گراوٹ، جس کے بعد تیز recovery ہو، اور ایک معمولی مگر برسوں جاری رہنے والی گراوٹ، دونوں ایک ہی percentage میں سمٹ جاتے ہیں۔ March 2020 کا crash پہلی صورت کی textbook مثال ہے، جبکہ crashes کے بعد markets کیسے recover کرتے ہیں اس سفر کے دوسرے مرحلے کی وضاحت کرتا ہے۔

زیادہ عرصے تک پیمائش کرنے سے maximum drawdown کیوں بدتر دکھائی دیتا ہے

Maximum drawdown ایک maximum ہوتا ہے، اس لیے تاریخی مدت بڑھانے سے یہ صرف اتنا ہی رہ سکتا ہے یا مزید گہرا ہو سکتا ہے۔ طویل window میں running peak ہر مقام پر مختصر window کے peak کے برابر یا اس سے زیادہ ہوتا ہے، اور یہی arithmetic نتیجہ طے کرتی ہے۔ 31 جولائی 2026 کو ختم ہونے والی پانچ windows میں اسی fund کی پیمائش اس اثر کو ظاہر کرتی ہے۔

استفسار کریںایک ہی fund، پانچ lookback windows: sample length کے لحاظ سے SPY maximum drawdown، 31 جولائی 2026 تک
ہر عدد کے پیچھے موجود درست SQL
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-07-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY session_date
),
scoped AS (
    SELECT arrayJoin([1, 2, 3, 5, 10]) AS lookback_years,
           session_date,
           close_px
    FROM daily
),
windowed AS (
    SELECT lookback_years, session_date, close_px
    FROM scoped
    WHERE session_date >= subtractYears(toDate('2026-07-31'), lookback_years)
),
runs AS (
    SELECT lookback_years,
           session_date,
           close_px,
           max(close_px) OVER (PARTITION BY lookback_years ORDER BY session_date
                               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak
    FROM windowed
)
SELECT concat(toString(lookback_years), if(lookback_years = 1, ' year', ' years')) AS lookback,
       round(100 * max(1 - close_px / running_peak), 1) AS max_drawdown_pct,
       formatDateTime(argMax(session_date, 1 - close_px / running_peak), '%b %Y') AS worst_point
FROM runs
GROUP BY lookback_years
ORDER BY lookback_years
Run this yourself

گزشتہ 1 year window میں سب سے بڑی گراوٹ 9.1% ریکارڈ ہوئی۔ اسی series کو بڑھا کر 10 years کرنے پر reading 34.2% ہو گئی، جبکہ worst point Mar 2020 میں آیا۔ Fund زیادہ خطرناک نہیں ہوا۔ صرف sample کی مدت طویل ہوئی۔

یہی arithmetic مختلف strategies کے موازنے کو بھی مسخ کرتی ہے۔ تین سالہ backtest اور بیس سالہ backtest یکساں رویے کی عکاسی کر سکتے ہیں، پھر بھی ان کے reported drawdowns بہت مختلف ہو سکتے ہیں۔ اس لیے window بتائے بغیر یہ figure محدود معنی رکھتا ہے۔ backtesting میں look-ahead bias ایک اور طریقے کا جائزہ لیتا ہے جس سے بظاہر صاف backtest خود کو بہتر دکھا سکتا ہے۔

زیادہ سے زیادہ drawdown بمقابلہ volatility

Volatility روزانہ قیمت میں دونوں سمتوں میں ہونے والی عام حرکت کا حجم ناپتی ہے۔ Maximum drawdown قیمت کے ایک مخصوص منفی سفر کی پیمائش کرتا ہے۔ دونوں risk metrics ہیں، مگر ان کے سوالات مختلف ہیں۔ یہ panel پانچ برسوں، یعنی 31 جولائی 2026 تک، آٹھ معروف کمپنیوں کے لیے دونوں اعداد کو ساتھ رکھتا ہے۔ Volatility کا annualization روزانہ کے closing prices کی بنیاد پر کیا گیا ہے۔

استفسار کریںMaximum drawdown بمقابلہ annualized volatility: آٹھ large caps، 31 جولائی 2026 تک پانچ سال
ہر عدد کے پیچھے موجود درست SQL
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'AAPL', 'MSFT', 'KO', 'JNJ', 'CVX', 'VZ', 'PG')
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2021-08-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session_date
),
runs AS (
    SELECT ticker,
           session_date,
           close_px,
           max(close_px) OVER (PARTITION BY ticker ORDER BY session_date
                               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_peak,
           lagInFrame(close_px, 1) OVER (PARTITION BY ticker ORDER BY session_date
                                         ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
    FROM daily
)
SELECT ticker,
       round(100 * max(1 - close_px / running_peak), 1) AS max_drawdown_pct,
       round(100 * sqrt(252) * stddevSampIf(close_px / prev_close - 1, prev_close > 0), 1) AS annualized_volatility_pct
FROM runs
GROUP BY ticker
HAVING countIf(prev_close > 0) > 20
ORDER BY max_drawdown_pct DESC
Run this yourself

دونوں columns کو ساتھ پڑھیں۔ VZ نے گروپ میں 45.4% کی صورت میں سب سے گہری گراوٹ ریکارڈ کی، جبکہ اس کی annualized volatility 22.6% رہی۔ کم ترین سطح پر KO میں 20.9% کی گراوٹ آئی اور volatility 16.7% رہی۔ Volatility اس پوری مدت کے ہر دن کا average ہے، اور averages طویل، بتدریج decline کے اثر کو کم کر دیتے ہیں۔ Drawdown وہ واحد بدترین راستہ ہے جس سے قیمت حقیقت میں گزری۔ کوئی relatively quiet holding جو دو برس تک آہستہ آہستہ نیچے جاتی رہے، غیر نمایاں volatility کے باوجود گہرا drawdown دکھا سکتی ہے۔

کم volatility کا anomaly طویل مدت میں کم اتار چڑھاؤ والے ناموں کے رویے کا جائزہ لیتا ہے، جبکہ Kelly criterion کے تحت position sizing دکھاتا ہے کہ drawdown برداشت کرنے کی حد کو position size میں کیسے تبدیل کیا جاتا ہے۔

جو number آپ کو نہیں بتا سکتا

چار حدود ذہن میں رکھنا ضروری ہیں:

  1. یہ صرف ایک realised path ہے۔ مختلف market draw میں یہی process کہیں زیادہ خراب figure پیدا کر سکتا تھا۔
  2. یہ sample length پر منحصر ہے، اس لیے دو drawdowns کا تقابل صرف یکساں windows میں ہی کیا جا سکتا ہے۔
  3. یہ sampling frequency پر منحصر ہے۔ Month-end closes، intraday lows کو چھپا دیتے ہیں اور اسی period میں daily closes کے مقابلے میں چھوٹا number دکھاتے ہیں۔
  4. اس میں مستقبل کے بارے میں کوئی information شامل نہیں ہوتی۔ Peak سے 30% نیچے ہونا یہ نہیں بتاتا کہ 31st point کل آئے گا یا نہیں۔

یہ آخری حد اس وجہ سے اہم ہے کہ automated system کو drawdown threshold کے بجائے drawdown policy درکار ہوتی ہے۔ “20% پر halt کریں” ایک سوال کا جواب دیتا ہے، مگر دو سوالات کا نہیں: halt کے وقت open positions کے ساتھ کیا ہوگا، اور system کو دوبارہ on کرنے کے لیے کون سا evidence درکار ہوگا۔ Trading bots کے لیے circuit breakers اسی policy کی ساخت کا جائزہ لیتا ہے۔ من مانے flat rule کی لاگت recovery leg میں سامنے آتی ہے، جہاں low کے قریب رکنے اور دیر سے restart ہونے والا system دوبارہ ہونے والی تیزی سے باہر رہ جاتا ہے۔ Best days سے محروم رہنا اس arithmetic کو اعداد میں بیان کرتا ہے۔

دو figures کا تقابل کرنے سے پہلے measurement کی ایک تفصیل اہم ہے: fund کی price series پر drawdown اور حقیقی account پر drawdown اس وقت مختلف ہوتے ہیں جب cash اندر یا باہر منتقل ہو اور جب dividends موصول ہوں۔ ماہانہ returns کیسے ناپے جاتے ہیں اس نکتے کی مکمل وضاحت کرتا ہے۔

Maximum drawdown سے متعلق عام سوالات

اچھا maximum drawdown کتنا ہوتا ہے؟

اس کی کوئی عالمی طور پر مقررہ حد نہیں۔ اس کے لیے ایک benchmark اور پیمائش کی مدت درکار ہوتی ہے۔ 31 جولائی 2026 تک کے دس برسوں میں SPY کی running peak سے سب سے بڑی گراوٹ روزانہ کے closing prices کی بنیاد پر 34.2% رہی۔ مختصر مدت کے sample میں اس سے کم figure پیش کرنے والی strategy لازماً زیادہ محفوظ نہیں ہوتی۔

کیا maximum drawdown اور volatility ایک ہی چیز ہیں؟

نہیں۔ Volatility روزانہ کی معمول کی price movement کو بیان کرتی ہے، جبکہ maximum drawdown peak سے trough تک کا سب سے خراب مسلسل راستہ دکھاتا ہے۔ دو برس تک مسلسل گرنے والا کم-volatility holding، ایسی تیزی سے حرکت کرنے والی investment کے مقابلے میں زیادہ گہرا drawdown رکھ سکتا ہے جو مسلسل نئی بلند ترین سطحیں بناتی رہے۔

Maximum drawdown سے بحالی میں کتنا وقت لگتا ہے؟

یہ مختلف ہوتا ہے، اور واپسی کا مرحلہ اکثر اس پورے عمل کا زیادہ طویل حصہ ہوتا ہے۔ 2016 سے SPY کے لیے کسی سابقہ high سے نیچے رہنے والا سب سے گہرا مکمل دور peak سے نئی high تک 181 calendar days پر محیط تھا، جن میں 33 دن گراوٹ میں گزرے۔

کیا maximum drawdown مستقبل کے نقصانات کی پیش گوئی کرتا ہے؟

نہیں۔ یہ صرف اس راستے کو بیان کرتا ہے جو پہلے ہی طے ہو چکا ہے، اور طویل sample تقریباً ہمیشہ بڑا figure پیدا کرتا ہے۔ یہ ریکارڈ کرتا ہے کہ strategy اب تک کن حالات سے گزر چکی ہے؛ مستقبل کے نقصانات کی کوئی حد اس سے معلوم نہیں ہوتی۔


اوپر موجود ہر panel اپنے پیچھے موجود SQL محفوظ رکھتا ہے۔ کسی panel کو کھولیں، ticker یا window تبدیل کریں، اور Strasmore terminal پر یہی drawdown arithmetic چلائیں۔

#risk#drawdown#backtesting#performance metrics#python