Skip to content

Commit

Permalink
Add mutual funds to sdk (#4610)
Browse files Browse the repository at this point in the history
* add mutual funds to sdk

* add docstring returns

* mypy

* remove avanza

* add historical chart

* split funcs

* revert po controller

* revert forecast sdk controller

* revert forecsat

* revert changes to forecast

* redo po

* remove .md files

* pylint

* why these md gone?

* pagesize to limit

* missed this one

* country default US

* default on load not on search

---------

Co-authored-by: James Maslek <jmaslek11@gmail.com>
  • Loading branch information
montezdesousa and jmaslek committed Apr 12, 2023
1 parent aa8bc16 commit b01dbf1
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 113 deletions.
6 changes: 4 additions & 2 deletions openbb_terminal/common/behavioural_analysis/reddit_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ def has_content(submission_) -> bool:


class RedditResponses:
tickers: dict = {}
authors: List[str] = []

def __init__(self):
self.tickers: dict = {}
self.authors: List[str] = []
pass

def gather(self, praw_api, responses) -> int:
count = 0
Expand Down
3 changes: 2 additions & 1 deletion openbb_terminal/core/sdk/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from .econometrics_sdk_model import EconometricsRoot
from .economy_sdk_model import EconomyRoot
from .etf_sdk_model import EtfRoot
from .fixedincome_sdk_model import FixedincomeRoot
from .forecast_sdk_model import ForecastRoot
from .fixedincome_sdk_model import FixedincomeRoot
from .forex_sdk_model import ForexRoot
from .funds_sdk_model import FundsRoot
from .futures_sdk_model import FuturesRoot
from .keys_sdk_model import KeysRoot
from .portfolio_sdk_model import PortfolioRoot
Expand Down
35 changes: 35 additions & 0 deletions openbb_terminal/core/sdk/models/funds_sdk_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ######### THIS FILE IS AUTO GENERATED - ANY CHANGES WILL BE VOID ######### #
# flake8: noqa
# pylint: disable=C0301,R0902,R0903
from openbb_terminal.core.sdk.sdk_helpers import Category
import openbb_terminal.core.sdk.sdk_init as lib


class FundsRoot(Category):
"""Mutual Funds Module
Attributes:
`carbon`: Search mstarpy for carbon metrics\n
`exclusion`: Search mstarpy exclusion policy in esgData\n
`historical`: Get historical fund, category, index price\n
`historical_chart`: Display historical fund, category, index price\n
`holdings`: Search mstarpy for holdings\n
`load`: Search mstarpy for matching funds\n
`search`: Search mstarpy for matching funds\n
`sector`: Get fund, category, index sector breakdown\n
`sector_chart`: Display fund, category, index sector breakdown\n
"""

_location_path = "funds"

def __init__(self):
super().__init__()
self.carbon = lib.funds_mstarpy_model.load_carbon_metrics
self.exclusion = lib.funds_mstarpy_model.load_exclusion_policy
self.historical = lib.funds_mstarpy_model.get_historical
self.historical_chart = lib.funds_mstarpy_view.display_historical
self.holdings = lib.funds_mstarpy_model.load_holdings
self.load = lib.funds_mstarpy_model.load_funds
self.search = lib.funds_mstarpy_model.search_funds
self.sector = lib.funds_mstarpy_model.get_sector
self.sector_chart = lib.funds_mstarpy_view.display_sector
6 changes: 6 additions & 0 deletions openbb_terminal/core/sdk/sdk_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@
sdk_helpers as forex_sdk_helpers,
)

# Funds
from openbb_terminal.mutual_funds import (
mstarpy_model as funds_mstarpy_model,
mstarpy_view as funds_mstarpy_view,
)

