GithubHelp home page GithubHelp logo

fmilthaler / finquant Goto Github PK

View Code? Open in Web Editor NEW
1.3K 31.0 186.0 1.19 MB

A program for financial portfolio management, analysis and optimisation.

License: MIT License

Makefile 0.88% Python 97.72% Shell 1.40%
portfolio-management portfolio-optimisation optimisation finance financial-analysis analysis financial financial-portfolio-management moving-average bollinger-bands

finquant's People

Contributors

drcsturm avatar fmilthaler avatar herrfz avatar noxan avatar pietropaolofrisoni avatar slpenn13 avatar texify[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

finquant's Issues

yfinance returns no data.

When using yfinance as the data source no data is returned.
In portfolio.py line 791
start_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")

Question about plotting EF

Hey thanks so much for all your work here! It is really useful for me.

The plots look particularly great. My question is, is there a way to get the EF plot to also show the "black line" that defines the efficient frontier? It shows that in your example picture in ReadMe but not in the plot that is actually generated. Very minor, really for aesthetics sake. Thank you so much! :)

comp_cumulative_returns() weird behaviour

Hi

I do have a portfolio where some of the stocks have data starting at different time (some are more recent). I build my own Dataframe, so it's made to have an index that is date, and then if one stock still has no data when another one has, for that date the value for the stock still not started will be 0.0.

I then use FinQuant, giving it my Dataframe with the stocks and another with the weights, and do all calculations I need.

It works in every aspects I use, and I use pretty much all the functions, but one function, comp_cumulative_returns() fails to deal correctly with the data. If one of the stocks in portfolio starts later than the others, and so in the dataframe the prices for that stock are 0.0 till the 'real' data starts, that function doesn't work and the resulting output has 0.0 for the whole sequence of that specific stock.

Any hint about how to deal with this case?

Update documentation

Some of the new classes, e.g. market and asset are currently not in the documentation
When you are bored... Redo documentation to include proper support for type hints (after type hints are consistently implemented and tested with mypy).

How to use with lib plotly

Congratulations for the work. Excellent library!

How to use the efficient frontier data to plot in the plotly library the EF Min Volatility and EF Max Sharpe Ratio?

Thanks

'Index' object has no attribute 'tz_localize'

Hi there,

Tried to download the stock price from yfinance, used the code snippest in documentation.

from finquant.portfolio import build_portfolio
names = ['GOOG', 'AMZN', 'MCD', 'DIS']
pf = build_portfolio(names=names, data_api="yfinance")

But once I run it, it says 'AttributeError: 'Index' object has no attribute 'tz_localize''

Thanks in advance.

Regarding using index as stocks

Hi Sir,
I have just started with Python and cam across the FinQuant documentation. Was successful in replicating the code for stocks, but when i am trying to use S&P, FTSE and Nikkei in place of stocks then i receive an error. So could help me with the issue.

Error on data download

getting error when i run the commend
pf = build_portfolio(names=['GOOG', 'AMZN'],
start_date=start_date,
end_date=end_date)

Exception: Error during download of stock data from Quandl.
Make sure all the requested stock names/tickers are supported by Quandl.

Kindly solve the issue

Regularization Function / Bounds Config

Hello @fmilthaler !

I'm having some dificulty to use ef_maximum_sharpe_ratio with a more "spreaded" allocation... Would it be possible to add some regularization function to avoid the optimizer to concentrate allocation in only 1 or 2 stocks?
Another way to resolve this could be to add some "per stock" or global limit settings (lower and upper). I don't know wich solution is better.... E.g: only allow a maximum of 80% of portfolio allocation for each stock.

Thanks!

Inverted Axis when plotting

When running this code, that was extracted from the examples of the documentation, the plot seems to be inverted and since i simply copied/pasted the code i really dont know what would go wrong.
``#%%
from finquant.portfolio import build_portfolio
names = ['GOOG', 'AMZN', 'MCD', 'DIS']
pf = build_portfolio(names=names, data_api="yfinance")
from finquant.moving_average import compute_ma, ema

get stock data for Disney

dis = pf.get_stock("DIS").data.copy(deep=True)
spans = [10, 50, 100, 150]

computing and visualising a band of moving averages

