Giter VIP home page Giter VIP logo

robinhood-portfolio's Introduction

DEPRECATION NOTICE

This app is deprecated. I switched to different broker in 2017. I tried to maintain this repo, but it is becoming increasingly difficult mostly due to lack of interest. Many parts of this repo should be viable as long as the Robinhood API stays the same.

Note

This app is relying on pandas-datareader for stock historical prices. Over the last couple years multiple APIs were obsoleted by their providers (Google Finance, Morningstar) and as I am no longer a RH client I have no time to keep up with those changes. If you encounter the "Bad Gateway" error or similar it is likely that the current market data source is no longer valid. You are welcome to fork and try different sources of quotes - I will try to fix it, when/if I have time.

Current API is TIINGO for stock and market index.

Robinhood Portfolio

Python client to analyze the Robinhood portfolio. Based on unofficial robinhood-api and python libraries for financial analysis, such as:

Current Features

  • Creates a Flask web server with lightweight page Replaced with Jupyter notebook
  • Downloads orders and dividends from Robinhood account.
  • Downloads market data from google API and market index from open source. Supports incremental download for additional dates to reduce a number of requests to open APIs.
  • Calculates the total return of the portfolio, including dividend payouts and risk metric for the portfolio
  • Calculates the risk metric for individual securities and correlations between securities
  • Calculates Markowitz portfolios

LINK to Jupyter Notebook demo

Screenshots (OLD FLASK APP)

Image1 Image2 Image3 Image4 Image5

Non-Docker way

Create virtual environment, install dependencies:

git clone https://github.com/omdv/robinhood-portfolio && cd robinhood-portfolio
virtualenv robinhood && source robinhood/bin/activate && pip3 install -r requirements.txt

Or using conda (my preference):

conda create -n robinhood python=3.7
conda activate robinhood && pip install -r requirements.txt

To run:

jupyter notebook

Open main.ipynb, enter TIINGO api_key, Robinhood credentials, set demo_run variable to False to run with your data, execute all cells.

Docker way

docker run --name robinhood -d -p 8888:8888 omdv/robinhood-portfolio:notebook start.sh jupyter notebook --NotebookApp.token='' --notebook-dir='./work'

Once up and running connect to http://localhost:8888. Open main.ipynb, follow instructions.

Disclaimer

This tool uses the unofficial Robinhood API to access your account. This code and the corresponding tools are provided on "as is" basis and the user is responsible for the safety of his/her own account.


Related

robinhood-portfolio's People

Contributors

omdv 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

robinhood-portfolio's Issues

Issues updating data (running on docker)

Setup and initialization in docker run fine. Reasonably experienced with python code, but new to docker and flask. When I attempt to update Robinhood data with my login info (2FA disabled), I get this error:

json.decoder.JSONDecodeError
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Traceback (most recent call last)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2309, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functionsrule.endpoint
File "/robinhood-portfolio/app.py", line 104, in portfolio
bc.update_robinhood_data(user, password)
File "/robinhood-portfolio/backend/backend.py", line 121, in update_robinhood_data
rd.download_robinhood_data(user, password)
File "/robinhood-portfolio/backend/robinhood_data.py", line 188, in download_robinhood_data
self._login(user, password)
File "/robinhood-portfolio/backend/robinhood_data.py", line 25, in _login
self.client.login(username=user, password=password)
File "/robinhood-portfolio/backend/robinhood_api.py", line 73, in login
res = res.json()
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python3.5/json/init.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object

Any thoughts on how to fix this?

Missing Market data values shows up as NaN

In the original repo, historical prices are fetched from morning star and this api has been deprecated. After replacing this with 'tiingo' & providing it with a valid 'TIINGO_API_KEY', it is able to fetch the market data between the request start & end dates, but once this data is written to hdf datafile & read it gets turned into NaN.

This impacts most calculations especially Risk Analysis which relies heavily on the market data.

I'm unable to debug if this is due to the data format returned by tiingo or something inherent in the code base. Kindly suggest how to fix this issue.

cannot set using a list-like indexer with a different length than the value

