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

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

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

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

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

ما الذي لا يخبرك به الرقم

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

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

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

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

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

ما أقصى تراجع يُعد جيداً؟

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

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

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

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

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

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

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


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

#risk#drawdown#backtesting#performance metrics#python