Strasmore Research
تعلَّم Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-08

ما الحد الأقصى للتراجع؟ العمق مقابل التعافي

الحد الأقصى للتراجع هو أكبر هبوط من قمة إلى قاع في سلسلة قيمة. تعرّف إلى معنى التراجع العميق، ولماذا يستغرق التعافي إلى قمة جديدة وقتاً أطول.

الحد الأقصى للتراجع هو أكبر انخفاض من قمة إلى قاع في سلسلة قيمة، ويُقاس كنسبة مئوية من القمة المتحركة. إذا ارتفع حساب إلى 120,000 دولار، ثم هبط إلى 84,000 دولار قبل أن يتعافى، فسيبلغ الحد الأقصى للتراجع 30%، ويظل مسجلاً إلى الأبد، لأن هذا المقياس يرصد أسوأ فترة في تاريخ الحساب، لا وضعه الحالي. يذكر معظم الناس عمق التراجع وينتهون عند ذلك. لكن المقياس نفسه يتضمن رقمين إضافيين: المدة من القمة إلى القاع، والمدة الأطول بكثير من ذلك القاع إلى بلوغ قمة جديدة.

كيف يُحسَب الحد الأقصى للتراجع؟

تُجرى العملية الحسابية كاملةً في مرور واحد على السلسلة. عند كل قراءة، تحدّث القمة الجارية، وتقيس القيمة الحالية مقارنةً بها، وتحتفظ بأسوأ قراءة ظهرت حتى ذلك الحين.

  1. اضبط القمة الجارية على القيمة الأولى.
  2. عند كل قيمة جديدة، ارفع القمة إذا كانت القيمة أعلى.
  3. احسب التراجع عند تلك النقطة: اقسم القيمة على القمة ثم اطرح واحداً.
  4. احتفظ بأكثر قراءة سلبية. هذه هي قيمة الحد الأقصى للتراجع.

لا تدخل في هذه العملية سلسلة عوائد، ولا تقدير للتقلب، ولا افتراض بشأن التوزيع. تعمل الحلقة على قائمة عادية من الأرقام باستخدام المكتبة القياسية لـ Python. على نظام Ubuntu جديد، ثبّت المفسّر أولاً:

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

احفظ الحلقة باسم maxdd.py. الأسعار أدناه سلسلة افتراضية من عشر نقاط، وقد أُبقيت صغيرة بما يكفي للتحقق منها يدوياً:

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%. تحقّق منها يدوياً: القمة السابقة للقاع هي 104، والقاع هو 88، وقسمة 88 على 104 تساوي 0.846. وتنتهي السلسلة عند 106، وهو أعلى مستوى على الإطلاق، لكن نسبة 15.4% تظل مسجلة. الحد الأقصى للتراجع هو سجل دائم لأسوأ لحظة في العينة، ولا يوضح شيئاً عن موضع السلسلة اليوم. ويمكن لمتغيرين إضافيين في الحلقة نفسها تسجيل التوقيت: المؤشر الذي سُجلت عنده القمة، والمؤشر الذي ظهرت عنده أسوأ قراءة.

كيف يبدو منحنى التراجع

يحافظ منحنى التراجع على الخطوة الثالثة عند كل نقطة، بدلاً من اختزالها إلى أسوأ قيمة واحدة. يبقى الخط عند الصفر كلما سجلت السلسلة مستوى مرتفعاً جديداً، ويظل تحت الصفر بين تلك المستويات. لذلك تُسمّى هذه الفجوة «المنطقة المغمورة». يوضح الشكل التالي منحنى SPY، وهو ETF يتتبع مؤشر S&P 500، استناداً إلى أسعار الإغلاق في نهاية كل شهر منذ يناير 2016.

الاستعلاممنحنى تراجع SPY: إغلاق نهاية الشهر مقارنةً بأعلى مستوى سابق، 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 قراءة في نهاية الشهر، يبقى الخط لفترات طويلة قريباً من الصفر، ثم يهبط إلى عدد محدود من القيعان العميقة. وتبلغ قراءة الشهر الأخير المتاح -1.27% مقارنةً بالقمة المتحركة. يوضح شكل المنحنى نقطتين أساسيتين. تأتي التعافيّات على هيئة صعود بطيء، لا ارتدادات حادة. وكل قمة جديدة تعيد المنحنى إلى الصفر، وتمحو الأثر البصري لما سبقها.

كم يستغرق التعافي من التراجع؟

توجد ثلاثة أرقام منفصلة داخل كل تراجع، واعتبارها رقماً واحداً هو أكثر الأخطاء شيوعاً في قراءة جدول الأداء:

  1. العمق: مقدار هبوط القيمة عن ذروتها، كنسبة مئوية.
  2. المدة حتى القاع: عدد الأيام التقويمية من الذروة إلى القاع.
  3. مدة التعافي: عدد الأيام التقويمية من القاع إلى تسجيل مستوى قياسي جديد.