Hi, I am using Jupyter notebook locally and got an error : ValueError: cannot set using a list-like indexer with a different length than the value. Detailed logs here. Thanks!


ValueError Traceback (most recent call last)
in
1 # main calculations section
----> 2 ptf = PortfolioModels('data')
3 summary = ptf.portfolio_summary()
4 stocks = ptf.stocks_risk()
5 df_corr, df_cov = ptf.stocks_correlation()

~/Documents/robinhood-portfolio/backend/portfolio_models.py in init(self, datafolder)
15 self.datafolder = datafolder
16 self._daily = None
---> 17 self._calculate_daily()
18 return None
19

~/Documents/robinhood-portfolio/backend/portfolio_models.py in _calculate_daily(self)
153
154 # merge orders with market
--> 155 pf = self._merge_market_with_dividends(df, pf)
156
157 # replace null stock prices using backfill to avoid issues with

~/Documents/robinhood-portfolio/backend/portfolio_models.py in _merge_market_with_dividends(self, df_div, mkt)
81 df['cum_dividends'].fillna(0, inplace=True)
82
---> 83 mkt.loc[_symbol] = df.values
84
85 return mkt

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/indexing.py in setitem(self, key, value)
668
669 iloc = self if self.name == "iloc" else self.obj.iloc
--> 670 iloc._setitem_with_indexer(indexer, value)
671
672 def _validate_key(self, key, axis: int):

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value)
1800 # actually do the set
1801 self.obj._consolidate_inplace()
-> 1802 self.obj._mgr = self.obj._mgr.setitem(indexer=indexer, value=value)
1803 self.obj._maybe_update_cacher(clear=True)
1804

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/internals/managers.py in setitem(self, indexer, value)
532
533 def setitem(self, indexer, value) -> "BlockManager":
--> 534 return self.apply("setitem", indexer=indexer, value=value)
535
536 def putmask(

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/internals/managers.py in apply(self, f, align_keys, **kwargs)
404 applied = b.apply(f, **kwargs)
405 else:
--> 406 applied = getattr(b, f)(**kwargs)
407 result_blocks = _extend_blocks(applied, result_blocks)
408

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/internals/blocks.py in setitem(self, indexer, value)
852
853 # length checking
--> 854 check_setitem_lengths(indexer, value, values)
855 exact_match = (
856 len(arr_value.shape)

~/Documents/robinhood-portfolio/robinhood/lib/python3.7/site-packages/pandas/core/indexers.py in check_setitem_lengths(indexer, value, values)
150 ):
151 raise ValueError(
--> 152 "cannot set using a list-like indexer "
153 "with a different length than the value"
154 )

ValueError: cannot set using a list-like indexer with a different length than the value

502 bad gateway?

After following instructions, going to localhost:8080 i get this error

builtins.Exception
Exception: Request Error!: 502 : Bad Gateway

Traceback (most recent call last)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/jonchui/code/GitHub/robinhood-portfolio/app.py", line 90, in portfolio
bc = BackendClass(DATAFILE, USERFILE)
File "/Users/jonchui/code/GitHub/robinhood-portfolio/backend/backend.py", line 35, in __init__
self._validate_user_dict()
File "/Users/jonchui/code/GitHub/robinhood-portfolio/backend/backend.py", line 78, in _validate_user_dict
self.update_market_data(fresh_start=True)
File "/Users/jonchui/code/GitHub/robinhood-portfolio/backend/backend.py", line 104, in update_market_data
self._df_ord.symbol.unique(), min_date, max_date)
File "/Users/jonchui/code/GitHub/robinhood-portfolio/backend/market_data.py", line 72, in download_save_market_data
end_date.date())
File "/Users/jonchui/code/GitHub/robinhood-portfolio/backend/market_data.py", line 42, in _get_historical_prices
pf = web.DataReader(tickers, 'morningstar', start_date, end_date)
File "/usr/local/lib/python3.6/site-packages/pandas_datareader/data.py", line 391, in DataReader
session=session, interval="d").read()
File "/usr/local/lib/python3.6/site-packages/pandas_datareader/mstar/daily.py", line 219, in read
df = self._dl_mult_symbols(symbols=symbols)
File "/usr/local/lib/python3.6/site-packages/pandas_datareader/mstar/daily.py", line 130, in _dl_mult_symbols
resp.status_code, resp.reason))
Exception: Request Error!: 502 : Bad Gateway

