You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
risk_analysis in qlib/contrib/evaluate.py builds the running peak only from the observed cumulative curve so the starting value is never treated as a peak and a loss in the first period is never part of max_drawdown
A series that opens with a 10% loss and then recovers reports a max drawdown of 0 in both sum and product mode and a series that opens with two 5% losses reports half of its real drawdown in sum mode
This is not about the absolute vs relative question in #1615 since the sum mode convention stays as it is and the only change is that the curve starts from 0 in sum mode and from 1 in product mode before the first period
importpandasaspdfromqlib.contrib.evaluateimportrisk_analysis# -10% on the first day, then a recoveryr=pd.Series([-0.10, 0.05, 0.06, 0.02, 0.01], index=pd.date_range("2024-01-02", periods=5, freq="B"))
print(risk_analysis(r, N=252, mode="sum").loc["max_drawdown", "risk"])
print(risk_analysis(r, N=252, mode="product").loc["max_drawdown", "risk"])
# two -5% days, then a recoveryr=pd.Series([-0.05, -0.05, 0.03, 0.04, 0.02], index=pd.date_range("2024-01-02", periods=5, freq="B"))
print(risk_analysis(r, N=252, mode="sum").loc["max_drawdown", "risk"])
print(risk_analysis(r, N=252, mode="product").loc["max_drawdown", "risk"])
Output on main
0.0
0.0
-0.05
-0.04999999999999993
Expected Behavior
the first series should report a max drawdown of -0.10 in both modes
the second should report -0.10 in sum mode and -0.0975 in product mode
empyrical max_drawdown gives -0.10 and -0.0975 for the same two series
Screenshot
Not needed since the output above shows it
Environment
Qlib version: 0.9.8.dev34 installed from main
Python version: 3.12.14
OS (Windows, Linux, MacOS): MacOS
Commit number (optional, please provide it if you are using the dev version): be72549
Additional Notes
risk_analysis is what PortAnaRecord writes to port_analysis.pkl so this is the max drawdown shown for excess return with and without cost in the standard workflow and the first day with cost starts with the opening trades
the same pattern is in _calculate_mdd in qlib/contrib/report/analysis_position/report.py which draws the drawdown lines in the report and in get_max_drawdown_from_series in qlib/contrib/evaluate_portfolio.py
Bug Description
risk_analysisinqlib/contrib/evaluate.pybuilds the running peak only from the observed cumulative curve so the starting value is never treated as a peak and a loss in the first period is never part ofmax_drawdownA series that opens with a 10% loss and then recovers reports a max drawdown of 0 in both
sumandproductmode and a series that opens with two 5% losses reports half of its real drawdown in sum modeThis is not about the absolute vs relative question in #1615 since the sum mode convention stays as it is and the only change is that the curve starts from 0 in sum mode and from 1 in product mode before the first period
To Reproduce
Steps to reproduce the behavior:
Output on main
Expected Behavior
max_drawdowngives -0.10 and -0.0975 for the same two seriesScreenshot
Not needed since the output above shows it
Environment
Windows,Linux,MacOS): MacOSAdditional Notes
risk_analysisis whatPortAnaRecordwrites toport_analysis.pklso this is the max drawdown shown for excess return with and without cost in the standard workflow and the first day with cost starts with the opening trades_calculate_mddinqlib/contrib/report/analysis_position/report.pywhich draws the drawdown lines in the report and inget_max_drawdown_from_seriesinqlib/contrib/evaluate_portfolio.py