عادةً ما تكون المدة الثالثة هي الأطول، وهي المدة التي لا يظهرها الرقم الرئيسي. يعيد الجدول أدناه بناء كل فترة مكتملة ظل فيها SPY دون ذروته السابقة منذ عام 2016، بالاعتماد على أسعار الإغلاق اليومية. تبدأ الفترة في اليوم الذي تُسجَّل فيه الذروة، وتنتهي في اليوم الذي يغلق فيه الصندوق للمرة الأولى فوقها.

الاستعلامتراجعات SPY المكتملة منذ 2016: العمق، أيام الهبوط، أيام التعافي
استعلام 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

بدأت أعمق فترة مكتملة في القائمة خلال Feb 2020، وبلغت 34.2% دون الذروة السابقة. واستغرق الهبوط 33 يوماً تقويمياً، ثم استغرق الصعود مجدداً 148، ليبقى الصندوق دون ذروته مدة إجمالية قدرها 181 يوماً. أما الإدخال التالي، من Jan 2022، فكان تراجعه أقل عند 25.4%، لكنه أبقى الصندوق دون أعلى مستوى سابق له مدة 746 يوماً.

ينفصل العمق عن المدة تماماً. فالهبوط الحاد الذي يعقبه تعافٍ سريع، والتراجع المحدود الذي يستمر سنوات، يختزلان معاً في نسبة مئوية واحدة. انهيار مارس 2020 هو المثال النموذجي للحالة الأولى، بينما يتناول كيفية تعافي الأسواق من الانهيارات المرحلة الثانية من المسار.

لماذا يزداد سوء أقصى تراجع كلما طالت فترة القياس

أقصى تراجع هو قيمة قصوى، لذلك لا يمكن لإضافة بيانات تاريخية أن تؤدي إلا إلى إبقائه كما هو أو تعميقه. وتكون القمة المتحركة في فترة أطول مساوية على الأقل للقمة المتحركة في كل نقطة ضمن فترة أقصر، وهو ما يحدد النتيجة الحسابية. ويظهر هذا الأثر عند قياس الصندوق نفسه عبر خمس فترات تنتهي جميعاً في 31 يوليو 2026.

الاستعلامالصندوق نفسه، خمس نوافذ رجوع: أقصى تراجع لـ SPY حسب طول العينة حتى 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 السابقة، بلغ أسوأ انخفاض 9.1%. وعند تمديد السلسلة نفسها إلى 10 years، تصبح القراءة 34.2%، مع وقوع أسوأ نقطة في Mar 2020. لم يصبح الصندوق أكثر خطورة. بل أصبحت العينة أطول.

ويشوّه الحساب نفسه مقارنات الاستراتيجيات. فقد يصف اختبار رجعي مدته ثلاث سنوات واختبار رجعي مدته عشرون سنة السلوك نفسه، ومع ذلك يبلغان عن أقصى تراجعات مختلفة جداً. لذلك لا تعني هذه النسبة الكثير من دون إرفاق فترة القياس بها. ويتناول تحيز التطلع إلى المستقبل في الاختبارات الرجعية طريقة أخرى يجعل بها الاختبار الرجعي الذي يبدو سليماً أداءه أفضل مما ينبغي.

الحد الأقصى للتراجع مقابل التقلب

يقيس التقلب الحجم المعتاد لتحرك يومي في أي من الاتجاهين. أما الحد الأقصى للتراجع فيقيس مساراً هبوطياً محدداً. كلاهما مقياس للمخاطر، لكنهما يجيبان عن سؤالين مختلفين. يعرض الجدول المقياسين جنباً إلى جنب لثمانية أسماء معروفة لدى الأسر خلال السنوات الخمس المنتهية في 31 يوليو 2026، مع احتساب التقلب على أساس سنوي انطلاقاً من أسعار الإغلاق اليومية.

الاستعلامأقصى تراجع مقابل التقلب السنوي: ثمانية أسهم كبيرة، خمس سنوات حتى 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

اقرأ العمودين معاً. يسجل VZ أعمق هبوط في المجموعة عند 45.4%، مقابل تقلب سنوي قدره 22.6%. وفي الطرف الأقل تراجعاً، انخفض KO بنسبة 20.9%، مع تقلب قدره 16.7%. التقلب هو متوسط جميع الأيام خلال الفترة، والمتوسطات قد تخفي انخفاضاً طويلاً وبطيئاً. أما التراجع فهو أسوأ مسار فعلي سلكه السعر. وقد يسجل أصل هادئ ينخفض تدريجياً لمدة عامين تراجعاً عميقاً، رغم أن قراءة التقلب لديه تبدو عادية.