ma = compute_ma(dis, ema, spans, plot=True)
print(ma.tail())`
plot

`

Depciation warning 5.0

Dear hero's

Im using your libary heavly but now there is a problem: this error keeps popping up:
\finquant\monte_carlo.py:37: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return np.asarray(result)

Are you still alive? Is there a possiblity for you to fix this?
Can I fix it?

ValueError when optimizing a portfolio with 3 indices

I'm currently having an issue running the demo code when I try to run the mc_optimisation with 3 stocks in the portfolio. I've tried running with 2 stocks as well as portfolios with more than 3 stocks and everything seems to work fine. However, when I setup a portfolio with 3 stocks, I run into the following error.

ValueError: Shape of passed values is (2, 5000), indices imply (2, 3)

Code that produced the error:

from finquant.portfolio import build_portfolio

names = ['MSFT', 'AAPL', 'GOOG']

start_date = '2015-01-01'
end_date = '2020-04-25'
pf = build_portfolio(names=names,
start_date=start_date,
end_date=end_date, data_api="yfinance")

opt_w, opt_res = pf.mc_optimisation(num_trials=5000)

Limit allocation weights

Thanks for the great work at this library.

How can I set the lower and upper limit for the allocation of shares in the portfolio when calculating EfficientFrontier? E.g. not less than 2% and not more than 15% per title.

Thank you

Mira

Use type hints consistently

As part of that: where a variable could be either pd.Series or pd.DataFrame, do sth like the following:

DataFrameOrSeries = Union[pd.DataFrame, pd.Series]

def compute_ma(
    data: DataFrameOrSeries, fun: Callable, spans: List[int], plot: bool = True
) -> pd.DataFrame:
    # rest of function

While at it, fix pylint issues as well.

MCOpt plot: Add "MC" to label

Adding "MC" or "Monte-Carlo" to labels of Monte Carlo optimisation plots. Easier to distinguish it from the Efficient Frontier output.

Momentum Indicators - RSI, MACD

First of all thanks for the great work. This package is amazing!

I think apart from moving averages and related bollinger bands, indicators like RSI would add relative strength to the package (pun intended). Let me know what you think.

This issue is about adding a feature for plotting RSI indicators using a 14 day window as suggested using the approach here -> https://www.alpharithms.com/relative-strength-index-rsi-in-python-470209/

Update: Edited the issue and generalized it over a number of momentum indicators. I can go ahead and implement them all or we can discuss it if you have suggestions.

Naive question regarding Allocation

Hello Frank,

Awesome job on Finquant. I was trying to use however, I myself am new to finance. I had a question.
The allocation column in a portfolio. Are they number of units of stocks? or are they weighted?
also. How do I input what is my average price for which i bought these stocks?

Sorry had to ask you via issues since there was not other way to contact. you.

Thanks for your help

Regards

Sriram

pf._udpate() called numerous times when adding stocks in bulk.

I noticed when adding a number of stocks to a portfolio the time to add them takes longer and longer. Adding a deferment to the pf._update() call seems to resolve this and makes adding bulk stocks much faster. Pull request to follow for your consideration.

Depreciation pandas

Error while using package

error

-packages\finquant\portfolio.py:260: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
self.portfolio = self.portfolio.append(stock.investmentinfo, ignore_index=True)

Cant this problem be solved.

Unit Test Revamp - Efficient Frontier and Monte Carlo

Hi @fmilthaler / @PietropaoloFrisoni,

When you guys get the time, could you add some unit tests for the monte_carlo and efficient_frontier modules? I feel that these are as essential as the portfolio file. Understanding the effect of changes to preserving the functionality could be made clearer through a few more comprehensive unit tests.

Thanks for your continued hard work.

ValueError: Could not find column labels in given dataframe.

Hi

I'm exploring Finquant as it seems really the best library out there for quick portfolio optimisation.

I'm testing it following the examples for csv files, it works with the test provided .csv, when I try with my ones I can create a portfolio equally balanced without problems (so without providing the weights from portfolio.csv), but when I try giving custom weights I receive error:

ValueError Traceback (most recent call last)
in
50 print(df_data)
51
---> 52 pf = build_portfolio(data=df_data, pf_allocation=df_pf)
53 #pf = build_portfolio(data=df_data)
54