# Futures
from openbb_terminal.futures import (
yfinance_model as futures_yfinance_model,
Expand Down
7 changes: 7 additions & 0 deletions openbb_terminal/core/sdk/trail_map.csv
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ forex.oanda.positionbook,forex_oanda_model.positionbook_plot_data_request,forex_
forex.oanda.price,forex_oanda_model.fx_price_request,forex_oanda_view.get_fx_price
forex.oanda.summary,forex_oanda_model.account_summary_request,forex_oanda_view.get_account_summary
forex.quote,forex_sdk_helpers.quote,
funds.load,funds_mstarpy_model.load_funds,
funds.search,funds_mstarpy_model.search_funds,
funds.holdings,funds_mstarpy_model.load_holdings,
funds.exclusion,funds_mstarpy_model.load_exclusion_policy,
funds.carbon,funds_mstarpy_model.load_carbon_metrics,
funds.historical,funds_mstarpy_model.get_historical,funds_mstarpy_view.display_historical
funds.sector,funds_mstarpy_model.get_sector,funds_mstarpy_view.display_sector
futures.curve,futures_yfinance_model.get_curve_futures,futures_yfinance_view.display_curve
futures.historical,futures_sdk_model.get_historical,futures_yfinance_view.display_historical
futures.search,futures_yfinance_model.get_search_futures,
Expand Down
7 changes: 6 additions & 1 deletion openbb_terminal/mutual_funds/avanza_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@


@log_start_end(log=logger)
def get_data(isin: str):
def get_data(isin: str) -> dict:
"""Gets the data from Avanza
Parameters
----------
isin: str
ISIN of the fund
Returns
-------
dict
Fund data
"""
ava_fund = pd.read_csv(
os.path.join("openbb_terminal", "mutual_funds", "avanza_fund_ID.csv"),
Expand Down
138 changes: 130 additions & 8 deletions openbb_terminal/mutual_funds/mstarpy_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,100 @@
import pandas as pd

from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console

logger = logging.getLogger(__name__)


def get_historical(
loaded_funds: mstarpy.Funds,
start_date: str,
end_date: str,
comparison: str = "",
) -> pd.DataFrame:
"""Get historical fund, category, index price
Parameters
----------
loaded_funds: mstarpy.Funds
class mstarpy.Funds instantiated with selected funds
start_date: str
start date of the historical data
end_date: str
end date of the historical data
comparison: str
can be index, category, both
Returns
-------
pd.DataFrame
Dataframe containing historical data
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> f = openbb.funds.load("Vanguard", "US")
>>> openbb.funds.historical(f, "2020-01-01", "2020-12-31")
"""
try:
start_date_dt = pd.to_datetime(start_date)
end_date_dt = pd.to_datetime(end_date)
if not comparison:
data = loaded_funds.nav(start_date_dt, end_date_dt, frequency="daily")
df = pd.DataFrame(data).set_index("date")
df.index = pd.to_datetime(df.index)
else:
comparison_list = {
"index": [
"fund",
"index",
],
"category": ["fund", "category"],
"both": ["fund", "index", "category"],
}
data = loaded_funds.historicalData()
df_dict = {}
for x in comparison_list[comparison]:
df_dict[x] = pd.DataFrame(data["graphData"][x]).set_index("date")

df = pd.concat(
list(df_dict.values())[:], axis=1, keys=list(df_dict.keys())[:]
)
df.index = pd.to_datetime(df.index)
df = df.loc[(df.index >= start_date_dt) & (df.index <= end_date_dt)]
df = (df.pct_change().fillna(0) + 1).cumprod() * 100
df.columns = [col[0] for col in df.columns]
except Exception as e:
console.print(f"Error: {e}")
return pd.DataFrame()
return df


@log_start_end(log=logger)
def get_sector(loaded_funds: mstarpy.Funds, asset_type: str = "equity"):
"""Get fund, category, index sector breakdown
Parameters
----------
loaded_funds: mstarpy.funds
class mstarpy.Funds instantiated with selected funds
asset_type: str
can be equity or fixed income
Returns
-------
pd.DataFrame
Dataframe containing sector breakdown
"""
key = "EQUITY" if asset_type == "equity" else "FIXEDINCOME"

d = loaded_funds.sector()[key]

if d:
return pd.DataFrame(d)
return pd.DataFrame()


@log_start_end(log=logger)
def load_carbon_metrics(loaded_funds: mstarpy.Funds) -> pd.DataFrame:
"""Search mstarpy for carbon metrics
Expand All @@ -19,7 +109,14 @@ class mstarpy.Funds instantiated with selected funds
Returns
-------
pd.DataFrame of carbon metrics
pd.DataFrame
Dataframe containing carbon metrics
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> f = openbb.funds.load("Vanguard", "US")
>>> openbb.funds.carbon(f)
"""
carbonMetrics = loaded_funds.carbonMetrics()
return pd.Series(carbonMetrics, name="carbonMetrics").reset_index()
Expand All @@ -36,7 +133,14 @@ class mstarpy.Funds instantiated with selected funds
Returns
-------
pd.DataFrame of exclusion policy
pd.DataFrame
Dataframe containing exclusion policy
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> f = openbb.funds.load("Vanguard", "US")
>>> openbb.funds.exclusion(f)
"""
esgData = loaded_funds.esgData()
if "sustainabilityIntentionality" in esgData:
Expand All @@ -49,7 +153,7 @@ class mstarpy.Funds instantiated with selected funds
@log_start_end(log=logger)
def load_funds(
term: str = "",
country: str = "",
country: str = "US",
) -> mstarpy.Funds:
"""Search mstarpy for matching funds
Expand All @@ -62,7 +166,13 @@ def load_funds(
Returns
-------
mstarpy.Funds
mstarpy.Funds
class mstarpy.Funds instantiated with selected funds
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> f = openbb.funds.load("Vanguard", "US")
"""
return mstarpy.Funds(term, country)

Expand All @@ -83,7 +193,14 @@ class mstarpy.Funds instantiated with selected funds
Returns
-------
pd.DataFrame of funds holdings
pd.DataFrame
Dataframe containing holdings
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> f = openbb.funds.load("Vanguard", "US")
>>> openbb.funds.holdings(f)
"""
holdings = loaded_funds.holdings(holding_type)
if holdings.empty:
Expand All @@ -95,7 +212,7 @@ class mstarpy.Funds instantiated with selected funds
def search_funds(
term: str = "",
country: str = "",
pageSize=10,
limit=10,
) -> pd.DataFrame:
"""Search mstarpy for matching funds
Expand All @@ -107,18 +224,23 @@ def search_funds(
list of field who will be displayed
country : str
country where the funds is hosted
pageSize : int
limit : int
length of results to display
Returns
-------
pd.DataFrame
Dataframe containing matches
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> openbb.funds.search("Vanguard", "US")
"""
field = ["SecId", "TenforeId", "LegalName"]
try:
return pd.DataFrame(
mstarpy.search_funds(term, field, country=country, pageSize=pageSize)
mstarpy.search_funds(term, field, country=country, pageSize=limit)
)
except RuntimeError as e:
logger.exception(str(e))
Expand Down
Loading

0 comments on commit b01dbf1

Please sign in to comment.