any ideas?

What?

Ok so I open that main file, and then what? How do I get my Robinhood api_key?? That notebook literally has no instructions. How does someone use this?

Google API change?

Getting error pandas_datareader._utils.RemoteDataError: No data fetched using 'GoogleDailyReader'

Portfolio on Raspberry pi

Hi,
I'm the guy who was taking help from you on the robinhood subreddit post and I'm currently trying to get it to run in docker on the rpi but while it creates the container, it never actually runs it; it just says exited. If I take out -d from the main command to get it to run not in the background, it gives me this error: "standard_init_linux.go:178: exec user process caused "exec format error"".

I did some research and I think this may be because the docker image is compiled for an x86 platform and the raspberry pi runs on ARM. Would this be fixed by recompiling the docker image?

Thanks for the help

Exception: Request Error!: 404 : Not Found (/mstar/daily.py)

It appears the morningstar endpoint for collecting data is no longer available...

Exception: Request Error!: 404 : Not Found

Traceback (most recent call last)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1997, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functionsrule.endpoint
File "/home/robinhood/robinhood-portfolio/app.py", line 90, in portfolio
bc = BackendClass(DATAFILE, USERFILE)
File "/home/robinhood/robinhood-portfolio/backend/backend.py", line 35, in init
self._validate_user_dict()
File "/home/robinhood/robinhood-portfolio/backend/backend.py", line 78, in _validate_user_dict
self.update_market_data(fresh_start=True)
File "/home/robinhood/robinhood-portfolio/backend/backend.py", line 104, in update_market_data
self._df_ord.symbol.unique(), min_date, max_date)
File "/home/robinhood/robinhood-portfolio/backend/market_data.py", line 71, in download_save_market_data
end_date.date())
File "/home/robinhood/robinhood-portfolio/backend/market_data.py", line 41, in _get_historical_prices
pf = web.DataReader(tickers, 'morningstar', start_date, end_date)
File "/usr/lib/python3.5/site-packages/pandas_datareader/data.py", line 391, in DataReader
session=session, interval="d").read()
File "/usr/lib/python3.5/site-packages/pandas_datareader/mstar/daily.py", line 219, in read
df = self._dl_mult_symbols(symbols=symbols)
File "/usr/lib/python3.5/site-packages/pandas_datareader/mstar/daily.py", line 130, in _dl_mult_symbols
resp.status_code, resp.reason))
Exception: Request Error!: 404 : Not Found

Trying to run in a conda env with most updated pandas-0.23.3

$ python3 app.py
/anaconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
  return f(*args, **kwds)
/anaconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
  return f(*args, **kwds)
Traceback (most recent call last):
  File "app.py", line 8, in <module>
    from backend.backend import BackendClass
  File "/Users/tw/Github/robinhood-portfolio/backend/backend.py", line 5, in <module>
    from backend.robinhood_data import RobinhoodData
  File "/Users/tw/Github/robinhood-portfolio/backend/robinhood_data.py", line 3, in <module>
    from pandas.core.tools.datetimes import normalize_date
ImportError: cannot import name 'normalize_date'

Docker run fails. No module named 'Robinhood'

When I use the docker run command, I get this failure:

docker run -e TIINGO_API_KEY=xxx -p 8080:8080 --name robinhood omdv/robinhood-portfolio:ubuntu

Status: Downloaded newer image for omdv/robinhood-portfolio:ubuntu
Traceback (most recent call last):
  File "app.py", line 8, in <module>
    from backend.backend import BackendClass
  File "/robinhood-portfolio/backend/backend.py", line 5, in <module>
    from backend.robinhood_data import RobinhoodData
  File "/robinhood-portfolio/backend/robinhood_data.py", line 4, in <module>
    from Robinhood import Robinhood
ImportError: No module named 'Robinhood'

Running on Mac OSX 10.13.6 (High Sierra)
Docker version 19.03.2, build 6a30dfc

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.