mmaxDrawdown
首发版本:3.00.6
语法
mmaxDrawdown(X, window, [ratio=true], [minPeriods])
别名:mmdd
详情
计算滑动最大回撤(Maximum Drawdown)或滑动最大回撤率(Maximum Drawdown Rate)。计算时忽略空值。
参数
X 数值向量、矩阵或表,指定参与最大回撤计算的数据,一般为累计的收益或收益率。
window 正整数或 DURATION 标量。
- 当 window 为正整数时,指定以元素个数衡量的滑动窗口长度。
- 当 window 为 DURATION 时,指定以时间衡量的滑动窗口长度。此时,X 必须是带有时间类型行索引的索引矩阵或者索引序列。
ratio 布尔标量,指定是否返回最大回撤率。默认值为 true。
若为 true,返回最大回撤率,即相对于峰值的最大下降百分比,计算公式为:

若为 false,返回基于下降金额绝对值的最大回撤,计算公式为:

minPeriods 正整数标量,指定滑动窗口中最少包含的非 NULL 元素个数。如果滑动窗口中的元素个数小于 minPeriods,该窗口的计算结果为 NULL。默认值与 window 相等。 如果 window 是 DURATION,且需要设置 minPeriods 时,minPeriods 必须是 1。
返回值
DOUBLE 类型,形式和输入数据 X 保持一致。
例子
例 1:用内存表存储投资组合的累计收益,以 3 天为一个窗口,滑动计算累计收益的最大回撤。
// 创建内存表,记录某投资组合连续 8 天的累计收益
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 |
// 以 3 天为一个窗口,滑动计算投资组合累计收益的最大回撤
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 |
例 2:用索引矩阵存储投资组合的累计收益,以 3 天为一个窗口,滑动计算累计收益的最大回撤率。
// 创建索引矩阵,记录某投资组合连续 8 天的累计收益
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 |
// 以 3 天为一个窗口,滑动计算投资组合累计收益的最大回撤率
// 返回结果是一个矩阵,通过 col 函数取得计算结果向量
round(mmaxDrawdown(m,3d,true).col(1), 2)
// 输出:[0,0,0.56,0.56,0.41,0.41,0.71,0.71]
例 3:模拟沪深 300 成分股行情,计算 5 日滑动最大回撤率。
// 设置待模拟的股票和观察日
securities = `600519.SH`000858.SZ`601318.SH`600036.SH`000333.SZ
n = 10
dates = 2024.01.02 + 0..(n - 1)
// 模拟生成收盘价
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
// 对每只股票分别计算 5 日滑动最大回撤率
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
由于 close 使用随机数生成,每次运行得到的价格和回撤率不同。部分输出示例如下:
| 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 |
相关函数:maxDrawdown