/usr/local/lib/python3.7/site-packages/finquant/portfolio.py in build_portfolio(**kwargs)
1181 )
1182 # get portfolio:
-> 1183 pf = _build_portfolio_from_df(**kwargs)
1184
1185 # final check

/usr/local/lib/python3.7/site-packages/finquant/portfolio.py in _build_portfolio_from_df(data, pf_allocation, datacolumns)
1037 # extract only "Adjusted Close" price ("Adj. Close" in quandl, "Adj Close" in yfinance)
1038 # column from DataFrame:
-> 1039 data = _get_stocks_data_columns(data, pf_allocation.Name.values, datacolumns)
1040 # building portfolio:
1041 pf = Portfolio()

/usr/local/lib/python3.7/site-packages/finquant/portfolio.py in _get_stocks_data_columns(data, names, cols)
875 # else, error
876 else:
--> 877 raise ValueError("Could not find column labels in given dataframe.")
878 # append correct name to list of correct names
879 reqcolnames.append(colname)

ValueError: Could not find column labels in given dataframe.

I've tried looking into portfolio.py to see why I get the error with my .csv only, but I can't see honestly where is the problem.

This is my stocks file containing the close prices (it works):

EQQQ float64
IWFM float64
IGLT float64
IBTM float64
SGLN float64
STM float64
dtype: object
EQQQ IWFM IGLT IBTM SGLN STM
Date
2015-01-02 6721.0 1694.75 12.44 128.51 1532.5 246.4
2015-01-05 6713.0 1690.25 12.51 130.25 1554.5 242.0
2015-01-06 6670.0 1684.75 12.61 131.75 1579.0 241.5
2015-01-07 6724.0 1706.00 12.58 132.54 1597.5 245.1
2015-01-08 6866.0 1740.00 12.55 131.73 1593.0 252.7

And this is my portfolio.csv containing the weights:

Allocation float64
Name object
dtype: object
Allocation Name
0 20.25 EQQQ
1 10.97 IWFM
2 29.44 IGLT
3 28.56 IBTM
4 9.67 SGLN
5 1.11 SMT

Any idea how can I make it work and what's the problem? As I said it works with test data CSV in your repo...

Plotting error

`import os

import numpy as np
import pandas as pd
from finquant.portfolio import build_portfolio
from finquant.moving_average import compute_ma, ema

names = ['GOOG', 'AMZN', 'MCD', 'DIS']
pf = build_portfolio(names=names, data_api="yfinance")

get stock data for Disney

dis = pf.get_stock("DIS").data.copy(deep=True)

dis.index = dis.index.map(str)

np.save("dis_data.npz", dis)

dis.to_csv("dis.csv")

spans = [10, 50, 100, 150, 200]

computing and visualising a band of moving averages

ma = compute_ma(dis, ema, spans, plot=True)
print(ma.tail())
`


`ssh://leef_wsl_u18@localhost:22/home/leef_wsl_u18/miniconda3/envs/py36/bin/python -u /home/leef_wsl_u18/.pycharm_helpers/pydev/pydevd.py --cmd-line --multiproc --qt-support=auto --client 0.0.0.0 --port 55053 --file /tmp/rd_finquant/rd_leef/rd2.py
Connected to pydev debugger (build 211.7142.13)
[100%**] 4 of 4 completed
Traceback (most recent call last):
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/contextlib.py", line 99, in exit
self.gen.throw(type, value, traceback)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py", line 85, in pandas_converters
yield
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py", line 65, in wrapper
return func(*args, **kwargs)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/pandas/plotting/_matplotlib/core.py", line 668, in _plot
return ax.plot(*args, **kwds)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/init.py", line 1892, in inner
return func(ax, *args, **kwargs)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 1407, in plot
self.add_line(line)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 1787, in add_line
self._update_line_limits(line)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 1809, in _update_line_limits
path = line.get_path()
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/lines.py", line 989, in get_path
self.recache()
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/lines.py", line 672, in recache
xconv = self.convert_xunits(self._xorig)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/artist.py", line 199, in convert_xunits
return ax.xaxis.convert_units(x)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/axis.py", line 1472, in convert_units
ret = self.converter.convert(x, self.units, self)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py", line 256, in convert
values = DatetimeConverter._convert_1d(values, unit, axis)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py", line 291, in _convert_1d
values = dates.date2num(values)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/dates.py", line 362, in date2num
return _to_ordinalf_np_vectorized(d)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/numpy/lib/function_base.py", line 2108, in call
return self._vectorize_call(func=func, args=vargs)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/numpy/lib/function_base.py", line 2186, in _vectorize_call
ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/numpy/lib/function_base.py", line 2146, in _get_ufunc_and_otypes
outputs = func(*inputs)
File "/home/leef_wsl_u18/miniconda3/envs/py36/lib/python3.6/site-packages/matplotlib/dates.py", line 220, in _to_ordinalf
python-BaseException
base = float(dt.toordinal())
AttributeError: 'numpy.datetime64' object has no attribute 'toordinal'

Process finished with exit code 1
`

