mmaxDrawdown
First introduced in version 3.00.6
Syntax
mmaxDrawdown(X, window, [ratio=true], [minPeriods])
Alias: mmdd
Details
Calculates the moving maximum drawdown or moving maximum drawdown rate. NULL values are ignored in the calculation.
Parameters
X is a numeric vector, matrix, or table that specifies the data used to calculate the maximum drawdown. It typically contains cumulative returns or rates of return.
window is a positive integer or a DURATION scalar.
- If window is a positive integer, it specifies the moving window length measured by the number of elements.
- If window is a DURATION, it specifies the moving window length measured by time. In this case, X must be an indexed matrix or indexed series with a temporal row index.
ratio is a Boolean scalar that specifies whether to return the maximum drawdown rate. The default value is true.
If true, returns the maximum drawdown rate, which is the maximum percentage decline relative to the peak. The formula is:

If false, returns the maximum drawdown based on the absolute decline amount. The formula is:

minPeriods is a positive integer that specifies the minimum number of non-NULL elements required in the moving window. If the number of non-NULL elements in the moving window is less than minPeriods, the result for that window is NULL. The default value is the same as window. If window is a DURATION and minPeriods must be set, minPeriods must be 1.
Returns
A DOUBLE value with the same form as the input data X.
Examples
Example 1: Store the cumulative returns of a portfolio in an in-memory table, and calculate the moving maximum drawdown of the cumulative returns over a 3-day window.
// Create an in-memory table to record the cumulative returns of a portfolio over 8 consecutive days
t = table(2024.10.01 + 0..7 as date, [36, 96, 42, 100, 59, 86, 25, 72] as cumReturn)
| date | cumReturn |
|---|---|
| 2024.10.01 | 36 |
| 2024.10.02 | 96 |
| 2024.10.03 | 42 |
| 2024.10.04 | 100 |
| 2024.10.05 | 59 |
| 2024.10.06 | 86 |
| 2024.10.07 | 25 |
| 2024.10.08 | 72 |
// Calculate the moving maximum drawdown of the portfolio's cumulative returns over a 3-day window
select date, cumReturn as MDD_in_3days from mmaxDrawdown(t, 3, false)
| date | MDD_in_3days |
|---|---|
| 2024.10.01 | |
| 2024.10.02 | |
| 2024.10.03 | 54 |
| 2024.10.04 | 54 |
| 2024.10.05 | 41 |
| 2024.10.06 | 41 |
| 2024.10.07 | 61 |
| 2024.10.08 | 61 |
Example 2: Store the cumulative returns of a portfolio in an indexed matrix, and calculate the moving maximum drawdown rate of the cumulative returns over a 3-day window.
// Create an indexed matrix to record the cumulative returns of a portfolio over 8 consecutive days
m = matrix(1..8, 36 96 42 100 59 86 25 72)
m.rename!(2024.10.01..2024.10.08, `No.`cumReturn)
m.setIndexedMatrix!()
| No. | cumReturn | |
|---|---|---|
| 2024.10.01 | 1 | 36 |
| 2024.10.02 | 2 | 96 |
| 2024.10.03 | 3 | 42 |
| 2024.10.04 | 4 | 100 |
| 2024.10.05 | 5 | 59 |
| 2024.10.06 | 6 | 86 |
| 2024.10.07 | 7 | 25 |
| 2024.10.08 | 8 | 72 |
// Calculate the moving maximum drawdown rate of the portfolio's cumulative returns over a 3-day window.
// The result is a matrix. Use the col function to retrieve the result vector.
round(mmaxDrawdown(m,3d,true).col(1), 2)
// Output: [0,0,0.56,0.56,0.41,0.41,0.71,0.71]
Example 3: Simulate market data for CSI 300 stocks and calculate the 5-day moving maximum drawdown rate.
// Set the stocks and observation dates for simulation.
securities = `600519.SH`000858.SZ`601318.SH`600036.SH`000333.SZ
n = 10
dates = 2024.01.02 + 0..(n - 1)
// Simulate closing prices.
stockInfo = table(securities as securityID)
dateInfo = table(dates as tradeDate)
price = cj(stockInfo, dateInfo)
price[`close] = round(100 + rand(20.0, size(securities) * n), 2)
price = select * from price order by securityID, tradeDate
// Calculate the 5-day moving maximum drawdown rate for each stock.
result = select tradeDate,
securityID,
close,
round(mmaxDrawdown(close, 5, true), 4) as mdd5
from price
context by securityID
select * from result where tradeDate >= 2024.01.08
Because close is generated from random numbers, the prices and drawdown rates differ each time the script runs. A sample of the output is shown below:
| tradeDate | securityID | close | mdd5 |
|---|---|---|---|
| 2024.01.08 | 000333.SZ | 111.2 | 0.0291 |
| 2024.01.09 | 000333.SZ | 110.83 | 0.017 |
| 2024.01.10 | 000333.SZ | 110.45 | 0.017 |
| 2024.01.11 | 000333.SZ | 109.77 | 0.0129 |
| 2024.01.08 | 000858.SZ | 117.32 | 0.1036 |
| 2024.01.09 | 000858.SZ | 111.15 | 0.1036 |
| 2024.01.10 | 000858.SZ | 106.04 | 0.1036 |
| 2024.01.11 | 000858.SZ | 108.65 | 0.0961 |
| 2024.01.08 | 600036.SH | 114.27 | 0.1285 |
Related function: maxDrawdown
