Maximum drawdown ni nini na jinsi ya kuipima
Maximum drawdown ni kushuka kwa thamani kutoka kilele hadi chini. Jifunze jinsi ya kupima kina cha kushuka na kwa nini kurudi kwenye kilele kipya huchukua muda mrefu zaidi.
33
Maximum drawdown ni kushuka kwa thamani kwa kiwango kikubwa zaidi kutoka kilele hadi chini, na hupimwa kama asilimia ya kilele cha sasa. Akaunti inayopanda hadi $120,000, ikashuka hadi $84,000, kisha ikapata nafuu, ina maximum drawdown ya asilimia thelathini, na namba hiyo hubaki hivyo milele, kwa sababu takwimu hii hurekodi kipindi kibaya zaidi katika historia badala ya hali ya sasa. Watu wengi hutaja kina cha kushuka huko na kuishia hapo. Namba nyingine mbili zipo ndani ya takwimu hiyo hiyo: muda uliotumika kutoka kileleni hadi chini, na muda mrefu zaidi uliotumika kutoka chini hiyo hadi kufikia kilele kipya.
Je, maximum drawdown huhesabiwaje?
Hesabu nzima hufanyika kwa kupitia mfululizo wa data mara moja. Katika kila hatua ya uchunguzi, unasasisha kilele cha juu zaidi (running maximum), unapima thamani ya sasa dhidi ya kilele hicho, na kuhifadhi thamani mbaya zaidi iliyopatikana hadi wakati huo.
- Weka kilele cha kuanzia (running peak) sawa na thamani ya kwanza.
- Katika kila thamani mpya, pandisha kilele ikiwa thamani hiyo ni kubwa zaidi.
- Kokotoa drawdown katika hatua hiyo: thamani ikigawanywa kwa kilele, kisha toa moja.
- Hifadhi thamani hasi zaidi. Hiyo ndiyo maximum drawdown.
Hakuna mfululizo wa returns, makadirio ya volatility, wala dhana ya usambazaji (distribution assumption) inayohusika. Mzunguko huu (loop) hufanya kazi kwenye orodha rahisi ya namba kwa kutumia maktaba ya kawaida ya Python. Kwenye mashine mpya ya Ubuntu, sakinisha interpreter kwanza:
apt-get update && apt-get install -y python3
Hifadhi mzunguko huo kama maxdd.py. Bei zilizo hapa chini ni mfululizo wa pointi kumi zilizotungwa, zilizowekwa ndogo vya kutosha ili kuweza kukaguliwa kwa mkono:
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}%")
Endesha python3 maxdd.py na itachapisha maximum drawdown: -15.4%. Iangalie kwa mkono: kilele kabla ya kiwango cha chini ni 104, kiwango cha chini ni 88, na 88 ikigawanywa kwa 104 ni 0.846. Mfululizo huo kisha unaishia 106, kiwango cha juu kabisa cha wakati wote, na ile asilimia 15.4 bado inabaki. Maximum drawdown ni rekodi ya kudumu ya wakati mbaya zaidi katika sampuli, na haisemi chochote kuhusu hali ya mfululizo huo kwa sasa. Vigezo vingine viwili katika mzunguko uleule vinaweza kunasa muda: index ambapo kilele kiliwekwa, na index ambapo thamani mbaya zaidi ilitokea.
Muonekano wa mkondo wa drawdown
Mkondo wa drawdown hufuatilia hatua ya tatu katika kila nukta badala ya kuipunguza kuwa thamani moja mbaya zaidi. Mstari huu hukaa kwenye sifuri wakati wowote mfululizo wa data unapopata kilele kipya na hutundika chini ya sifuri katikati ya vipindi hivyo, ndiyo maana pengo hilo huitwa "underwater". Hapa kuna mkondo huo kwa ajili ya SPY, ETF inayofuatilia S&P 500, kulingana na bei za kufunga mwezi tangu Januari mbili elfu kumi na sita.
SQL halisi nyuma ya kila namba
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_startKatika usomaji wa mwisho wa mwezi 127, mstari huu hutumia muda mrefu ukiwa karibu na sifuri na kushuka katika mipasuko michache mirefu. Mwezi wa mwisho kwenye kumbukumbu unasoma -1.27% dhidi ya kilele kinachoendelea. Vipengele viwili vya umbo hili vinatoa mafunzo. Urejeshaji ni kupanda kwa taratibu badala ya kuruka kwa kasi, na kila kilele kipya huweka upya mkondo huo kwenye sifuri, na kufuta kumbukumbu ya kuona ya kile kilichotokea awali.
Inachukua muda gani kupona kutokana na drawdown?
Namba tatu tofauti zipo ndani ya drawdown moja, na kuzichukulia kama namba moja ndilo kosa la kawaida zaidi katika kusoma jedwali la utendaji:
- Kina: umbali ambao thamani ilishuka chini ya kilele chake, kwa asilimia.
- Muda wa kufika chini: siku za kalenda kuanzia kileleni hadi chini kabisa.
- Muda wa kupona: siku za kalenda kuanzia chini hapo hadi kufikia kilele kipya.
Namba ya tatu kwa kawaida ndiyo ndefu zaidi, na ndiyo namba ambayo kichwa cha habari hakionyeshi kamwe. Paneli iliyo hapa chini inajenga upya kila kipindi kilichokamilika cha kuporomoka kwa thamani (underwater stretch) kwa SPY tangu mwaka elfu mbili na kumi na sita kutokana na bei za kufunga za kila siku. Kipindi huanza siku ambayo kilele kinawekwa na kuishia siku ambayo mfuko unafunga kwa mara ya kwanza juu ya kilele hicho.
SQL halisi nyuma ya kila namba
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 8Kipindi kirefu zaidi kilichokamilika kwenye orodha kinaanza katika Feb 2020 na kufikia 34.2% chini ya kilele cha awali. Kilikaa 33 siku za kalenda kikishuka na 148 kikipanda kurudi, jumla ya siku 181 kikiwa chini ya maji. Ingizo linalofuata, kutoka Jan 2022, ni la kina kifupi zaidi kwa 25.4%, na liliufanya mfuko kubaki chini ya kilele chake cha zamani kwa siku 746.
Kina na muda hutofautiana kabisa. Kushuka kwa kasi na kurudi haraka, na kusua-sua kwa kina kifupi kunakochukua miaka, vyote hubanwa na kuwa asilimia moja. Kuporomoka kwa Machi 2020 ni mfano wa kitabu wa umbo la kwanza, na jinsi masoko yanavyopona kutokana na kuporomoka hufuata mguu wa pili wa safari hiyo.
Kwa nini maximum drawdown huzidi kuwa mbaya kadiri unavyoongeza muda wa kipimo
Maximum drawdown ni thamani ya juu zaidi, hivyo kuongeza historia ya data kunaweza kuifanya ibaki vilevile au ishuke zaidi. Kilele cha mfululizo wa data katika kipindi kirefu ni angalau sawa na kilele cha kipindi kifupi katika kila hatua, jambo ambalo huathiri hesabu hiyo. Kupima mfuko uleule katika vipindi vitano vyote vinavyoishia Julai 31, 2026 kunaonyesha athari hii.
SQL halisi nyuma ya kila namba
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_yearsKatika kipindi cha 1 year, anguko baya zaidi lililopimwa lilikuwa 9.1%. Ukiongeza mfululizo huo huo hadi 10 years, kipimo kinakuwa 34.2%, huku hatua mbaya zaidi ikitokea katika Mar 2020. Mfuko haukuwa na hatari zaidi. Sampuli ya muda ilirefuka tu.
Hesabu hiyo hiyo hupotosha ulinganisho wa mikakati. Backtest ya miaka mitatu na ile ya miaka ishirini zinaweza kuelezea tabia inayofanana kabisa na bado zikatoa ripoti za drawdowns tofauti sana, hivyo takwimu hiyo haina maana kubwa bila kipindi husika kuambatishwa nayo. Upendeleo wa kutazama mbele katika backtesting unaelezea njia nyingine ambayo backtest inayoonekana kuwa safi hujipamba isivyo halisi.
Maximum drawdown dhidi ya volatility
Volatility hupima ukubwa wa kawaida wa mabadiliko ya kila siku katika mwelekeo wowote. Maximum drawdown hupima mwelekeo mmoja mahususi wa kushuka. Zote mbili ni namba za hatari, na zinajibu maswali tofauti. Jopo hili linaziweka kando kwa kando kwa majina nane maarufu katika kipindi cha miaka mitano hadi Julai 31, 2026, huku volatility ikiwa imepimwa kwa mwaka kulingana na bei za kufunga za kila siku.
SQL halisi nyuma ya kila namba
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 DESCSoma safu hizi mbili pamoja. VZ ina anguko kubwa zaidi katika kundi hili kwa 45.4%, dhidi ya volatility ya kila mwaka ya 22.6%. Katika upande wa chini, KO ilishuka kwa 20.9% ikiwa na volatility ya 16.7%. Volatility ni wastani wa kila siku ndani ya kipindi hicho, na wastani husamehe kushuka kwa muda mrefu na polepole. Drawdown ni mwelekeo mbaya zaidi ambao bei ilipitia kihalisi. Hisa tulivu inayoshuka taratibu kwa miaka miwili inaweza kuonyesha drawdown kubwa huku ikiwa na volatility ya kawaida.
The low volatility anomaly inaangalia jinsi majina tulivu yanavyotenda katika muda mrefu, na Kelly criterion position sizing inaonyesha jinsi uvumilivu wa drawdown unavyogeuka kuwa ukubwa wa nafasi ya uwekezaji.
Yale ambayo namba haiwezi kukuambia
Kuna mipaka minne inayofaa kuzingatiwa:
- Hii ni njia moja iliyotekelezwa. Mchakato uleule ungeweza kutoa namba mbaya zaidi katika jaribio tofauti.
- Inategemea urefu wa sampuli, hivyo drawdown mbili zinaweza kulinganishwa tu ndani ya vipindi vinavyolingana.
- Inategemea mzunguko wa kuchukua sampuli. Bei za mwisho wa mwezi huficha viwango vya chini vya ndani ya siku na kutoa namba ndogo kuliko bei za mwisho wa siku kwa kipindi hicho hicho.
- Haina taarifa zozote za mbele. Kuwa asilimia thelathini chini ya kilele hakusemi chochote kuhusu kama pointi ya thelathini na moja itafika kesho.
Kikomo hicho cha mwisho ndiyo sababu mfumo wa kiotomatiki unahitaji sera ya drawdown badala ya kizingiti cha drawdown. "Simama kwa asilimia ishirini" hujibu swali moja na kuacha mawili bila majibu: nini kinatokea kwa nafasi zilizo wazi wakati wa kusimama, na ni ushahidi upi unaoufanya mfumo uanze tena. Circuit breakers kwa roboti za biashara huchunguza umbo la sera hiyo. Gharama ya sheria ya kiholela huonekana katika hatua ya kufufuka, ambapo mfumo unaosimama karibu na kiwango cha chini na kuanza tena kwa kuchelewa hukosa kupanda kwa soko. Kukosa siku bora huweka namba kwenye hesabu hiyo.
Maelezo moja ya kipimo ni muhimu kabla ya kulinganisha namba mbili: drawdown kwenye mfululizo wa bei ya mfuko na drawdown kwenye akaunti halisi hutofautiana wakati wowote pesa zinapoingia au kutoka na wakati wowote dividends zinapowasili, jambo ambalo jinsi mapato ya kila mwezi yanavyopimwa hulielezea kikamilifu.
Maswali yanayoulizwa mara kwa mara kuhusu maximum drawdown
Ni kiasi gani cha maximum drawdown kinachokubalika?
Hakuna kiasi cha kimataifa, bali kuna kigezo na muda wa kupimia. Katika kipindi cha miaka kumi hadi Julai 31, 2026, anguko kubwa zaidi la SPY kutoka kilele cha juu lilikuwa 34.2% kulingana na bei za kufunga soko za kila siku. Mkakati unaotaja namba ndogo zaidi katika sampuli fupi haumaanishi kuwa ni salama zaidi.
Je, maximum drawdown ni sawa na volatility?
Hapana. Volatility inaelezea mabadiliko ya kawaida ya kila siku; maximum drawdown inaelezea njia mbaya zaidi ya kushuka kutoka kilele hadi chini kabisa. Uwekezaji wenye volatility ya chini unaoweza kushuka mfululizo kwa miaka miwili unaweza kuwa na drawdown kubwa zaidi kuliko ule unaobadilika-badilika lakini unaoendelea kuweka viwango vipya vya juu.
Inachukua muda gani kurejea kutoka kwenye maximum drawdown?
Inatofautiana, na safari ya kupanda kurejea kileleni mara nyingi ndiyo sehemu ndefu zaidi. Kwa SPY tangu mwaka 2016, kipindi kirefu zaidi cha kushuka chini ya kilele cha awali kilichukua 181 ya siku za kalenda kutoka kilele hadi kufikia kilele kipya, ambapo 33 ya siku hizo zilitumika katika kushuka.
Je, maximum drawdown inatabiri hasara za baadaye?
Hapana. Inaelezea njia moja iliyokwisha tokea, na sampuli ndefu zaidi karibu kila mara hutoa namba kubwa zaidi. Inarekodi kile ambacho mkakati umestahimili hadi sasa, bila kikomo chochote kwa kitakachotokea baadaye.
Kila paneli hapo juu inahifadhi SQL inayoiendesha. Fungua moja, badilisha ticker au muda, na uendeshe hesabu hiyo hiyo ya drawdown kwenye terminal ya Strasmore.