Skip to content

Commit

Permalink
Added defer_update flag to add_stock function (#125)
Browse files Browse the repository at this point in the history
Added defer_update flag to add_stock function so bulk adding of stocks
can have update deferred until after all are added.

This closes #57.

---------

Co-authored-by: David Cheeseman <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 3, 2023
1 parent e9ec4c6 commit eb980c1
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 10 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Thank you to all the individuals who have contributed to this project!
- @drcsturm: bug fix for single stock portfolio
- @donin1129: bug fix for pandas index reference
- @aft90: helped to implement the Sortino Ratio
- David Cheeseman (@nuvious): added `defer_update` flag to `add_stock` function so bulk adding of stocks can have update deferred until after all are added (improved performance).

## Special Thanks

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<img src="https://img.shields.io/github/stars/fmilthaler/FinQuant.svg?style=social&label=Star" alt='pypi'>
</a>
<a href="https://pypi.org/project/FinQuant">
<img src="https://img.shields.io/badge/pypi-v0.5.0-brightgreen.svg?style=popout" alt='pypi'>
<img src="https://img.shields.io/badge/pypi-v0.6.0-brightgreen.svg?style=popout" alt='pypi'>
</a>
<a href="https://github.com/fmilthaler/FinQuant">
<img src="https://github.com/fmilthaler/finquant/actions/workflows/pytest.yml/badge.svg?branch=master" alt='GitHub Actions'>
Expand Down
2 changes: 1 addition & 1 deletion README.tex.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<img src="https://img.shields.io/github/stars/fmilthaler/FinQuant.svg?style=social&label=Star" alt='pypi'>
</a>
<a href="https://pypi.org/project/FinQuant">
<img src="https://img.shields.io/badge/pypi-v0.5.0-brightgreen.svg?style=popout" alt='pypi'>
<img src="https://img.shields.io/badge/pypi-v0.6.0-brightgreen.svg?style=popout" alt='pypi'>
</a>
<a href="https://github.com/fmilthaler/FinQuant">
<img src="https://github.com/fmilthaler/finquant/actions/workflows/pytest.yml/badge.svg?branch=master" alt='GitHub Actions'>
Expand Down
19 changes: 13 additions & 6 deletions finquant/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,24 +182,29 @@ def var_confidence_level(self, val):
# now that this changed, update VaR
self._update()

def add_stock(self, stock: Stock) -> None:
def add_stock(self, stock: Stock, defer_update=False) -> None:
"""Adds a stock of type ``Stock`` to the portfolio. Each time ``add_stock``
is called, the following instance variables are updated:
- ``portfolio``: ``pandas.DataFrame``, adds a column with information from ``stock``
- ``stocks``: ``dictionary``, adds an entry for ``stock``
- ``data``: ``pandas.DataFrame``, adds a column of stock prices from ``stock``
Also, the following instance variables are (re-)computed:
Also, if argument ``defer_update`` is ``True``,
the following instance variables are (re-)computed:
- ``expected_return``: Expected Return of the portfolio
- ``volatility``: Volatility of the portfolio
- ``downside_risk``: Downside Risk
- ``var``: Value at Risk of the portfolio
- ``sharpe``: Sharpe Ratio of the portfolio
- ``sortino``: Sortino Ratio of the portfolio
- ``skew``: Skewness of the portfolio's stocks
- ``kurtosis``: Kurtosis of the portfolio's stocks
:Input:
:stock: an object of ``Stock``
:defer_update: bool, if True _update() is not called after the stock is added.
"""
# adding stock to dictionary containing all stocks provided
self.stocks.update({stock.name: stock})
Expand All @@ -212,8 +217,9 @@ def add_stock(self, stock: Stock) -> None:
# also add stock data of stock to the dataframe
self._add_stock_data(stock)

# update quantities of portfolio
# self._update() # the update will be done at the end of building portfolio
if not defer_update:
# update quantities of portfolio
self._update()

def _add_stock_data(self, stock: Stock) -> None:
# insert given data into portfolio stocks dataframe:
Expand Down Expand Up @@ -1109,8 +1115,9 @@ def _build_portfolio_from_df(
name = pf_allocation.iloc[i].Name
# extract data column of said stock
stock_data = data.loc[:, [name]].copy(deep=True).squeeze()
# create Stock instance and add it to portfolio
pf.add_stock(Stock(pf_allocation.iloc[i], data=stock_data))
# create Stock instance and add it to portfolio,
# and defer updating portfolio attributes until all stocks are added
pf.add_stock(Stock(pf_allocation.iloc[i], data=stock_data), defer_update=True)
# update the portfolio
pf._update()
return pf
Expand Down
4 changes: 2 additions & 2 deletions version
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=0.5.0
release=0.5.0
version=0.6.0
release=0.6.0

0 comments on commit eb980c1

Please sign in to comment.