يتناول شذوذ التقلب المنخفض سلوك الأصول الهادئة على مدى فترات طويلة، بينما يوضح تحديد حجم المركز وفق معيار Kelly كيف يتحول تحمّل التراجع إلى حجم مركز.

ما الذي لا يستطيع الرقم أن يخبرك به

هناك أربعة قيود يجدر بك تذكّرها:

  1. إنه مسار محقق واحد. كان من الممكن للعملية نفسها أن تنتج رقماً أسوأ بكثير في مسار مختلف.
  2. يعتمد على طول العينة. لذلك لا تجوز مقارنة السحبين إلا ضمن فترتين متماثلتين.
  3. يعتمد على وتيرة أخذ العينات. فأسعار الإغلاق في نهاية الشهر تخفي القيعان خلال اليوم، وتنتج رقماً أصغر من أسعار الإغلاق اليومية للفترة نفسها.
  4. لا يحمل أي معلومات مستقبلية. إن كونك أقل بنسبة 30% من قمة سابقة لا يخبرك شيئاً عن احتمال بلوغ النقطة الحادية والثلاثين غداً.

هذا القيد الأخير هو سبب حاجة النظام الآلي إلى سياسة للسحب، لا إلى عتبة للسحب فحسب. فعبارة «أوقف التداول عند 20%» تجيب عن سؤال واحد وتترك سؤالين بلا إجابة: ماذا يحدث للمراكز المفتوحة عند الإيقاف، وما الدليل الذي يعيد تشغيل النظام؟ يوضح قواطع التداول الآلية كيفية بناء هذه السياسة. وتظهر تكلفة القاعدة الثابتة الاعتباطية في مرحلة التعافي، إذ يفوّت النظام الذي يتوقف قرب القاع ويُعاد تشغيله متأخراً جزءاً من الصعود. وتضع تفويت أفضل أيام التداول أرقاماً لهذه الحسابات.

ثمة تفصيل منهجي مهم قبل مقارنة رقمين: يختلف السحب المحسوب من سلسلة أسعار صندوق عن السحب المحسوب في حساب فعلي كلما دخلت أموال إلى الحساب أو خرجت منه، وكلما استُلمت توزيعات أرباح. ويتناول كيفية قياس العوائد الشهرية هذه المسألة بالكامل.

الأسئلة الشائعة حول الحد الأقصى للتراجع

ما الحد الأقصى الجيد للتراجع؟

لا توجد قيمة عالمية. بل يعتمد الأمر على معيار وفترة زمنية تُقاس النتيجة على أساسهما. خلال السنوات العشر المنتهية في 31 يوليو 2026، بلغ أسوأ هبوط لـ SPY من قمة سابقة متحركة، والمقاس وفق أسعار الإغلاق اليومية، 34.2%. ولا يعني تسجيل استراتيجية لرقم أقل خلال عينة أقصر أنها كانت أكثر أماناً بالضرورة.

هل الحد الأقصى للتراجع هو نفسه التقلب؟

لا. يصف التقلب الحركة اليومية المعتادة. أما الحد الأقصى للتراجع فيصف أسوأ مسار منفرد من القمة إلى القاع. قد يتكبد أصل منخفض التقلب تراجعاً أعمق إذا انخفض بثبات على مدى عامين، مقارنةً بأصل متذبذب يواصل تسجيل قمم جديدة.

كم يستغرق التعافي من الحد الأقصى للتراجع؟

يختلف ذلك، وغالباً ما يكون الصعود مجدداً هو الجزء الأطول. بالنسبة إلى SPY منذ عام 2016، امتدت أطول فترة مكتملة دون تجاوز قمة سابقة 181 يوماً تقويمياً من القمة إلى تسجيل قمة جديدة، قضى منها السعر 33 يوماً في الهبوط.

هل يتنبأ الحد الأقصى للتراجع بالخسائر المستقبلية؟

لا. فهو يصف مساراً واحداً حدث بالفعل، كما أن العينة الأطول تنتج تقريباً دائماً رقماً أكبر. ويسجل ما تمكنت الاستراتيجية من تحمله حتى الآن، من دون حد أقصى لما قد يحدث لاحقاً.


تخزّن كل لوحة أعلاه استعلام SQL الذي يقف وراءها. افتح إحدى اللوحات، وبدّل رمز السهم أو الفترة الزمنية، ثم نفّذ الحساب نفسه للتراجع على منصة Strasmore.

#risk#drawdown#backtesting#performance metrics#python