ranaroussi / quantstats

Portfolio analytics for quants, written in Python
Apache License 2.0
4.73k stars 827 forks source link

Chart "Monthly Returns (%)" shows all zero #255

Closed RuralHunter closed 1 year ago

RuralHunter commented 1 year ago

Hi, I'm running quantstats on Ubuntu 20.04 and found the "Monthly Returns (%)" chart shows all "0.0" for every months. Other charts are all fine. I run the same code on another Windows system and the "Monthly Returns (%)" is fine. Not sure what's the problem on the Ubuntu system.

RuralHunter commented 1 year ago

There are 2 warnings on Ubuntu, not sure if it's related to the problem: findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans. /home/xxxxxx/.local/lib/python3.8/site-packages/quantstats/stats.py:968: FutureWarning: In a future version of pandas all arguments of DataFrame.pivot will be keyword-only. returns = returns.pivot('Year', 'Month', 'Returns').fillna(0)

RuralHunter commented 1 year ago

Figured out the problem. The month names generated in quantstats on my platform is Chinese:

             Returns  Year Month
2016-07-01  0.009674  2016    7月
2016-08-01  0.039612  2016    8月
2016-09-01 -0.080099  2016    9月
2016-10-01  0.022045  2016   10月
2016-11-01 -0.003973  2016   11月
...              ...   ...   ...
2022-11-01  0.040734  2022   11月
2022-12-01  0.006401  2022   12月
2023-01-01  0.007737  2023    1月
2023-02-01  0.000505  2023    2月
2023-03-01  0.060410  2023    3月

However, in the code here:

    # handle missing months
    for month in ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']:
        if month not in returns.columns:
            returns.loc[:, month] = 0

Quantstats checks English month names and fill others with 0. The fix should be finding where the month names are generated and using only English names

RuralHunter commented 1 year ago

It's on this line. I changed it like this and it works:

    import locale    
    old_locale=locale.getlocale(locale.LC_ALL)
    locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
    returns['Month'] = returns.index.strftime('%b')
    locale.setlocale(locale.LC_ALL, old_locale)