ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
12
返回列表 发新帖
楼主: ericyoto

[求助] 请问怎么用VBA算最大回撤

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-9-21 13:54 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
cheetahfly 发表于 2014-11-18 13:07
楼主 所提的是一个金融投资方面的问题,用一般的excel计算方法去解答可能不全面,推荐http://zhiqiang.org/ ...

好文章,学习了

TA的精华主题

TA的得分主题

发表于 2018-10-18 11:33 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
8楼 @qy1219no2,你好,你的代码有一个bug:如果行情一直上涨 最大回撤应该是0 但这代码返回的值是正数。。

TA的精华主题

TA的得分主题

发表于 2019-5-16 19:15 | 显示全部楼层
本帖最后由 d11yushi 于 2019-5-16 20:53 编辑

楼主你好,已经帮你编了一个自定义函数,代码如下:
  1. Function MaxDrawdown(InvestReturn) As Double    Dim max As Double, mdd As Double
  2.     Dim InvestArr(), MaxArr(), MinArr(), Temp(), Drawdown(), Drawdown2D()
  3.     Dim i As Long, j As Long, k As Long, BM As Long, l As Long, i1 As Long, x As Long, y As Long
  4.     Dim step%
  5. '    Dim Peak As String, Through As String, MDDvalue As String
  6. '    Peak = "M3"
  7. '    Through = "M4"
  8. '    MDDvalue = "M5"

  9.     InvestArr = Range2Arr(InvestReturn)
  10.     j = 1
  11.     k = 0
  12.     step = 1

  13.     ReDim Preserve MaxArr(1 To 2, 1 To 1)
  14.     MaxArr(1, 1) = InvestArr(1)
  15.     MaxArr(2, 1) = 1

  16.     For i = 2 To UBound(InvestArr) - 1
  17.         If InvestArr(i + step) <= InvestArr(i) And InvestArr(i - step) <= InvestArr(i) Then
  18.             j = j + 1
  19.             ReDim Preserve MaxArr(1 To 2, 1 To j)
  20.             MaxArr(1, j) = InvestArr(i)
  21.             MaxArr(2, j) = i
  22.         End If
  23.         If InvestArr(i) <= InvestArr(i + step) And InvestArr(i) <= InvestArr(i - step) Then
  24.             k = k + 1
  25.             ReDim Preserve MinArr(1 To 2, 1 To k)
  26.             MinArr(1, k) = InvestArr(i)
  27.             MinArr(2, k) = i
  28.         End If
  29.     Next i

  30.     ReDim Preserve MinArr(1 To 2, 1 To k + 1)
  31.     MinArr(1, k + 1) = InvestArr(i)
  32.     MinArr(2, k + 1) = i

  33.     Temp = MaxArr
  34.     ReDim MaxArr(1 To j, 1 To 2)
  35.     MaxArr = Application.WorksheetFunction.Transpose(Temp)
  36.     Temp = MinArr
  37.     ReDim MinArr(1 To k, 1 To 2)
  38.     MinArr = Application.WorksheetFunction.Transpose(Temp)

  39.     ReDim Drawdown(1 To UBound(MaxArr), 1 To UBound(MinArr), 1 To 3)

  40.     For i1 = 1 To j
  41.         BM = BenchMark(MinArr, MaxArr(i1, 2)) '获取样本序列中MaxArr(i1,1)之后的波谷横坐标
  42.         For l = BM To k + 1
  43.             Drawdown(i1, l, 1) = (MaxArr(i1, 1) - MinArr(l, 1)) / MaxArr(i1, 1) '获取最大回撤
  44.             Drawdown(i1, l, 2) = MaxArr(i1, 2)                                  '获取波峰的横坐标
  45.             Drawdown(i1, l, 3) = MinArr(l, 2)                                   '获取波谷的横坐标
  46.         Next l
  47.     Next i1

  48.     ReDim Drawdown2D(1 To UBound(Drawdown, 1), 1 To UBound(Drawdown, 2))
  49.     For i = 1 To UBound(Drawdown, 1)
  50.         For j = 1 To UBound(Drawdown, 2)
  51.             Drawdown2D(i, j) = Drawdown(i, j, 1)
  52.         Next j
  53.     Next i

  54.     mdd = Application.WorksheetFunction.max(Drawdown2D)

  55. '    ReDim Temp(1 To 2)
  56. '    Temp = SearchCoordinates(mdd, Drawdown2D)
  57. '    x = Drawdown(Temp(1), Temp(2), 2)
  58. '    y = Drawdown(Temp(1), Temp(2), 3)
  59. '    MsgBox "最大回撤的两个坐标分别是:" & x & "和" & y & "。"
  60. '    Range(Peak).Value = x
  61. '    Range(Through).Value = y
  62. '    Range(MDDvalue).Value = mdd
  63.     MaxDrawdown = mdd

  64. End Function
  65. Function Range2Arr(Range1) As Variant
  66.     Dim arr()
  67.     Dim i As Long, n As Long

  68.     n = Range1.Rows.Count
  69.     ReDim arr(1 To n)
  70.     For i = 1 To n
  71.         arr(i) = Range1(i)
  72.     Next i
  73.     Range2Arr = arr
  74. End Function
  75. Function BenchMark(arr, bm0) As Long
  76.     Dim i As Long
  77.     For i = 1 To UBound(arr)
  78.         If arr(i, 2) > bm0 Then
  79.             Exit For
  80.         End If
  81.     Next i
  82.     BenchMark = i
  83. End Function
  84. Function MaxDrawdown2(InvestReturn) As Double
  85.     Dim max As Double, mdd As Double
  86.     Dim InvestArr(), MaxArr(), MinArr(), Temp(), Drawdown(), Drawdown2D()
  87.     Dim i As Long, j As Long, k As Long, BM As Long, l As Long, i1 As Long, x As Long, y As Long
  88.     Dim step%
  89.     Dim Peak As String, Through As String, MDDvalue As String
  90.     Peak = "M3"
  91.     Through = "M4"
  92.     MDDvalue = "M5"

  93.     InvestArr = InvestReturn
  94.     j = 1
  95.     k = 0
  96.     step = 1

  97.     ReDim Preserve MaxArr(1 To 2, 1 To 1)
  98.     MaxArr(1, 1) = InvestArr(1, 1)
  99.     MaxArr(2, 1) = 1

  100.     For i = 2 To UBound(InvestArr) - 1
  101.         If InvestArr(i + step, 1) <= InvestArr(i, 1) And InvestArr(i - step, 1) <= InvestArr(i, 1) Then
  102.             j = j + 1
  103.             ReDim Preserve MaxArr(1 To 2, 1 To j)
  104.             MaxArr(1, j) = InvestArr(i, 1)
  105.             MaxArr(2, j) = i
  106.         End If
  107.         If InvestArr(i, 1) <= InvestArr(i + step, 1) And InvestArr(i, 1) <= InvestArr(i - step, 1) Then
  108.             k = k + 1
  109.             ReDim Preserve MinArr(1 To 2, 1 To k)
  110.             MinArr(1, k) = InvestArr(i, 1)
  111.             MinArr(2, k) = i
  112.         End If
  113.     Next i

  114.     ReDim Preserve MinArr(1 To 2, 1 To k + 1)
  115.     MinArr(1, k + 1) = InvestArr(i, 1)
  116.     MinArr(2, k + 1) = i

  117.     Temp = MaxArr
  118.     ReDim MaxArr(1 To j, 1 To 2)
  119.     MaxArr = Application.WorksheetFunction.Transpose(Temp)
  120.     Temp = MinArr
  121.     ReDim MinArr(1 To k, 1 To 2)
  122.     MinArr = Application.WorksheetFunction.Transpose(Temp)

  123.     ReDim Drawdown(1 To UBound(MaxArr), 1 To UBound(MinArr), 1 To 3)

  124.     For i1 = 1 To j
  125.         BM = BenchMark(MinArr, MaxArr(i1, 2)) '获取样本序列中MaxArr(i1,1)之后的波谷横坐标
  126.         For l = BM To k + 1
  127.             Drawdown(i1, l, 1) = (MaxArr(i1, 1) - MinArr(l, 1)) / MaxArr(i1, 1) '获取最大回撤
  128.             Drawdown(i1, l, 2) = MaxArr(i1, 2)                                  '获取波峰的横坐标
  129.             Drawdown(i1, l, 3) = MinArr(l, 2)                                   '获取波谷的横坐标
  130.         Next l
  131.     Next i1

  132.     ReDim Drawdown2D(1 To UBound(Drawdown, 1), 1 To UBound(Drawdown, 2))
  133.     For i = 1 To UBound(Drawdown, 1)
  134.         For j = 1 To UBound(Drawdown, 2)
  135.             Drawdown2D(i, j) = Drawdown(i, j, 1)
  136.         Next j
  137.     Next i

  138.     mdd = Application.WorksheetFunction.max(Drawdown2D)

  139.     ReDim Temp(1 To 2)
  140.     Temp = SearchCoordinates(mdd, Drawdown2D)
  141.     x = Drawdown(Temp(1), Temp(2), 2)
  142.     y = Drawdown(Temp(1), Temp(2), 3)
  143. '    MsgBox "最大回撤的两个坐标分别是:" & x & "和" & y & "。"
  144.     Range(Peak).Value = x
  145.     Range(Through).Value = y
  146.     Range(MDDvalue).Value = mdd
  147.     MaxDrawdown2 = mdd

  148. End Function
  149. Sub mdd()
  150.     Dim Period As String, arr()
  151.     Dim Peak As String, Through As String, MDDvalue As String
  152.     Peak = "M3"
  153.     Through = "M4"
  154.     MDDvalue = "M5"
  155.     Period = Range("M2").Value
  156.     arr = Range(Period)

  157.     Call MaxDrawdown2(arr)
  158.     ActiveSheet.Shapes.AddChart2(227, xlLine).Select
  159.     ActiveChart.SetSourceData Source:=Range(Period)
  160.     ActiveChart.SetElement (msoElementDataLabelTop)
  161. End Sub
  162. Function SearchCoordinates(Goal As Double, arr) As Variant
  163.     Dim i As Long, j As Long
  164.     Dim brr(1 To 2)
  165. '    ReDim SearchCoordinates(1 To 2)
  166.     For i = 1 To UBound(arr, 1)
  167.         For j = 1 To UBound(arr, 2)
  168.             If arr(i, j) = Goal Then
  169.                 GoTo 100
  170.             End If
  171.         Next j
  172.     Next i
  173.     MsgBox "未找到"
  174.     Exit Function
  175. 100:
  176.     brr(1) = i
  177.     brr(2) = j

  178.     SearchCoordinates = brr
  179. End Function
复制代码



此外,为楼主编了个宏,可以定位最大回撤波峰、波谷的坐标,并且绘制折线图,便于检验。详见附件。

最大回撤计算.zip

31.59 KB, 下载次数: 94

TA的精华主题

TA的得分主题

发表于 2020-3-14 20:30 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
d11yushi 发表于 2019-5-16 19:15
楼主你好,已经帮你编了一个自定义函数,代码如下:

太牛了老师,请问波峰波谷坐标是计算区间内最大回撤的坐标吗

TA的精华主题

TA的得分主题

发表于 2021-8-22 22:24 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
d11yushi 发表于 2019-5-16 19:15
楼主你好,已经帮你编了一个自定义函数,代码如下:

您好,感谢分享代码,但是我测试后发现一个适用性问题,如果数据选择中有空值则无法返回运算结果,这个如何解决呢?

TA的精华主题

TA的得分主题

发表于 2022-12-4 17:47 | 显示全部楼层
d11yushi 发表于 2019-5-16 19:15
楼主你好,已经帮你编了一个自定义函数,代码如下:

请问各位,这位老师给的模板里面,MaxDrawdown2这个函数应该如何使用呢。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-20 14:20 , Processed in 0.040987 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表