ranaroussi / quantstats Goto Github PK
View Code? Open in Web Editor NEWPortfolio analytics for quants, written in Python
License: Apache License 2.0
Portfolio analytics for quants, written in Python
License: Apache License 2.0
Hello,
after creating a model in the stable baselines library anytrading (https://github.com/AminHP/gym-anytrading) and running the following code:
env = gym.make('stocks-v0', frame_bound=(50, 100), window_size=10)
model = DQN('MlpPolicy', env, tensorboard_log="D:\ReinforcementLearning\BaseLines\Trading\Tensorboard",
verbose=2)
results = model.learn(int(1000))
how do I use the results to compare with a benchmark in quantstats?
Currently the results doesn't hold the data that quantstats expect to be able to use in conjunction with qs.reports.html(results, "SPY", output="D:\ReinforcementLearning\BaseLines\Trading\Myreport.html")
I have a dataframe or series with daily returns for a model I have built... it contains just 2019 data - Jan 2nd to Dec 31st. The cumsum of that Close column in 17.86%. But when I run it through Quantstats, the HTML output is showing a cumulative return of 17.2%.
Even the sum of the monthly returns from the HTML shows 17.84%
Hi Ran,
I'm trying to get full report from cumulative returns pandas dataframe. Everything seems to be fine except EOY Returns.
2015 | 4063561685.19% | inf%
2016 | 5685063513.11% | inf%
2017 | 8068012580.76% | inf%
2018 | 9992995288.14% | inf%
2019 | 5817419000.9% | inf%
MTD | 0.55%
3M | 10.35%
6M | 15.35%
YTD | 12.37%
1Y | 5.07%
3Y (ann.) | 20.56%
5Y (ann.) | 26.93%
10Y (ann.) | 26.93%
All-time (ann.) | 26.93%
test.xlsx
Below two functions are not working in attached data.
Function returns:
OverflowError: cannot convert float infinity to integer
I am running the following backtesting with monthly returns:
# =============================================================================
# Backtesting strategy - I : Monthly portfolio rebalancing
# Author : Mayank Rasu
# Please report bug/issues in the Q&A section
# =============================================================================
import numpy as np
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as pdr
import datetime
import copy
import quantstats as qs
# Download historical data (monthly) for DJI constituent stocks
tickers = ["MMM","AXP","T","BA","CAT","CVX","CSCO","KO", "XOM","GE","GS","HD",
"IBM","INTC","JNJ","JPM","MCD","MRK","MSFT","NKE","PFE","PG","TRV",
"UNH","VZ","V","WMT","DIS","SPY","QQQ","TLT","LQD","GLD","SLV","IEI","AAPL"]
ohlc_mon = {} # directory with ohlc value for each stock
attempt = 0 # initializing passthrough variable
drop = [] # initializing list to store tickers whose close price was successfully extracted
while len(tickers) != 0 and attempt <= 5:
tickers = [j for j in tickers if j not in drop] # removing stocks whose data has been extracted from the ticker list
for i in range(len(tickers)):
try:
ohlc_mon[tickers[i]] = pdr.get_data_yahoo(tickers[i],datetime.date.today()-datetime.timedelta(5500),datetime.date.today(),interval='m')
ohlc_mon[tickers[i]].dropna(inplace = True)
drop.append(tickers[i])
except:
print(tickers[i]," :failed to fetch data...retrying")
continue
attempt+=1
tickers = ohlc_mon.keys() # redefine tickers variable after removing any tickers with corrupted data
################################Backtesting####################################
# calculating monthly return for each stock and consolidating return info by stock in a separate dataframe
ohlc_dict = copy.deepcopy(ohlc_mon)
return_df = pd.DataFrame()
for ticker in tickers:
print("calculating monthly return for ",ticker)
ohlc_dict[ticker]["mon_ret"] = ohlc_dict[ticker]["Adj Close"].pct_change()
return_df[ticker] = ohlc_dict[ticker]["mon_ret"]
# function to calculate portfolio return iteratively
def pflio(DF,m,x):
"""Returns cumulative portfolio return
DF = dataframe with monthly return info for all stocks
m = number of stock in the portfolio
x = number of underperforming stocks to be removed from portfolio monthly"""
df = DF.copy()
portfolio = []
monthly_ret = [0]
for i in range(1,len(df)):
if len(portfolio) > 0:
monthly_ret.append(df[portfolio].iloc[i,:].mean())
bad_stocks = df[portfolio].iloc[i,:].sort_values(ascending=True)[:x].index.values.tolist()
portfolio = [t for t in portfolio if t not in bad_stocks]
fill = m - len(portfolio)
new_picks = df.iloc[i,:].sort_values(ascending=False)[:fill].index.values.tolist()
portfolio = portfolio + new_picks
print(portfolio)
monthly_ret_df = pd.DataFrame(np.array(monthly_ret),columns=["mon_ret"])
return monthly_ret_df
Strategy = pflio(return_df,6,3)
Strategy["Date"] = return_df[1:].index.values
Strategy.set_index("Date", inplace = True)
#calculating KPIs for Index buy and hold strategy over the same period
SP500 = pdr.get_data_yahoo("^GSPC",datetime.date.today()-datetime.timedelta(5500),datetime.date.today(),interval='m')
SP500["mon_ret"] =SP500["Adj Close"].pct_change()
#len(DJI["mon_ret"][1:])
qs.reports.html(Strategy["mon_ret"], SP500["mon_ret"][1:], output='report2.html', title = "Monthly portfolio rebalancing")
But when requesting the report it throws me the following error:
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 127, in f
result = alt(values, axis=axis, skipna=skipna, **kwds)
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 479, in nanmean
the_sum = _ensure_numeric(values.sum(axis, dtype=dtype_sum))
File "C:\Users\Alexrios22\AppData\Roaming\Python\Python38\site-packages\numpy\core\_methods.py", line 38, in _sum
return umr_sum(a, axis, dtype, out, keepdims, initial, where)
ValueError: operands could not be broadcast together with shapes (12,) (11,)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 130, in f
result = alt(values, axis=axis, skipna=skipna, **kwds)
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 479, in nanmean
the_sum = _ensure_numeric(values.sum(axis, dtype=dtype_sum))
File "C:\Users\Alexrios22\AppData\Roaming\Python\Python38\site-packages\numpy\core\_methods.py", line 38, in _sum
return umr_sum(a, axis, dtype, out, keepdims, initial, where)
ValueError: operands could not be broadcast together with shapes (12,) (11,)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Alexrios22\Downloads\Trading\Curso Algorithmic Trading And Quantitative Analysis Using Python\Market Map\Rebalancing\Rebalancing.py", line 82, in <module>
qs.reports.html(Strategy["mon_ret"], SP500["mon_ret"][1:], output='report2.html', title = "Monthly portfolio rebalancing")
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\quantstats\reports.py", line 121, in html
_plots.yearly_returns(returns, benchmark, grayscale=grayscale,
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\quantstats\_plotting\wrappers.py", line 362, in yearly_returns
hline=returns.mean(),
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\generic.py", line 10945, in stat_func
return self._reduce(f, name, axis=axis, skipna=skipna,
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\series.py", line 3626, in _reduce
return op(delegate, skipna=skipna, **kwds)
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 76, in _f
return f(*args, **kwargs)
File "C:\Users\Alexrios22\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\nanops.py", line 138, in f
raise TypeError(e)
TypeError: operands could not be broadcast together with shapes (12,) (11,)
I had already run it before, and it hadn't given me that error, but now it does.
Hi,
I would appreciate some help to scale the report when using a benchmark.
As you will see from the attachment there is a very flat line that is hard to read.
Thanks
Fig
From: https://aroussi.com//assets/tearsheets/lazy.html
The drawdowns seem to be selected according to length, not depth. Can you confirm?
Maybe this should appear as a note under the plot.
Hey thanks so much for your great work here! It is super useful. Would it be possible to pass your functions a list of Tickers and Weights so i can get a full report on a buy and hold portfolio over time? Thanks so much! :)
Is there any reason why you calculate profit factor as
return abs(returns.sum() / returns[returns < 0].sum())
as opposed to:
return abs(returns[returns > 0].sum() / returns[returns < 0].sum())
I thought normally profit factor is total profit / total loss
As mentioned in the readme to let you know feedback..
Its a great project and wonderful with backtrader too.
I prefer to pyfolio
Keep up the good work!
Hi, how can I save the monthly returns table as a CSV file? Thank you
FutureWarning error in the utils.py module at line 94 in the rebase function.
Pandas' .ix is now deprecated and a simple change to .iloc[0] in the rebase function fixes this. I've run this in isolation and tested against both series and dataframe timeseries prices and it works well.
Hello,
First of all, thank you very much for releasing this lib publicly. I've been using it since it's so much simpler to use than many other ones.
I did come across a problem when there aren't any drawdowns or if there are fewer than 5 drawdowns. The problem is in at least two places that I've seen.
In stats._drawdown_details(drawdown)
, when returning None
here, some code later expects a DataFrame and therefore it fails.
# no drawdown :)
if len(starts) == 0:
return None
Even if above we return an empty DataFrame with the right column names, the code that uses this function still fails because range(1,6)
is assigned to an index:
E.g. in reports.full()
dd_info = _stats.drawdown_details(dd).sort_values(
by='max drawdown', ascending=True)[:5]
dd_info.index = range(1, 6) # <-- Fails here
Dear Project Team,
Not an issue per se, more a question. Is there an easy way to override the default colors used by Quantstats curves & graphs? I ve looked a bit the code; I have seen where there are defined. However, I d like to modify these colors without "forking"/duplicating the whole project?
Many thanks in advance
Regards,
Hi @ranaroussi ,
The static output works fine on visual studio but charts are not showing any output.
1
qs.plots.snapshot(df0['PPL_Return'],
title='PPL Performance')`
This command runs but no output is displayed. Is there any other command to add so that output can be displayed?
I wonder if we can use minutes return instead of daily returns input to quantstats?
backtest-result-2020-08-19_11-42-18.zip
Thanks for this awesome open source project. I try to link it to another exciting project which is -> https://github.com/freqtrade/freqtrade
In Freqtrade you can do backtests with the strategy being crafted - however the analysis tools are currently limited. The backtest results are exported as .json files (example enclosed).
I have tried to "cast" the backtest results in the input format of Quantstats, which was working well to the point of plotting the snapshot. Here is my code - probably not the most elegant way (I am not a coder):
import quantstats as qs
from freqtrade.data.btanalysis import load_backtest_data
# extend pandas functionality with metrics, etc.
qs.extend_pandas()
# load backtest data
backtest = load_backtest_data('/home/andreas/freqtrade/user_data/backtest_results/backtest-result-2020-08-19_11-42-18.json')
# define stake amount and compute equity curve
stake_amount = 100
max_open_trades = 10
stake_amount_total = stake_amount * max_open_trades
backtest['profit_amount'] = (backtest['profit_percent']) * stake_amount
backtest['cum_profit'] = backtest['profit_amount'].cumsum() # cumulated profits in stake currency
# prepare data for Quantstat format
backtest = backtest.set_index('close_date')
daily_resampled_data = backtest.cum_profit.resample('D').mean()
daily_resampled_data1 = daily_resampled_data.apply(lambda x: x + stake_amount_total) # add stake amount x max open trades
# feed own data into Quantstat "stock" algo
stock = daily_resampled_data1.pct_change()
# show performance plot
qs.plots.snapshot(stock, title='Performance')
When trying to apply the most interesting function (full report, benchmark e.g. LTC-USD) I got an error message:
qs.reports.basic(stock, "LTC-USD")
qs.reports.basic(stock, "LTC-USD")
<IPython.core.display.HTML object>
Traceback (most recent call last):
File "<ipython-input-217-a1e5d119cf6e>", line 1, in <module>
qs.reports.basic(stock, "LTC-USD")
File "/home/andreas/anaconda3/lib/python3.7/site-packages/quantstats/reports.py", line 259, in basic
compounded=compounded)
File "/home/andreas/anaconda3/lib/python3.7/site-packages/quantstats/reports.py", line 299, in metrics
dd = _calc_dd(df, display=(display or "internal" in kwargs))
File "/home/andreas/anaconda3/lib/python3.7/site-packages/quantstats/reports.py", line 588, in _calc_dd
by='days', ascending=False)['days'].values[0])),
ValueError: cannot convert float NaN to integer
What to do here?
After the last update of the code when importing quantstats it returns the error:
AttributeError: 'str' object has no attribute 'magic
I checked the code and it's an error on line 278 of utils.py. Where it reads
shell.magic("matplotlib inline")
should be
get_ipython().magic("matplotlib inline").
You're doing a great job! Go for it!
Hi,
Thanks for your library I'm using it.
I was getting a negative CAGR when my total return was positive. There are 2 issues I think, firstly the year calculation does not cope with periods less than a year. Secondly in the total return part you need to add back 1.0 before you do the power calculation.
E.g. If I make 10% for 2 years then my total returns should be 21%. My CAGR should obviously be 10%. To achieve this calculation I need to compute (0.21 + 1.0) ** (1/2.0) - 1
# years = len(set(returns.index.year))
years = (returns.index[-1] - returns.index[0]).days/365.0
# res = abs(total / 1.0) ** (1.0 / years) - 1
res = abs(total + 1.0) ** (1.0 / years) - 1
Hi, i use your module - thanks. i think the CAGR calculation is not correct. For example :
Strategie BM
Cumulative Return 81.23% 79.44%
CAGR% -1.38% -1.52%
to check this quick, i used:
https://www.investopedia.com/calculator/cagr.aspx
Beginning Value:
100
Ending Value:
181.23
Number of Periods:
14
Result: Compound Annual Growth Rate:4.34%
greets
Thanks for providing the great example for evaluating FB.
Can quantstats be used to evaluate a watchlist of stocks?
IndexError: invalid index to scalar variable.
when doing cvar = returns[returns<var].mean()[0]
In conditional value at risk fn
Hi Ran,
I have been using quantstats to generate a complete report of my portfolio with the function qs.reports.html but it gave me a TypeError. After exploring the error a little bit more, if I use the function qs.reports.full(trader.daily_returns, "SPY") in a jupyter notebook it gives the Output until the Cumulative Returns vs SPY (Volatility Matched). However while trying to print the graph EOY Returns vs Benchmark, the following error occurs:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-27-649f47ec8503> in <module>
----> 1 qs.reports.full(trader.daily_returns, "SPY")
~\Anaconda3\lib\site-packages\quantstats\reports.py in full(returns, benchmark, rf, grayscale, figsize, display, compounded)
247
248 plots(returns=returns, benchmark=benchmark,
--> 249 grayscale=grayscale, figsize=figsize, mode='full')
250
251
~\Anaconda3\lib\site-packages\quantstats\reports.py in plots(returns, benchmark, grayscale, figsize, mode, compounded)
509 grayscale=grayscale,
510 figsize=(figsize[0], figsize[0]*.5),
--> 511 show=True, ylabel=False)
512
513 _plots.histogram(returns, grayscale=grayscale,
~\Anaconda3\lib\site-packages\quantstats\_plotting\wrappers.py in yearly_returns(returns, benchmark, fontname, grayscale, hlw, hlcolor, hllabel, match_volatility, log_scale, figsize, ylabel, subtitle, compounded, savefig, show)
371 grayscale=grayscale,
372 ylabel=ylabel,
--> 373 subtitle=subtitle, savefig=savefig, show=show)
374
375
~\Anaconda3\lib\site-packages\quantstats\_plotting\core.py in plot_returns_bars(returns, benchmark, returns_label, hline, hlw, hlcolor, hllabel, resample, title, match_volatility, log_scale, figsize, grayscale, fontname, ylabel, subtitle, savefig, show)
110 if benchmark is None:
111 colors = colors[1:]
--> 112 df.plot(kind='bar', ax=ax, color=colors)
113
114 fig.set_facecolor('white')
~\Anaconda3\lib\site-packages\pandas\plotting\_core.py in __call__(self, *args, **kwargs)
792 data.columns = label_name
793
--> 794 return plot_backend.plot(data, kind=kind, **kwargs)
795
796 def line(self, x=None, y=None, **kwargs):
~\Anaconda3\lib\site-packages\pandas\plotting\_matplotlib\__init__.py in plot(data, kind, **kwargs)
60 kwargs["ax"] = getattr(ax, "left_ax", ax)
61 plot_obj = PLOT_CLASSES[kind](data, **kwargs)
---> 62 plot_obj.generate()
63 plot_obj.draw()
64 return plot_obj.result
~\Anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py in generate(self)
277 def generate(self):
278 self._args_adjust()
--> 279 self._compute_plot_data()
280 self._setup_subplots()
281 self._make_plot()
~\Anaconda3\lib\site-packages\pandas\plotting\_matplotlib\core.py in _compute_plot_data(self)
412 # no non-numeric frames or series allowed
413 if is_empty:
--> 414 raise TypeError("no numeric data to plot")
415
416 # GH25587: cast ExtensionArray of pandas (IntegerArray, etc.) to
TypeError: no numeric data to plot
got this data when running datasets including 02/29/2020
Traceback (most recent call last):
File "report.py", line 28, in
qs.reports.html(series, output='ASSET.html')
File "/usr/local/lib/python3.7/site-packages/quantstats/reports.py", line 61, in html
compounded=compounded)[2:]
File "/usr/local/lib/python3.7/site-packages/quantstats/reports.py", line 389, in metrics
df[df.index >= _dt(today.year-3, today.month, today.day)
ValueError: day is out of range for month
When I execute "qs.utils.download_returns('FB')" I get the following error message: AttributeError: module 'pandas.core.common' has no attribute '_dict_keys_to_ordered_list'.
The graphs and summary look really nice and powerful - thus it would be nice to use this library.
Should this be _stats.compsum(returns)
?
Hi, I think that when there is no drawdown, we will get the error:
ValueError: cannot convert float NaN to integer
This problem was previously closed without being completely fixed #2
Here's the error traceback:
Traceback (most recent call last):
File "test.py", line 269, in <module>
qs.reports.html(returns['net_worth'], benchmark, output=os.path.join(projectDir, 'report.html'))
File "/home/athena/anaconda3/envs/unicorn/lib/python3.8/site-packages/quantstats/reports.py", line 58, in html
mtrx = metrics(returns=returns, benchmark=benchmark,
File "/home/athena/anaconda3/envs/unicorn/lib/python3.8/site-packages/quantstats/reports.py", line 299, in metrics
dd = _calc_dd(df, display=(display or "internal" in kwargs))
File "/home/athena/anaconda3/envs/unicorn/lib/python3.8/site-packages/quantstats/reports.py", line 587, in _calc_dd
'Longest DD Days': str(round(bench_dd.sort_values(
ValueError: cannot convert float NaN to integer
Using quantstats 0.0.25, pandas 1.0.3
Thanks!
Hi,
I've come across an edge case that took me quite a while to debug.
Basically when a daily return is >= 100% (during backtesting, pennystocks etc), utils._prepare_prices()
thinks that the input series has already been converted to prices and it does nothing. This obviously messes up the calculations.
elif data.min() <= 0 and data.max() < 1:
data = to_prices(data, base)
For now as a hack I just clip all my returns to 0.9999.
Any thoughts on how to deal with this, given that it is an edge case... unfortunately :-)?
I think putting an or
instead of the and
might be more robust, but still not foolproof.
qs.reports.full(stock,benchmark='^NSEI',rf=0.065)
Performance Metrics
Strategy Benchmark
Start Period 2014-11-14 2014-11-14
End Period 2019-11-14 2019-11-14
Risk-Free Rate 0.06% 0.06%
Time in Market 100.0% 100.0%
Cumulative Return -100.0% -100.0%
CAGR% -100.0% -100.0%
Sharpe -62.45 -118.52
Sortino -15.39 -15.73
The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.
In html report we pass risk-free rate in year basis, but in calculating the excess_returns we have to substract the daily change.
def to_excess_returns(returns, rf, nperiods=None):
"""
Calculates excess returns by subtracting
risk-free returns from total returns
Args:
* returns (Series, DataFrame): Returns
* rf (float, Series, DataFrame): Risk-Free rate(s)
* nperiods (int): Optional. If provided, will convert rf to different
frequency using deannualize
Returns:
* excess_returns (Series, DataFrame): Returns - rf
"""
if not isinstance(rf, float):
rf = rf[rf.index.isin(returns.index)]
if nperiods is not None:
# deannualize
rf = _np.power(1 + returns, 1. / nperiods) - 1.
return returns - rf
Thank you very much for the very good work!
I am using quantstats to evaluate my trading strategies and I have some doubts about the data that quantstats is able to read.
A strategy that I trade signal to signal and is in a trade all the time works well.
Use one csv with one date and returns column like this
But in a strategy that opens one day and closes another day, and in between days may pass no longer.
1- Can you put two dates, one entry and one exit? How would the code for this be?
Another question, and I don't know if this is covered by quantstats, is the function of pyramid.
2-I have a strategy in which I do up to three pyramid trades, but when I enter the data into quantstats, I compose them too much and it gives unrealistic results.
3-May I add the option of non-compounding returns?
I think that in the case of the pyramid this will be an option.
Enter each trade with a fixed amount.
Shared one spreadshet with the trades:
The most important stats are : signal type, date with hour, price, contract (strategy is set for take profit 35% in certain circumstances, profit %)
https://docs.google.com/spreadsheets/d/1OdI3e38OsEDSh5gQLdNtW75DaHtgshpvRI6HofaE00I/edit#gid=0
I'm not sure what kind of analysis I can do for this strategy to get the right results.
Sorry about the long post. Cheers and thanks.
Currently the stats.py annualizes using 252 period. There needs to be an option for 365 for crypto.
For running HTML reports, I can't see a straightforward way to annualise without overwritting the stats.py file.
Ideally this should be an input in reports.py.
Thanks
Hello people,
I'm trying to run the examples but for some reason the charts don't get displayed. It looks like the window flashes and closes itself straight after.
Has anyone else faced similar issue?
Thanks all
Can I use this library to monitor my live performace on an API for eg: Binance.
When evaluating a strategy over short time horizon, report shows stats for invalid time periods e.g. returns for 5Y (ann) and 10Y (ann).
I would prefer to not show data. Instead replace with: "" or "-" or "na"
Dependabot couldn't authenticate with https://pypi.python.org/simple/.
You can provide authentication details in your Dependabot dashboard by clicking into the account menu (in the top right) and selecting 'Config variables'.
Hi,
I'm trying to install QuantStats for Anaconda using this command:
"conda install -c ranaroussi quantstats"
I am facing the following error:
"_The following NEW packages will be INSTALLED:
multitasking ranaroussi/noarch::multitasking-0.0.9-py_0
quantstats ranaroussi/noarch::quantstats-0.0.25-py_0
tabulate pkgs/main/win-64::tabulate-0.8.3-py37_0
yfinance ranaroussi/noarch::yfinance-0.1.54-py_0
Proceed ([y]/n)? y
Downloading and Extracting Packages
yfinance-0.1.54 | 735 KB | ############################################################################ | 100%
InvalidArchiveError('Error with archive C:\Users\mihae\Anaconda3\pkgs\yfinance-0.1.54-py_0.tar.bz2. You probably need to delete and re-download or re-create this file. Message from libarchive was:\n\nCould not unlink (errno=22, retcode=-25, archive_p=1835644343904)')_
"
I've tried the suggested solution (delete and try again) but I haven't much success.
Could you please support me?
Thanks a lot,
Adriana
First of all, I would like to thank for this really awesome tool. I have been trying to use it for some time and from the examples I see that almost all the functions need returns as input to generate the stats and tearsheet etc.
My doubt is that what kind of returns does this library assume. Is it simple returns calculated using pct_change() in pandas or log returns calculated using np.log(close_price).diff().
Hi,
I'd like to create a nice PDF using Quantstats.
Is there a better way to do it other than:
The problem is, a number of the charts get cut off and split across pages.
Please Let me know if there is a nice way to save and share these reports, ideally PDF!
Thank you,
CWSE
Hello,
First of all, thank you for your amazing library and work, is great!
I'm using it and I think I have discovered two little bugs:
1.- In reports.py line 71; today = _dt.today()
This line is good if the final date of the returns is equal to today(), but if we are doing a backtest, and the final date of teh returns where 2 years ago, this line is not correct. I think this can be solved changing that line to:
today = df.index[-1]
2.- In reports.py line 217; dd_info.index = range(1, 6)
The code breaks were there is less than 5 drawdowns. This can happen easily if our portfolio don't do to many operations. I think this can be fixed changing that line to:
dd_info.index = range(1, min(6, len(dd_info)+1))
3.- Finally, when I execute the some reports that include plots, I get the following error (executing the code from pycharm console):
...\lib\site-packages\quantstats\_plotting\wrappers.py:154: MatplotlibDeprecationWarning:
Passing the block parameter of show() positionally is deprecated since Matplotlib 3.1; the parameter will become keyword-only in 3.3.
I have tried to change every _plt.show(fig)
to_plt.show(fig, block=False)
and still not working, any idea of how can be solved that?
hello everyone, how much I try to do :
qs.reports.html(returns=stock,benchmark=bench,output="report.html")
UnicodeEncodeError Traceback (most recent call last)
in
----> 1 qs.reports.html(returns=stock,benchmark=bench,output='1.html')
~\Miniconda3\envs\quant\lib\site-packages\quantstats\reports.py in html(returns, benchmark, rf, grayscale, title, output, compounded)
205
206 with open(output, 'w') as f:
--> 207 f.write(tpl)
208
209
~\Miniconda3\envs\quant\lib\encodings\cp1252.py in encode(self, input, final)
17 class IncrementalEncoder(codecs.IncrementalEncoder):
18 def encode(self, input, final=False):
---> 19 return codecs.charmap_encode(input,self.errors,encoding_table)[0]
20
21 class IncrementalDecoder(codecs.IncrementalDecoder):
UnicodeEncodeError: 'charmap' codec can't encode character '\u2212' in position 649916: character maps to <undefined>
Any solution?
Thank you very much for your work!
The start date is found a position after the correct one.
I am trying to run this code
import quantstats as qs
stock = qs.utils.download_returns('FB')
qs.reports.html(stock, "SPY")
the output I get on my spyder ide is:
<IPython.core.display.HTML object>
How do I save it as html in my pc?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.