"Could not find column labels in given dataframe."

When trying to get data from Quandl I get the an error (made sure ticker names are correct beforehand):

`d = {
0: {"Name": "XLON/BP_", "Allocation": 1000000},
1: {"Name": "XLON/III", "Allocation": 1000000},
2: {"Name": "XLON/GSK", "Allocation": 1000000},
3: {"Name": "XLON/OCDO", "Allocation": 1000000},
4: {"Name": "XLON/RBS", "Allocation": 2000000},
5: {"Name": "XLON/SVT", "Allocation": 1000000},
}

pf_allocation = pd.DataFrame.from_dict(d, orient="index")

#set list of names based on names
names = pf_allocation["Name"].values.tolist()`

This is the error message:

`runfile('C:/Users/Joe Shiafa Pierce/.spyder-py3/FinQuant POM project.py', wdir='C:/Users/Joe Shiafa Pierce/.spyder-py3')
Traceback (most recent call last):

File "", line 1, in
runfile('C:/Users/Joe Shiafa Pierce/.spyder-py3/FinQuant POM project.py', wdir='C:/Users/Joe Shiafa Pierce/.spyder-py3')

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 786, in runfile
execfile(filename, namespace)

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Joe Shiafa Pierce/.spyder-py3/FinQuant POM project.py", line 40, in
names=names, pf_allocation=pf_allocation, start_date=start, end_date=end

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\finquant\portfolio.py", line 1153, in build_portfolio
pf = _build_portfolio_from_api(**kwargs)

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\finquant\portfolio.py", line 935, in _build_portfolio_from_api
pf = _build_portfolio_from_df(data, pf_allocation)

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\finquant\portfolio.py", line 1035, in _build_portfolio_from_df
data = _get_stocks_data_columns(data, pf_allocation.Name.values, datacolumns)

File "C:\Users\Joe Shiafa Pierce\Anaconda3\lib\site-packages\finquant\portfolio.py", line 869, in _get_stocks_data_columns
raise ValueError("Could not find column labels in given dataframe.")

ValueError: Could not find column labels in given dataframe.`

Thanks for your help,

Benchmarking Performance

Hi @fmilthaler and @PietropaoloFrisoni

Is there a way to compare the effectiveness of this program to a benchmarked or baseline run?

What I mean to say is, how can we see or quantify how well FinQuant is performing against no optimisation / a random-search optimisation? Currently, I'm not sure if there's such a way to evaluate how "well" the program is working, if you understand me correctly.

Thanks and I've been having a blast learning from FinQuant!

example/Example-Build-Portfolio-from-web.py fails

Running the example without edit fails.

(.venv) vagrant@linux:~/dev/FinQuant/example$ python3 Example-Build-Portfolio-from-web.py 
/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py:260: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
Traceback (most recent call last):
  File "Example-Build-Portfolio-from-web.py", line 85, in <module>
    pf = build_portfolio(
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 1170, in build_portfolio
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 939, in _build_portfolio_from_api
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 1051, in _build_portfolio_from_df
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 267, in add_stock
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 282, in _update
  File "/home/vagrant/dev/FinQuant/.venv/lib/python3.8/site-packages/FinQuant-0.2.2-py3.8.egg/finquant/portfolio.py", line 202, in totalinvestment
ValueError: Total investment must be a float or integer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.