diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b74580b17cc4..c62ecb70c32d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -681,7 +681,7 @@ With: transactions = Portfolio.read_orderbook("../../portfolio/holdings/example.csv") P = Portfolio(transactions) P.generate_portfolio_data() - P.load_benchmark() + P.set_benchmark() # SDK endpoint access openbb.portfolio.gaintopain(P) @@ -695,7 +695,7 @@ With: ```python - def get_gaintopain_ratio(portfolio: PortfolioModel) -> pd.DataFrame: + def get_gaintopain_ratio(portfolio: PortfolioEngine) -> pd.DataFrame: """...""" diff --git a/openbb_terminal/miscellaneous/library/trail_map.csv b/openbb_terminal/miscellaneous/library/trail_map.csv index 2929418a5aa2..c8d61a1fcef9 100644 --- a/openbb_terminal/miscellaneous/library/trail_map.csv +++ b/openbb_terminal/miscellaneous/library/trail_map.csv @@ -295,36 +295,42 @@ forex.oanda.listorders,openbb_terminal.forex.oanda.oanda_model.order_history_req forex.oanda.orderbook,openbb_terminal.forex.oanda.oanda_model.orderbook_plot_data_request,openbb_terminal.forex.oanda.oanda_view.get_order_book forex.oanda.pending,openbb_terminal.forex.oanda.oanda_model.pending_orders_request,openbb_terminal.forex.oanda.oanda_view.get_pending_orders forex.oanda.positionbook,openbb_terminal.forex.oanda.oanda_model.positionbook_plot_data_request,openbb_terminal.forex.oanda.oanda_view.get_position_book +portfolio.load,openbb_terminal.portfolio.portfolio_model.generate_portfolio, +portfolio.show,openbb_terminal.portfolio.portfolio_model.get_transactions, +portfolio.bench,openbb_terminal.portfolio.portfolio_model.set_benchmark, portfolio.holdv,openbb_terminal.portfolio.portfolio_model.get_holdings_value,openbb_terminal.portfolio.portfolio_view.display_holdings_value portfolio.holdp,openbb_terminal.portfolio.portfolio_model.get_holdings_percentage,openbb_terminal.portfolio.portfolio_view.display_holdings_percentage -portfolio.yret,openbb_terminal.portfolio.portfolio_model.get_yearly_returns,openbb_terminal.portfolio.portfolio_view.display_yearly_returns portfolio.mret,openbb_terminal.portfolio.portfolio_model.get_monthly_returns,openbb_terminal.portfolio.portfolio_view.display_monthly_returns +portfolio.yret,openbb_terminal.portfolio.portfolio_model.get_yearly_returns,openbb_terminal.portfolio.portfolio_view.display_yearly_returns portfolio.dret,openbb_terminal.portfolio.portfolio_model.get_daily_returns,openbb_terminal.portfolio.portfolio_view.display_daily_returns -portfolio.max_drawdown_ratio,openbb_terminal.portfolio.portfolio_model.get_maximum_drawdown,openbb_terminal.portfolio.portfolio_view.display_maximum_drawdown_ratio portfolio.distr,openbb_terminal.portfolio.portfolio_model.get_distribution_returns,openbb_terminal.portfolio.portfolio_view.display_distribution_returns portfolio.maxdd,openbb_terminal.portfolio.portfolio_model.get_maximum_drawdown,openbb_terminal.portfolio.portfolio_view.display_maximum_drawdown portfolio.rvol,openbb_terminal.portfolio.portfolio_model.get_rolling_volatility,openbb_terminal.portfolio.portfolio_view.display_rolling_volatility portfolio.rsharpe,openbb_terminal.portfolio.portfolio_model.get_rolling_sharpe,openbb_terminal.portfolio.portfolio_view.display_rolling_sharpe -portfolio.rsortino,openbb_terminal.portfolio.portfolio_model.get_rolling_sortino,openbb_terminal.portfolio.portfolio_view.display_rolling_sortino +portfolio.rsort,openbb_terminal.portfolio.portfolio_model.get_rolling_sortino,openbb_terminal.portfolio.portfolio_view.display_rolling_sortino portfolio.rbeta,openbb_terminal.portfolio.portfolio_model.get_rolling_beta,openbb_terminal.portfolio.portfolio_view.display_rolling_beta portfolio.summary,openbb_terminal.portfolio.portfolio_model.get_summary, -portfolio.skew,openbb_terminal.portfolio.portfolio_model.get_skewness, -portfolio.kurtosis,openbb_terminal.portfolio.portfolio_model.get_kurtosis, -portfolio.volatility,openbb_terminal.portfolio.portfolio_model.get_volatility, -portfolio.sharpe,openbb_terminal.portfolio.portfolio_model.get_sharpe_ratio, -portfolio.sortino,openbb_terminal.portfolio.portfolio_model.get_sortino_ratio, -portfolio.maxdrawdown,openbb_terminal.portfolio.portfolio_model.get_maximum_drawdown_ratio, -portfolio.rsquare,openbb_terminal.portfolio.portfolio_model.get_r2_score, -portfolio.gaintopain,openbb_terminal.portfolio.portfolio_model.get_gaintopain_ratio, -portfolio.trackerr,openbb_terminal.portfolio.portfolio_model.get_tracking_error, -portfolio.information,openbb_terminal.portfolio.portfolio_model.get_information_ratio, -portfolio.tail,openbb_terminal.portfolio.portfolio_model.get_tail_ratio, -portfolio.commonsense,openbb_terminal.portfolio.portfolio_model.get_common_sense_ratio, -portfolio.jensens,openbb_terminal.portfolio.portfolio_model.get_jensens_alpha, -portfolio.calmar,openbb_terminal.portfolio.portfolio_model.get_calmar_ratio, -portfolio.kelly,openbb_terminal.portfolio.portfolio_model.get_kelly_criterion, -portfolio.payoff,openbb_terminal.portfolio.portfolio_model.get_payoff_ratio, -portfolio.profitfactor,openbb_terminal.portfolio.portfolio_model.get_profit_factor, +portfolio.alloc.assets,openbb_terminal.portfolio.portfolio_model.get_assets_allocation, +portfolio.alloc.sectors,openbb_terminal.portfolio.portfolio_model.get_sectors_allocation, +portfolio.alloc.countries,openbb_terminal.portfolio.portfolio_model.get_countries_allocation, +portfolio.alloc.regions,openbb_terminal.portfolio.portfolio_model.get_regions_allocation, +portfolio.metric.volatility,openbb_terminal.portfolio.portfolio_model.get_volatility, +portfolio.metric.sharpe,openbb_terminal.portfolio.portfolio_model.get_sharpe_ratio, +portfolio.metric.sortino,openbb_terminal.portfolio.portfolio_model.get_sortino_ratio, +portfolio.metric.maxdrawdown,openbb_terminal.portfolio.portfolio_model.get_maximum_drawdown_ratio, +portfolio.metric.rsquare,openbb_terminal.portfolio.portfolio_model.get_r2_score, +portfolio.metric.skew,openbb_terminal.portfolio.portfolio_model.get_skewness, +portfolio.metric.kurtosis,openbb_terminal.portfolio.portfolio_model.get_kurtosis, +portfolio.metric.gaintopain,openbb_terminal.portfolio.portfolio_model.get_gaintopain_ratio, +portfolio.metric.trackerr,openbb_terminal.portfolio.portfolio_model.get_tracking_error, +portfolio.metric.information,openbb_terminal.portfolio.portfolio_model.get_information_ratio, +portfolio.metric.tail,openbb_terminal.portfolio.portfolio_model.get_tail_ratio, +portfolio.metric.commonsense,openbb_terminal.portfolio.portfolio_model.get_common_sense_ratio, +portfolio.metric.jensens,openbb_terminal.portfolio.portfolio_model.get_jensens_alpha, +portfolio.metric.calmar,openbb_terminal.portfolio.portfolio_model.get_calmar_ratio, +portfolio.metric.kelly,openbb_terminal.portfolio.portfolio_model.get_kelly_criterion, +portfolio.metric.payoff,openbb_terminal.portfolio.portfolio_model.get_payoff_ratio, +portfolio.metric.profitfactor,openbb_terminal.portfolio.portfolio_model.get_profit_factor, portfolio.perf,openbb_terminal.portfolio.portfolio_model.get_performance_vs_benchmark, portfolio.var,openbb_terminal.portfolio.portfolio_model.get_var, portfolio.es,openbb_terminal.portfolio.portfolio_model.get_es, diff --git a/openbb_terminal/portfolio/allocation_model.py b/openbb_terminal/portfolio/allocation_model.py index c4f2616e7c9e..15e0a000d85f 100644 --- a/openbb_terminal/portfolio/allocation_model.py +++ b/openbb_terminal/portfolio/allocation_model.py @@ -1,5 +1,5 @@ import logging -from typing import Dict +from typing import Dict, Tuple import pandas as pd import requests @@ -12,22 +12,61 @@ @log_start_end(log=logger) -def get_assets_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): - """Obtain the assets allocation of the benchmark and portfolio [Source: Yahoo Finance] +def get_allocation( + category: str, benchmark_info: Dict, portfolio_trades: pd.DataFrame +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """Get category allocation for benchmark and portfolio Parameters ---------- + category: str + Chosen category: Asset, Sector, Country or Region benchmark_info: Dict - Dictionary containing Yahoo Finance information. + Dictionary containing Yahoo Finance information portfolio_trades: pd.DataFrame - Object containing trades made within the portfolio. + Object containing trades made within the portfolio Returns ------- - benchmark_assets_allocation: dict - Dictionary with the top 10 of the benchmark's asset allocations. - portfolio_assets_allocation: dict - Dictionary with the portfolio's asset allocations + pd.DataFrame + DataFrame with the top 10 of the benchmark's asset allocations + pd.DataFrame + DataFrame with the portfolio's asset allocations + """ + + if category == "Asset": + return get_assets_allocation(benchmark_info, portfolio_trades) + if category == "Sector": + return get_sectors_allocation(benchmark_info, portfolio_trades) + if category == "Country": + return get_countries_allocation(benchmark_info, portfolio_trades) + if category == "Region": + return get_regions_allocation(benchmark_info, portfolio_trades) + console.print( + "Category not available. Choose from: Asset, Sector, Country or Region." + ) + return pd.DataFrame(), pd.DataFrame() + + +@log_start_end(log=logger) +def get_assets_allocation( + benchmark_info: Dict, portfolio_trades: pd.DataFrame +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """Get assets allocation for benchmark and portfolio [Source: Yahoo Finance] + + Parameters + ---------- + benchmark_info: Dict + Dictionary containing Yahoo Finance information + portfolio_trades: pd.DataFrame + Object containing trades made within the portfolio + + Returns + ------- + pd.DataFrame + DataFrame with the top 10 of the benchmark's asset allocations + pd.DataFrame + DataFrame with the portfolio's asset allocations """ benchmark_assets_allocation = pd.DataFrame(benchmark_info["holdings"]) benchmark_assets_allocation.rename( @@ -51,26 +90,26 @@ def get_assets_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): @log_start_end(log=logger) -def get_sector_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): - """Obtain the sector allocation of the benchmark and portfolio [Source: Yahoo Finance] +def get_sectors_allocation( + benchmark_info: Dict, portfolio_trades: pd.DataFrame +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """Get sector allocation for benchmark and portfolio [Source: Yahoo Finance] Parameters ---------- benchmark_info: Dict - Dictionary containing Yahoo Finance information. + Dictionary containing Yahoo Finance information portfolio_trades: pd.DataFrame - Object containing trades made within the portfolio. + Object containing trades made within the portfolio Returns ------- - regional_allocation: dict - Dictionary with regional allocations. - country_allocation: dict - Dictionary with country allocations + pd.DataFrame + DataFrame with regional allocations. + pd.DataFrame + DataFrame with country allocations """ - p_bar = tqdm(range(3), desc="Loading sector data") - benchmark_sectors_allocation = ( pd.DataFrame.from_dict( data={ @@ -91,6 +130,9 @@ def get_sector_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): ] benchmark_sectors_allocation.index = prettified + benchmark_sectors_allocation = pd.DataFrame(benchmark_sectors_allocation) + benchmark_sectors_allocation.reset_index(inplace=True) + benchmark_sectors_allocation.columns = ["Sector", "Benchmark"] # Define portfolio sector allocation # Aggregate sector value for stocks and crypto @@ -99,11 +141,9 @@ def get_sector_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): .groupby(by="Sector") .agg({"Portfolio Value": "sum"}) ) - p_bar.n += 1 - p_bar.refresh() # Aggregate sector value for ETFs - # Start by getting value by isin/ticker + # Start by getting value by isin/symbol etf_ticker_value = ( portfolio_trades[portfolio_trades["Type"].isin(["ETF"])] .groupby(by="Ticker") @@ -111,48 +151,45 @@ def get_sector_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): ) etf_global_sector_alloc = pd.DataFrame() - # Loop through each etf and multiply sector weights by current value - for item in etf_ticker_value.index.values: - - # TODO: This can be improved by caching this info similar to what is done in stocks - etf_info = yf.Ticker(item).info - - try: - etf_sector_weight = pd.DataFrame.from_dict( - data={ - sector_name: allocation - for sector in etf_info["sectorWeightings"] - for sector_name, allocation in sector.items() - }, - orient="index", - columns=["Portfolio Value"], + if not etf_ticker_value.empty: + # Loop through each etf and multiply sector weights by current value + for item in tqdm(etf_ticker_value.index.values, desc="Loading ETF data"): + + # TODO: This can be improved by caching this info similar to what is done in stocks + etf_info = yf.Ticker(item).info + + try: + etf_sector_weight = pd.DataFrame.from_dict( + data={ + sector_name: allocation + for sector in etf_info["sectorWeightings"] + for sector_name, allocation in sector.items() + }, + orient="index", + columns=["Portfolio Value"], + ) + + except Exception: + # If ETF has no sectors like VIX for example or it was not found, add to Other + etf_sector_weight = pd.DataFrame.from_dict( + data={"Other": 1}, orient="index", columns=["Portfolio Value"] + ) + + etf_ticker_sector_alloc = ( + etf_sector_weight * etf_ticker_value["Portfolio Value"][item] ) - except Exception: - # If ETF has no sectors like VIX for example or it was not found, add to Other - etf_sector_weight = pd.DataFrame.from_dict( - data={"Other": 1}, orient="index", columns=["Portfolio Value"] + # Aggregate etf sector allocation by value + etf_global_sector_alloc = pd.concat( + [etf_global_sector_alloc, etf_ticker_sector_alloc], axis=1 ) + etf_global_sector_alloc.fillna(0, inplace=True) + etf_global_sector_alloc = etf_global_sector_alloc.sum(axis=1) - etf_value = etf_ticker_value["Portfolio Value"][item] - - etf_ticker_sector_alloc = etf_sector_weight * etf_value - - # Aggregate etf sector allocation by value - etf_global_sector_alloc = pd.concat( - [etf_global_sector_alloc, etf_ticker_sector_alloc], axis=1 + etf_global_sector_alloc = pd.DataFrame( + etf_global_sector_alloc, columns=["Portfolio Value"] ) - - etf_global_sector_alloc.fillna(0, inplace=True) - - etf_global_sector_alloc = etf_global_sector_alloc.sum(axis=1) - - p_bar.n += 1 - p_bar.refresh() - - etf_global_sector_alloc = pd.DataFrame( - etf_global_sector_alloc, columns=["Portfolio Value"] - ) + console.print("\n") # Rename columns to match stock and crypto classification etf_global_sector_alloc.index.name = "Sector" @@ -175,51 +212,101 @@ def get_sector_allocation(benchmark_info: Dict, portfolio_trades: pd.DataFrame): portfolio_sectors_allocation, columns=["Portfolio Value"] ) - portfolio_sectors_allocation = ( - portfolio_sectors_allocation.div(portfolio_trades["Portfolio Value"].sum()) - .squeeze(axis=1) - .sort_values(ascending=False) - ) + portfolio_sectors_allocation = portfolio_sectors_allocation.div( + portfolio_trades["Portfolio Value"].sum() + ).sort_values(by="Portfolio Value", ascending=False) portfolio_sectors_allocation.fillna(0, inplace=True) - - p_bar.n += 1 - p_bar.refresh() - p_bar.disable = True - console.print("\n") + portfolio_sectors_allocation = pd.DataFrame(portfolio_sectors_allocation) + portfolio_sectors_allocation.reset_index(inplace=True) + portfolio_sectors_allocation.columns = ["Sector", "Portfolio"] return benchmark_sectors_allocation, portfolio_sectors_allocation @log_start_end(log=logger) -def get_region_country_allocation( - ticker: str, region_test: list = None, country_test: list = None -): +def get_countries_allocation( + benchmark_info: Dict, portfolio_trades: pd.DataFrame +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """Get countries allocation for benchmark and portfolio [Source: Yahoo Finance] + + Parameters + ---------- + benchmark_info: Dict + Dictionary containing Yahoo Finance information + portfolio_trades: pd.DataFrame + Object containing trades made within the portfolio + + Returns + ------- + pd.DataFrame + DataFrame with regional allocations. + pd.DataFrame + DataFrame with country allocations + """ + + benchmark_allocation = get_symbol_allocation( + symbol=benchmark_info["symbol"], category="Country", col_name="Benchmark" + ) + + portfolio_allocation = get_portfolio_allocation( + category="Country", portfolio_trades=portfolio_trades + ) + + return benchmark_allocation, portfolio_allocation + + +@log_start_end(log=logger) +def get_regions_allocation( + benchmark_info: Dict, portfolio_trades: pd.DataFrame +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """Get regions allocation for benchmark and portfolio [Source: Yahoo Finance] - """Obtain the region and country allocation for ETF ticker. [Source: Fidelity.com] + Parameters + ---------- + benchmark_info: Dict + Dictionary containing Yahoo Finance information + portfolio_trades: pd.DataFrame + Object containing trades made within the portfolio + + Returns + ------- + pd.DataFrame + DataFrame with regional allocations. + pd.DataFrame + DataFrame with country allocations + """ + benchmark_allocation = get_symbol_allocation( + symbol=benchmark_info["symbol"], category="Region", col_name="Benchmark" + ) + + portfolio_allocation = get_portfolio_allocation( + category="Region", portfolio_trades=portfolio_trades + ) + + return benchmark_allocation, portfolio_allocation + + +def get_symbol_allocation( + symbol: str, category: str, col_name: str = "Weight" +) -> pd.DataFrame: + """Get benchmark allocation [Source: Fidelity] Parameters ---------- - benchmark_ticker: str - The ticker, e.g. "SPY" - region_test: list - This includes a list of region names that should be used to discover - which list on the Fidelity page is the correct one - country_test: list - This includes a list of country names that should be used to discover - which list on the Fidelity page is the correct one + symbol: str + ETF symbol to get allocation + category: str + Chosen category: Country or Region Returns ------- - region_allocation: dict - Dictionary with regional allocations. - country_allocation: dict + pd.DataFrame Dictionary with country allocations """ - # Initialize variables - if not region_test: - region_test = [ + if category == "Region": + category_list = [ "North America", "Europe", "Asia", @@ -227,8 +314,9 @@ def get_region_country_allocation( "Africa", "Middle East", ] - if not country_test: - country_test = [ + + if category == "Country": + category_list = [ "United States", "United Kingdom", "Japan", @@ -236,189 +324,129 @@ def get_region_country_allocation( "China", ] - region_list = 0 - country_list = 0 + item_list = 0 # Collect data from Fidelity about the portfolio composition of the benchmark - URL = f"https://screener.fidelity.com/ftgw/etf/goto/snapshot/portfolioComposition.jhtml?symbols={ticker}" + URL = f"https://screener.fidelity.com/ftgw/etf/goto/snapshot/portfolioComposition.jhtml?symbols={symbol}" html = requests.get(URL).content df_list = pd.read_html(html) # Find the ones that contain regions and countries for index, item in enumerate(df_list): - for region in region_test: - if region in item.values: - region_list = index - break - for country in country_test: - if country in item.values: - country_list = index + for category_item in category_list: + if category_item in item.values: + item_list = index break - if region_list: - region_allocation = { + if item_list: + allocation = { row[1]: float(row[2].strip("%")) / 100 - for _, row in df_list[region_list].dropna(axis="columns").iterrows() + for _, row in df_list[item_list].dropna(axis="columns").iterrows() } - region_allocation = pd.DataFrame.from_dict( - region_allocation, orient="index" - ).squeeze() + allocation_df = pd.DataFrame.from_dict(allocation, orient="index") + allocation_df.reset_index(inplace=True) + allocation_df.columns = [category, col_name] else: - region_allocation = pd.DataFrame() + allocation_df = pd.DataFrame(columns=[category, col_name]) - if country_list: - country_allocation = { - row[1]: float(row[2].strip("%")) / 100 - for _, row in df_list[country_list].dropna(axis="columns").iterrows() - } - country_allocation = pd.DataFrame.from_dict( - country_allocation, orient="index" - ).squeeze() - else: - country_allocation = pd.DataFrame() - - return region_allocation, country_allocation + return allocation_df @log_start_end(log=logger) -def get_portfolio_region_country_allocation(portfolio_trades: pd.DataFrame): - """Obtain the regional and country allocation of the portfolio. +def get_portfolio_allocation( + category: str, portfolio_trades: pd.DataFrame +) -> pd.DataFrame: + """Get portfolio allocation Parameters ---------- + category: str + Chosen category: Country or Region portfolio_trades: pd.DataFrame - Object containing trades made within the portfolio. + Object containing trades made within the portfolio Returns - ------ - portfolio_regional_allocation: pd.DataFrame - Dictionary with regional allocations. - portfolio_country_allocation: pd.DataFrame + ------- + pd.DataFrame Dictionary with country allocations """ - p_bar = tqdm(range(3), desc="Loading country/region data") - - # Define portfolio regional allocation - if not portfolio_trades["Region"].isnull().any(): - portfolio_region_allocation = ( + # Define portfolio allocation + if not portfolio_trades[category].isnull().any(): + allocation = ( portfolio_trades[portfolio_trades["Type"].isin(["STOCK", "CRYPTO"])] - .groupby(by="Region") + .groupby(by=category) .agg({"Portfolio Value": "sum"}) ) else: - portfolio_region_allocation = pd.DataFrame() - - # Define portfolio country allocation - if not portfolio_trades["Country"].isnull().any(): - portfolio_country_allocation = ( - portfolio_trades[portfolio_trades["Type"].isin(["STOCK", "CRYPTO"])] - .groupby(by="Country") - .agg({"Portfolio Value": "sum"}) - ) - else: - portfolio_country_allocation = pd.DataFrame() - - p_bar.n += 1 - p_bar.refresh() + allocation = pd.DataFrame() # Aggregate sector value for ETFs - # Start by getting value by ticker + # Start by getting value by symbol etf_ticker_value = ( portfolio_trades[portfolio_trades["Type"].isin(["ETF"])] .groupby(by="Ticker") .agg({"Portfolio Value": "sum"}) ) - etf_global_region_alloc = pd.DataFrame() - etf_global_country_alloc = pd.DataFrame() + etf_global_alloc = pd.DataFrame(columns=[category, "Portfolio Value"]) - # Loop through each etf and multiply sector weights by current value - for item in etf_ticker_value.index.values: + if not etf_ticker_value.empty: - etf_region_weight, etf_country_weight = get_region_country_allocation(item) + no_info = [] + # Loop through each etf and multiply sector weights by current value + for item in tqdm(etf_ticker_value.index.values, desc="Loading ETF data"): - if etf_region_weight.empty: - # If ETF has no sectors like VIX for example or it was not found, add to Other - etf_region_weight = pd.DataFrame.from_dict( - data={"Other": 1}, orient="index", columns=["Portfolio Value"] + etf_weight = get_symbol_allocation( + symbol=item, category=category, col_name="Portfolio Value" ) - if etf_country_weight.empty: - etf_country_weight = pd.DataFrame.from_dict( - data={"Other": 1}, orient="index", columns=["Portfolio Value"] + if etf_weight.empty: + etf_weight = pd.DataFrame.from_dict( + data={"Other": 1}, orient="index", columns=["Portfolio Value"] + ) + etf_weight.index.name = category + no_info.append(item) + else: + etf_weight.set_index(category, inplace=True) + + # Aggregate etf allocation by value + etf_ticker_alloc = etf_weight + etf_ticker_alloc["Portfolio Value"] = ( + etf_ticker_alloc["Portfolio Value"] + * etf_ticker_value["Portfolio Value"][item] ) + etf_global_alloc = pd.concat([etf_global_alloc, etf_ticker_alloc], axis=1) + etf_global_alloc.fillna(0, inplace=True) + etf_global_alloc = etf_global_alloc.sum(axis=1) - etf_value = etf_ticker_value["Portfolio Value"][item] + etf_global_alloc = pd.DataFrame(etf_global_alloc, columns=["Portfolio Value"]) - # Aggregate etf region allocation by value - etf_ticker_region_alloc = etf_region_weight * etf_value - etf_global_region_alloc = pd.concat( - [etf_global_region_alloc, etf_ticker_region_alloc], axis=1 - ) - etf_global_region_alloc.fillna(0, inplace=True) - etf_global_region_alloc = etf_global_region_alloc.sum(axis=1) - - # Aggregate etf country allocation by value - etf_ticker_country_alloc = etf_country_weight * etf_value - etf_global_country_alloc = pd.concat( - [etf_global_country_alloc, etf_ticker_country_alloc], axis=1 - ) - etf_global_country_alloc.fillna(0, inplace=True) - etf_global_country_alloc = etf_global_country_alloc.sum(axis=1) - - p_bar.n += 1 - p_bar.refresh() - - etf_global_region_alloc = pd.DataFrame( - etf_global_region_alloc, columns=["Portfolio Value"] - ) - etf_global_country_alloc = pd.DataFrame( - etf_global_country_alloc, columns=["Portfolio Value"] - ) + console.print("") - # Aggregate region allocation for stocks and crypto with ETFs - portfolio_region_allocation = pd.merge( - portfolio_region_allocation, - etf_global_region_alloc, - how="outer", - left_index=True, - right_index=True, - ).sum(axis=1) + if no_info: + console.print( + f"[red]No data found for: {', '.join(no_info)}. Included in 'Other'.[/red]\n" + ) - # Aggregate country allocation for stocks and crypto with ETFs - portfolio_country_allocation = pd.merge( - portfolio_country_allocation, - etf_global_country_alloc, + # Aggregate allocation for stocks and crypto with ETFs + allocation = pd.merge( + allocation, + etf_global_alloc, how="outer", left_index=True, right_index=True, ).sum(axis=1) - portfolio_region_allocation = pd.DataFrame( - portfolio_region_allocation, columns=["Portfolio Value"] - ) - portfolio_country_allocation = pd.DataFrame( - portfolio_country_allocation, columns=["Portfolio Value"] - ) + allocation = pd.DataFrame(allocation, columns=["Portfolio Value"]) - portfolio_region_allocation = ( - portfolio_region_allocation.div(portfolio_trades["Portfolio Value"].sum()) - .squeeze(axis=1) - .sort_values(ascending=False) + allocation = allocation.div(portfolio_trades["Portfolio Value"].sum()).sort_values( + by="Portfolio Value", ascending=False ) - portfolio_country_allocation = ( - portfolio_country_allocation.div(portfolio_trades["Portfolio Value"].sum()) - .squeeze(axis=1) - .sort_values(ascending=False) - ) + allocation.fillna(0, inplace=True) - portfolio_region_allocation.fillna(0, inplace=True) - portfolio_country_allocation.fillna(0, inplace=True) + allocation.reset_index(inplace=True) - p_bar.n += 1 - p_bar.refresh() - p_bar.disable = True - console.print("\n") + allocation.columns = [category, "Portfolio"] - return portfolio_region_allocation, portfolio_country_allocation + return allocation diff --git a/openbb_terminal/portfolio/portfolio_controller.py b/openbb_terminal/portfolio/portfolio_controller.py index d409b5453a9b..f16f7013a46e 100644 --- a/openbb_terminal/portfolio/portfolio_controller.py +++ b/openbb_terminal/portfolio/portfolio_controller.py @@ -22,7 +22,7 @@ from openbb_terminal.menu import session from openbb_terminal.core.config.paths import MISCELLANEOUS_DIRECTORY from openbb_terminal.parent_classes import BaseController -from openbb_terminal.portfolio import portfolio_model +from openbb_terminal.portfolio.portfolio_model import generate_portfolio from openbb_terminal.portfolio import statics from openbb_terminal.portfolio import portfolio_view from openbb_terminal.portfolio import portfolio_helper @@ -139,9 +139,7 @@ def __init__(self, queue: List[str] = None): self.original_benchmark_name = "" self.risk_free_rate = 0 self.portlist: List[str] = os.listdir(self.DEFAULT_HOLDINGS_PATH) - self.portfolio: portfolio_model.PortfolioModel = ( - portfolio_model.PortfolioModel() - ) + self.portfolio = None if session and obbff.USE_PROMPT_TOOLKIT: self.update_choices() @@ -442,33 +440,26 @@ def call_load(self, other_args: List[str]): else: file_location = ns_parser.file # type: ignore - transactions = portfolio_model.PortfolioModel.read_transactions( - str(file_location) + self.portfolio = generate_portfolio( + transactions_file_path=str(file_location), + benchmark_symbol="SPY", + risk_free_rate=ns_parser.risk_free_rate / 100, ) - self.portfolio = portfolio_model.PortfolioModel(transactions) - self.benchmark_name = "" if ns_parser.name: self.portfolio_name = ns_parser.name else: self.portfolio_name = ns_parser.file - - # Generate holdings from trades - self.portfolio.generate_portfolio_data() - - # Add in the Risk-free rate - self.portfolio.set_risk_free_rate(ns_parser.risk_free_rate / 100) - self.risk_free_rate = ns_parser.risk_free_rate / 100 - - # Load benchmark - self.call_bench(["-b", "SPDR S&P 500 ETF Trust (SPY)"]) - console.print( f"\n[bold][param]Portfolio:[/param][/bold] {self.portfolio_name}" ) + + self.benchmark_name = "SPDR S&P 500 ETF Trust (SPY)" console.print( f"[bold][param]Risk Free Rate:[/param][/bold] {self.risk_free_rate:.2%}" ) + + self.risk_free_rate = ns_parser.risk_free_rate / 100 console.print( f"[bold][param]Benchmark:[/param][/bold] {self.benchmark_name}\n" ) @@ -538,19 +529,10 @@ def call_bench(self, other_args: List[str]): else: benchmark_ticker = chosen_benchmark - self.portfolio.load_benchmark(benchmark_ticker, ns_parser.full_shares) + self.portfolio.set_benchmark(benchmark_ticker, ns_parser.full_shares) self.benchmark_name = chosen_benchmark - # Make it so that there is no chance of there being a difference in length between - # the portfolio and benchmark return DataFrames - ( - self.portfolio.returns, - self.portfolio.benchmark_returns, - ) = portfolio_helper.make_equal_length( - self.portfolio.returns, self.portfolio.benchmark_returns - ) - else: console.print( "[red]Please first load transactions file using 'load'[/red]\n" @@ -596,41 +578,26 @@ def call_alloc(self, other_args: List[str]): self.portfolio_name, self.benchmark_name ): if ns_parser.agg == "assets": - if self.portfolio.portfolio_assets_allocation.empty: - self.portfolio.calculate_allocations("asset") portfolio_view.display_assets_allocation( - self.portfolio.portfolio_assets_allocation, - self.portfolio.benchmark_assets_allocation, + self.portfolio, ns_parser.limit, ns_parser.tables, ) elif ns_parser.agg == "sectors": - if self.portfolio.portfolio_sectors_allocation.empty: - self.portfolio.calculate_allocations("sector") - portfolio_view.display_category_allocation( - self.portfolio.portfolio_sectors_allocation, - self.portfolio.benchmark_sectors_allocation, - ns_parser.agg, + portfolio_view.display_sectors_allocation( + self.portfolio, ns_parser.limit, ns_parser.tables, ) elif ns_parser.agg == "countries": - if self.portfolio.portfolio_country_allocation.empty: - self.portfolio.calculate_allocations("country") - portfolio_view.display_category_allocation( - self.portfolio.portfolio_country_allocation, - self.portfolio.benchmark_country_allocation, - ns_parser.agg, + portfolio_view.display_countries_allocation( + self.portfolio, ns_parser.limit, ns_parser.tables, ) elif ns_parser.agg == "regions": - if self.portfolio.portfolio_region_allocation.empty: - self.portfolio.calculate_allocations("region") - portfolio_view.display_category_allocation( - self.portfolio.portfolio_region_allocation, - self.portfolio.benchmark_region_allocation, - ns_parser.agg, + portfolio_view.display_regions_allocation( + self.portfolio, ns_parser.limit, ns_parser.tables, ) @@ -909,7 +876,7 @@ def call_var(self, other_args: List[str]): ) else: portfolio_view.display_var( - portfolio=self.portfolio, + portfolio_engine=self.portfolio, use_mean=ns_parser.use_mean, adjusted_var=ns_parser.adjusted, student_t=ns_parser.student_t, @@ -966,7 +933,7 @@ def call_es(self, other_args: List[str]): if ns_parser and self.portfolio is not None: if self.portfolio_name: portfolio_view.display_es( - portfolio=self.portfolio, + portfolio_engine=self.portfolio, use_mean=ns_parser.use_mean, distribution=ns_parser.distribution, percentile=ns_parser.percentile, @@ -1277,7 +1244,7 @@ def call_rsort(self, other_args: List[str]): self.portfolio_name, self.benchmark_name ): portfolio_view.display_rolling_sortino( - portfolio=self.portfolio, + portfolio_engine=self.portfolio, risk_free_rate=ns_parser.risk_free_rate / 100, window=ns_parser.period, export=ns_parser.export, diff --git a/openbb_terminal/portfolio/portfolio_helper.py b/openbb_terminal/portfolio/portfolio_helper.py index cf76687668f6..45bdaf8c9164 100644 --- a/openbb_terminal/portfolio/portfolio_helper.py +++ b/openbb_terminal/portfolio/portfolio_helper.py @@ -1046,7 +1046,7 @@ def get_kelly_criterion( if (not period_return.empty) and (not period_portfolio_tr.empty): w = len(period_return[period_return > 0]) / len(period_return) r = len( - period_portfolio_tr[period_portfolio_tr["% Portfolio Return"] > 0] + period_portfolio_tr[period_portfolio_tr["Portfolio % Return"] > 0] ) / len( period_portfolio_tr[period_portfolio_tr["Type"].str.upper() != "CASH"] ) @@ -1086,10 +1086,10 @@ def get_payoff_ratio(portfolio_trades: pd.DataFrame) -> pd.DataFrame: period_portfolio_tr = filter_df_by_period(portfolio_trades, period) if not portfolio_trades.empty: portfolio_wins = period_portfolio_tr[ - period_portfolio_tr["% Portfolio Return"] > 0 + period_portfolio_tr["Portfolio % Return"] > 0 ] portfolio_loses = period_portfolio_tr[ - period_portfolio_tr["% Portfolio Return"] < 0 + period_portfolio_tr["Portfolio % Return"] < 0 ] if portfolio_loses.empty: vals.append(["-"]) @@ -1140,10 +1140,10 @@ def get_profit_factor(portfolio_trades: pd.DataFrame) -> pd.DataFrame: period_portfolio_tr = filter_df_by_period(portfolio_trades, period) if not portfolio_trades.empty: portfolio_wins = period_portfolio_tr[ - period_portfolio_tr["% Portfolio Return"] > 0 + period_portfolio_tr["Portfolio % Return"] > 0 ] portfolio_loses = period_portfolio_tr[ - period_portfolio_tr["% Portfolio Return"] < 0 + period_portfolio_tr["Portfolio % Return"] < 0 ] if portfolio_loses.empty: vals.append(["-"]) diff --git a/openbb_terminal/portfolio/portfolio_model.py b/openbb_terminal/portfolio/portfolio_model.py index 9b7a2afe9684..f61c9c9a6999 100644 --- a/openbb_terminal/portfolio/portfolio_model.py +++ b/openbb_terminal/portfolio/portfolio_model.py @@ -3,7 +3,7 @@ import contextlib import logging -from typing import Dict, Any +from typing import Dict, Any, Tuple, Union import datetime import numpy as np @@ -15,10 +15,8 @@ from pycoingecko import CoinGeckoAPI from openbb_terminal.common.quantitative_analysis import qa_model from openbb_terminal.decorators import log_start_end -from openbb_terminal.portfolio import ( - portfolio_helper, - allocation_model, -) +from openbb_terminal.portfolio import portfolio_helper +from openbb_terminal.portfolio.allocation_model import get_allocation from openbb_terminal.rich_config import console # pylint: disable=E1136,W0201,R0902,C0302 @@ -30,7 +28,7 @@ pd.options.mode.chained_assignment = None -class PortfolioModel: +class PortfolioEngine: """ Class for portfolio analysis in OpenBB Implements a Portfolio and related methods. @@ -40,11 +38,11 @@ class PortfolioModel: read_transactions: Class method to read transactions from file __set_transactions: - preprocess_transactions: Method to preprocess, format and compute auxiliary fields + __preprocess_transactions: Method to preprocess, format and compute auxiliary fields get_transactions: Outputs the formatted transactions DataFrame - load_benchmark: Adds benchmark ticker, info, prices and returns + set_benchmark: Adds benchmark ticker, info, prices and returns mimic_trades_for_benchmark: Mimic trades from the transactions based on chosen benchmark assuming partial shares generate_portfolio_data: Generates portfolio data from transactions @@ -52,29 +50,32 @@ class PortfolioModel: populate_historical_trade_data: Create a new dataframe to store historical prices by ticker calculate_value: Calculate value end of day from historical data - calculate_reserves: Takes dividends into account for returns calculation - - calculate_allocations: Determine allocations based on assets, sectors, countries and region - set_risk_free_rate: Sets risk free rate + calculate_reserves: Takes dividends into account for returns calculation + + calculate_allocation: Determine allocation based on assets, sectors, countries and regions. """ def __init__(self, transactions: pd.DataFrame = pd.DataFrame()): - """Initialize PortfolioModel class""" + """Initialize PortfolioEngine class""" # Portfolio + self.empty = True self.tickers_list = None self.tickers: Dict[Any, Any] = {} self.inception_date = datetime.date(1970, 1, 1) self.historical_trade_data = pd.DataFrame() - self.returns = pd.DataFrame() self.itemized_value = pd.DataFrame() - self.portfolio_trades = pd.DataFrame() self.portfolio_value = None self.portfolio_historical_prices = pd.DataFrame() - self.empty = True + self.returns = pd.DataFrame() + self.portfolio_trades = pd.DataFrame() self.risk_free_rate = float(0) + self.portfolio_assets_allocation = pd.DataFrame() + self.portfolio_sectors_allocation = pd.DataFrame() + self.portfolio_regions_allocation = pd.DataFrame() + self.portfolio_countries_allocation = pd.DataFrame() # Benchmark self.benchmark_ticker: str = "" @@ -82,17 +83,10 @@ def __init__(self, transactions: pd.DataFrame = pd.DataFrame()): self.benchmark_historical_prices = pd.DataFrame() self.benchmark_returns = pd.DataFrame() self.benchmark_trades = pd.DataFrame() - - # Allocations - self.portfolio_assets_allocation = pd.DataFrame() - self.portfolio_sectors_allocation = pd.DataFrame() - self.portfolio_region_allocation = pd.DataFrame() - self.portfolio_country_allocation = pd.DataFrame() - self.benchmark_assets_allocation = pd.DataFrame() self.benchmark_sectors_allocation = pd.DataFrame() - self.benchmark_region_allocation = pd.DataFrame() - self.benchmark_country_allocation = pd.DataFrame() + self.benchmark_regions_allocation = pd.DataFrame() + self.benchmark_countries_allocation = pd.DataFrame() # Set and preprocess transactions if not transactions.empty: @@ -100,15 +94,17 @@ def __init__(self, transactions: pd.DataFrame = pd.DataFrame()): def __set_transactions(self, transactions): self.__transactions = transactions - self.preprocess_transactions() + self.__preprocess_transactions() self.empty = False def get_transactions(self): """Get formatted transactions - Returns: + Returns + ------- pd.DataFrame: formatted transactions """ + df = self.__transactions[ [ "Date", @@ -133,12 +129,17 @@ def get_transactions(self): @staticmethod def read_transactions(path: str) -> pd.DataFrame: - """Static method to read transactions from file + """Static method to read transactions from file. Parameters ---------- path: str path to transactions file + + Returns + ------- + pd.DataFrame + DataFrame with transactions """ # Load transactions from file if path.endswith(".xlsx"): @@ -149,7 +150,7 @@ def read_transactions(path: str) -> pd.DataFrame: return transactions @log_start_end(log=logger) - def preprocess_transactions(self): + def __preprocess_transactions(self): """Method to preprocess, format and compute auxiliary fields. Preprocessing steps: @@ -351,12 +352,13 @@ def preprocess_transactions(self): # Warn user of removed ISINs if removed_tickers: + p_bar.disable = True console.print( - f"\n\n[red]The following tickers are not supported and were removed: {removed_tickers}." + f"\n[red]The following tickers are not supported and were removed: {removed_tickers}." f"\nManually edit the 'Ticker' field with the proper Yahoo Finance suffix or provide a valid ISIN." f"\nSuffix info on 'Yahoo Finance market coverage':" " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html" - f"\nE.g. IWDA -> IWDA.AS[/red]" + f"\nE.g. IWDA -> IWDA.AS[/red]\n" ) except Exception: console.print("\nCould not preprocess transactions.") @@ -428,24 +430,24 @@ def load_company_data(self): ] = info_list @log_start_end(log=logger) - def load_benchmark(self, ticker: str = "SPY", full_shares: bool = False): - """Adds benchmark dataframe + def set_benchmark(self, symbol: str = "SPY", full_shares: bool = False): + """Load benchmark into portfolio. Parameters ---------- - ticker: str - benchmark ticker to download data + symbol: str + Benchmark symbol to download data full_shares: bool - whether to mimic the portfolio trades exactly (partial shares) or round down the - quantity to the nearest number. + Whether to mimic the portfolio trades exactly (partial shares) or round down the + quantity to the nearest number """ - p_bar = tqdm(range(3), desc=" Loading benchmark") + p_bar = tqdm(range(4), desc=" Loading benchmark") - self.benchmark_ticker = ticker + self.benchmark_ticker = symbol self.benchmark_historical_prices = yf.download( - ticker, + symbol, start=self.inception_date - datetime.timedelta(days=1), threads=False, progress=False, @@ -470,7 +472,15 @@ def load_benchmark(self, ticker: str = "SPY", full_shares: bool = False): p_bar.refresh() self.benchmark_returns = self.benchmark_historical_prices.pct_change().dropna() - self.benchmark_info = yf.Ticker(ticker).info + self.benchmark_info = yf.Ticker(symbol).info + + p_bar.n += 1 + p_bar.refresh() + + ( + self.returns, + self.benchmark_returns, + ) = portfolio_helper.make_equal_length(self.returns, self.benchmark_returns) p_bar.n += 1 p_bar.refresh() @@ -478,6 +488,7 @@ def load_benchmark(self, ticker: str = "SPY", full_shares: bool = False): @log_start_end(log=logger) def mimic_trades_for_benchmark(self, full_shares: bool = False): """Mimic trades from the transactions based on chosen benchmark assuming partial shares + Parameters ---------- full_shares: bool @@ -732,6 +743,18 @@ def calculate_value(self): self.historical_trade_data = trade_data + @log_start_end(log=logger) + def set_risk_free_rate(self, risk_free_rate: float): + """Sets risk free rate + + Parameters + ---------- + risk_free_rate : float + Risk free rate in float format + """ + + self.risk_free_rate = risk_free_rate + @log_start_end(log=logger) def calculate_reserves(self): """Takes dividends into account for returns calculation""" @@ -739,80 +762,96 @@ def calculate_reserves(self): console.print("Still has to be build.") @log_start_end(log=logger) - def calculate_allocations(self, category: str): - """Determine allocations based on assets, sectors, countries and region. + def calculate_allocation(self, category: str, recalculate: bool = False): + """Determine allocation based on Asset, Sector, Country or Region Parameters ---------- category: str - chosen allocation category from asset, sector, country or region - + Chosen allocation category from Asset, Sector, Country or Region + recalculate: bool + Flag to force recalculate allocation if already exists """ - if category == "asset": - # Determine asset allocation - ( - self.benchmark_assets_allocation, - self.portfolio_assets_allocation, - ) = allocation_model.get_assets_allocation( - self.benchmark_info, self.portfolio_trades - ) - elif category == "sector": - # Determine sector allocation - ( - self.benchmark_sectors_allocation, - self.portfolio_sectors_allocation, - ) = allocation_model.get_sector_allocation( - self.benchmark_info, self.portfolio_trades - ) - elif category in ("country", "region"): - # Determine region and country allocations - ( - self.benchmark_region_allocation, - self.benchmark_country_allocation, - ) = allocation_model.get_region_country_allocation(self.benchmark_ticker) - - ( - self.portfolio_region_allocation, - self.portfolio_country_allocation, - ) = allocation_model.get_portfolio_region_country_allocation( - self.portfolio_trades + if category == "Asset": + if ( + self.benchmark_assets_allocation.empty + or self.portfolio_assets_allocation.empty + or recalculate + ): + ( + self.benchmark_assets_allocation, + self.portfolio_assets_allocation, + ) = get_allocation(category, self.benchmark_info, self.portfolio_trades) + elif category == "Sector": + if ( + self.benchmark_sectors_allocation.empty + or self.portfolio_sectors_allocation.empty + or recalculate + ): + ( + self.benchmark_sectors_allocation, + self.portfolio_sectors_allocation, + ) = get_allocation(category, self.benchmark_info, self.portfolio_trades) + elif category == "Country": + if ( + self.benchmark_countries_allocation.empty + or self.portfolio_countries_allocation.empty + or recalculate + ): + ( + self.benchmark_countries_allocation, + self.portfolio_countries_allocation, + ) = get_allocation(category, self.benchmark_info, self.portfolio_trades) + elif category == "Region": + if ( + self.benchmark_regions_allocation.empty + or self.portfolio_regions_allocation.empty + or recalculate + ): + ( + self.benchmark_regions_allocation, + self.portfolio_regions_allocation, + ) = get_allocation(category, self.benchmark_info, self.portfolio_trades) + else: + console.print( + "Category not available. Choose from: Asset, Sector, Country or Region" ) - @log_start_end(log=logger) - def set_risk_free_rate(self, risk_free_rate: float): - """Sets risk free rate - - Parameters - ---------- - risk_free (float): risk free rate in float format - """ - self.risk_free_rate = risk_free_rate - # Metrics @log_start_end(log=logger) -def get_r2_score(portfolio: PortfolioModel) -> pd.DataFrame: - """Class method that retrieves R2 Score for portfolio and benchmark selected +def get_r2_score(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Method that retrieves R2 Score for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame with R2 Score between portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.rsquare(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( round( r2_score( - portfolio_helper.filter_df_by_period(portfolio.returns, period), portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.returns, period + ), + portfolio_helper.filter_df_by_period( + portfolio_engine.benchmark_returns, period ), ), 3, @@ -822,31 +861,41 @@ def get_r2_score(portfolio: PortfolioModel) -> pd.DataFrame: @log_start_end(log=logger) -def get_skewness(portfolio: PortfolioModel) -> pd.DataFrame: - """Class method that retrieves skewness for portfolio and benchmark selected +def get_skewness(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Method that retrieves skewness for portfolio and benchmark selected - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame with skewness for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.skew(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( [ round( scipy.stats.skew( - portfolio_helper.filter_df_by_period(portfolio.returns, period) + portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ) ), 3, ), round( scipy.stats.skew( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ) ), 3, @@ -859,33 +908,43 @@ def get_skewness(portfolio: PortfolioModel) -> pd.DataFrame: @log_start_end(log=logger) -def get_kurtosis(portfolio: PortfolioModel) -> pd.DataFrame: - """Class method that retrieves kurtosis for portfolio and benchmark selected +def get_kurtosis(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Method that retrieves kurtosis for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame with kurtosis for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.kurtosis(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( [ round( scipy.stats.kurtosis( - portfolio_helper.filter_df_by_period(portfolio.returns, period) + portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ) ), 3, ), round( scipy.stats.skew( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ) ), 3, @@ -898,13 +957,14 @@ def get_kurtosis(portfolio: PortfolioModel) -> pd.DataFrame: @log_start_end(log=logger) -def get_stats(portfolio: PortfolioModel, window: str = "all") -> pd.DataFrame: - """Class method that retrieves stats for portfolio and benchmark selected based on a certain interval +def get_stats(portfolio_engine: PortfolioEngine, window: str = "all") -> pd.DataFrame: + """Method that retrieves stats for portfolio and benchmark selected based on a certain interval Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to consider. Choices are: mtd, qtd, ytd, 3m, 6m, 1y, 3y, 5y, 10y, all @@ -912,14 +972,21 @@ def get_stats(portfolio: PortfolioModel, window: str = "all") -> pd.DataFrame: ------- pd.DataFrame DataFrame with overall stats for portfolio and benchmark for a certain period + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.stats(P) """ + df = ( - portfolio_helper.filter_df_by_period(portfolio.returns, window) + portfolio_helper.filter_df_by_period(portfolio_engine.returns, window) .describe() .to_frame() .join( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ).describe() ) ) @@ -928,24 +995,34 @@ def get_stats(portfolio: PortfolioModel, window: str = "all") -> pd.DataFrame: @log_start_end(log=logger) -def get_volatility(portfolio: PortfolioModel) -> pd.DataFrame: - """Class method that retrieves volatility for portfolio and benchmark selected +def get_volatility(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Method that retrieves volatility for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame with volatility for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.volatility(P) """ + vals = list() for period in portfolio_helper.PERIODS: - port_rets = portfolio_helper.filter_df_by_period(portfolio.returns, period) + port_rets = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ) bench_rets = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ) vals.append( [ @@ -968,14 +1045,15 @@ def get_volatility(portfolio: PortfolioModel) -> pd.DataFrame: @log_start_end(log=logger) def get_sharpe_ratio( - portfolio: PortfolioModel, risk_free_rate: float = 0 + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0 ) -> pd.DataFrame: - """Class method that retrieves sharpe ratio for portfolio and benchmark selected + """Method that retrieves sharpe ratio for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. risk_free_rate: float Risk free rate value @@ -983,14 +1061,23 @@ def get_sharpe_ratio( ------- pd.DataFrame DataFrame with sharpe ratio for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.sharpe(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( [ round( portfolio_helper.sharpe_ratio( - portfolio_helper.filter_df_by_period(portfolio.returns, period), + portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ), risk_free_rate, ), 3, @@ -998,7 +1085,7 @@ def get_sharpe_ratio( round( portfolio_helper.sharpe_ratio( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ), risk_free_rate, ), @@ -1013,14 +1100,15 @@ def get_sharpe_ratio( @log_start_end(log=logger) def get_sortino_ratio( - portfolio: PortfolioModel, risk_free_rate: float = 0 + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0 ) -> pd.DataFrame: - """Class method that retrieves sortino ratio for portfolio and benchmark selected + """Method that retrieves sortino ratio for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. risk_free_rate: float Risk free rate value @@ -1028,14 +1116,23 @@ def get_sortino_ratio( ------- pd.DataFrame DataFrame with sortino ratio for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.sortino(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( [ round( portfolio_helper.sortino_ratio( - portfolio_helper.filter_df_by_period(portfolio.returns, period), + portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ), risk_free_rate, ), 3, @@ -1043,7 +1140,7 @@ def get_sortino_ratio( round( portfolio_helper.sortino_ratio( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ), risk_free_rate, ), @@ -1057,33 +1154,43 @@ def get_sortino_ratio( @log_start_end(log=logger) -def get_maximum_drawdown_ratio(portfolio: PortfolioModel) -> pd.DataFrame: - """Class method that retrieves maximum drawdown ratio for portfolio and benchmark selected +def get_maximum_drawdown_ratio(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Method that retrieves maximum drawdown ratio for portfolio and benchmark selected Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame with maximum drawdown for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.maxdrawdown(P) """ + vals = list() for period in portfolio_helper.PERIODS: vals.append( [ round( portfolio_helper.maximum_drawdown( - portfolio_helper.filter_df_by_period(portfolio.returns, period) + portfolio_helper.filter_df_by_period( + portfolio_engine.returns, period + ) ), 3, ), round( portfolio_helper.maximum_drawdown( portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, period + portfolio_engine.benchmark_returns, period ) ), 3, @@ -1096,36 +1203,45 @@ def get_maximum_drawdown_ratio(portfolio: PortfolioModel) -> pd.DataFrame: @log_start_end(log=logger) -def get_gaintopain_ratio(portfolio: PortfolioModel): +def get_gaintopain_ratio(portfolio_engine: PortfolioEngine): """Get Pain-to-Gain ratio based on historical data Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of the portfolio's gain-to-pain ratio + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.gaintopain(P) """ + gtp_period_df = portfolio_helper.get_gaintopain_ratio( - portfolio.historical_trade_data, - portfolio.benchmark_trades, - portfolio.benchmark_returns, + portfolio_engine.historical_trade_data, + portfolio_engine.benchmark_trades, + portfolio_engine.benchmark_returns, ) return gtp_period_df @log_start_end(log=logger) -def get_tracking_error(portfolio: PortfolioModel, window: int = 252): +def get_tracking_error(portfolio_engine: PortfolioEngine, window: int = 252): """Get tracking error Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: int Interval used for rolling values @@ -1135,47 +1251,62 @@ def get_tracking_error(portfolio: PortfolioModel, window: int = 252): DataFrame of tracking errors during different time windows pd.Series Series of rolling tracking error + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.trackerr(P) """ + trackr_period_df, trackr_rolling = portfolio_helper.get_tracking_error( - portfolio.returns, portfolio.benchmark_returns, window + portfolio_engine.returns, portfolio_engine.benchmark_returns, window ) return trackr_period_df, trackr_rolling @log_start_end(log=logger) -def get_information_ratio(portfolio: PortfolioModel): +def get_information_ratio(portfolio_engine: PortfolioEngine): """Get information ratio Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of the information ratio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.information(P) """ + ir_period_df = portfolio_helper.get_information_ratio( - portfolio.returns, - portfolio.historical_trade_data, - portfolio.benchmark_trades, - portfolio.benchmark_returns, + portfolio_engine.returns, + portfolio_engine.historical_trade_data, + portfolio_engine.benchmark_trades, + portfolio_engine.benchmark_returns, ) return ir_period_df @log_start_end(log=logger) -def get_tail_ratio(portfolio: PortfolioModel, window: int = 252): +def get_tail_ratio(portfolio_engine: PortfolioEngine, window: int = 252): """Get tail ratio Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded - + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: int Interval used for rolling values @@ -1187,33 +1318,48 @@ def get_tail_ratio(portfolio: PortfolioModel, window: int = 252): Series of the portfolios rolling tail ratio pd.Series Series of the benchmarks rolling tail ratio + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.tail(P) """ + tailr_period_df, portfolio_tr, benchmark_tr = portfolio_helper.get_tail_ratio( - portfolio.returns, portfolio.benchmark_returns, window + portfolio_engine.returns, portfolio_engine.benchmark_returns, window ) return tailr_period_df, portfolio_tr, benchmark_tr @log_start_end(log=logger) -def get_common_sense_ratio(portfolio: PortfolioModel): +def get_common_sense_ratio(portfolio_engine: PortfolioEngine): """Get common sense ratio Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of the portfolios and the benchmarks common sense ratio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.commonsense(P) """ + csr_period_df = portfolio_helper.get_common_sense_ratio( - portfolio.returns, - portfolio.historical_trade_data, - portfolio.benchmark_trades, - portfolio.benchmark_returns, + portfolio_engine.returns, + portfolio_engine.historical_trade_data, + portfolio_engine.benchmark_trades, + portfolio_engine.benchmark_returns, ) return csr_period_df @@ -1221,14 +1367,15 @@ def get_common_sense_ratio(portfolio: PortfolioModel): @log_start_end(log=logger) def get_jensens_alpha( - portfolio: PortfolioModel, risk_free_rate: float = 0, window: str = "1y" + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, window: str = "1y" ): """Get jensen's alpha Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: str Interval used for rolling values risk_free_rate: float @@ -1240,12 +1387,19 @@ def get_jensens_alpha( DataFrame of jensens's alpha during different time windows pd.Series Series of jensens's alpha data + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.jensens(P) """ + ja_period_df, ja_rolling = portfolio_helper.jensens_alpha( - portfolio.returns, - portfolio.historical_trade_data, - portfolio.benchmark_trades, - portfolio.benchmark_returns, + portfolio_engine.returns, + portfolio_engine.historical_trade_data, + portfolio_engine.benchmark_trades, + portfolio_engine.benchmark_returns, risk_free_rate, window, ) @@ -1254,13 +1408,14 @@ def get_jensens_alpha( @log_start_end(log=logger) -def get_calmar_ratio(portfolio: PortfolioModel, window: int = 756): +def get_calmar_ratio(portfolio_engine: PortfolioEngine, window: int = 756): """Get calmar ratio Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: int Interval used for rolling values @@ -1270,12 +1425,19 @@ def get_calmar_ratio(portfolio: PortfolioModel, window: int = 756): DataFrame of calmar ratio of the benchmark and portfolio during different time periods pd.Series Series of calmar ratio data + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.calmar(P) """ + cr_period_df, cr_rolling = portfolio_helper.get_calmar_ratio( - portfolio.returns, - portfolio.historical_trade_data, - portfolio.benchmark_trades, - portfolio.benchmark_returns, + portfolio_engine.returns, + portfolio_engine.historical_trade_data, + portfolio_engine.benchmark_trades, + portfolio_engine.benchmark_returns, window, ) @@ -1283,73 +1445,108 @@ def get_calmar_ratio(portfolio: PortfolioModel, window: int = 756): @log_start_end(log=logger) -def get_kelly_criterion(portfolio: PortfolioModel): +def get_kelly_criterion(portfolio_engine: PortfolioEngine): """Gets kelly criterion Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of kelly criterion of the portfolio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.kelly(P) """ + kc_period_df = portfolio_helper.get_kelly_criterion( - portfolio.returns, portfolio.portfolio_trades + portfolio_engine.returns, portfolio_engine.portfolio_trades ) return kc_period_df @log_start_end(log=logger) -def get_payoff_ratio(portfolio: PortfolioModel): +def get_payoff_ratio(portfolio_engine: PortfolioEngine): """Gets payoff ratio Returns ------- pd.DataFrame DataFrame of payoff ratio of the portfolio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.payoff(P) """ - pr_period_ratio = portfolio_helper.get_payoff_ratio(portfolio.portfolio_trades) + + pr_period_ratio = portfolio_helper.get_payoff_ratio( + portfolio_engine.portfolio_trades + ) return pr_period_ratio @log_start_end(log=logger) -def get_profit_factor(portfolio: PortfolioModel): +def get_profit_factor(portfolio_engine: PortfolioEngine): """Gets profit factor Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of profit factor of the portfolio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.profitfactor(P) """ - pf_period_df = portfolio_helper.get_profit_factor(portfolio.portfolio_trades) + + pf_period_df = portfolio_helper.get_profit_factor(portfolio_engine.portfolio_trades) return pf_period_df -def get_holdings_value(portfolio: PortfolioModel) -> pd.DataFrame: +def get_holdings_value(portfolio_engine: PortfolioEngine) -> pd.DataFrame: """Get holdings of assets (absolute value) Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. Returns ------- pd.DataFrame DataFrame of holdings + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.holdv(P) """ - all_holdings = portfolio.historical_trade_data["End Value"][portfolio.tickers_list] + + all_holdings = portfolio_engine.historical_trade_data["End Value"][ + portfolio_engine.tickers_list + ] all_holdings["Total Value"] = all_holdings.sum(axis=1) # No need to account for time since this is daily data @@ -1359,17 +1556,26 @@ def get_holdings_value(portfolio: PortfolioModel) -> pd.DataFrame: def get_holdings_percentage( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, ): """Get holdings of assets (in percentage) Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.holdp(P) """ - all_holdings = portfolio.historical_trade_data["End Value"][portfolio.tickers_list] + all_holdings = portfolio_engine.historical_trade_data["End Value"][ + portfolio_engine.tickers_list + ] all_holdings = all_holdings.divide(all_holdings.sum(axis=1), axis=0) * 100 @@ -1381,7 +1587,7 @@ def get_holdings_percentage( @log_start_end(log=logger) def get_maximum_drawdown( - portfolio: PortfolioModel, is_returns: bool = False + portfolio_engine: PortfolioEngine, is_returns: bool = False ) -> pd.Series: """Calculate the drawdown (MDD) of historical series. Note that the calculation is done on cumulative returns (or prices). The definition of drawdown is @@ -1396,13 +1602,20 @@ def get_maximum_drawdown( Flag to indicate inputs are returns Returns - ---------- + ------- pd.Series Holdings series pd.Series Drawdown series + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.maxdd(P) """ - holdings: pd.Series = portfolio.portfolio_value + + holdings: pd.Series = portfolio_engine.portfolio_value if is_returns: holdings = (1 + holdings).cumprod() @@ -1413,21 +1626,31 @@ def get_maximum_drawdown( def get_distribution_returns( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", ): """Display daily returns Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.distr(P) """ - portfolio_returns = portfolio_helper.filter_df_by_period(portfolio.returns, window) + + portfolio_returns = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, window + ) benchmark_returns = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) df = pd.DataFrame(portfolio_returns).join(pd.DataFrame(benchmark_returns)) @@ -1438,25 +1661,34 @@ def get_distribution_returns( def get_rolling_volatility( - portfolio: PortfolioModel, window: str = "1y" + portfolio_engine: PortfolioEngine, window: str = "1y" ) -> pd.DataFrame: """Get rolling volatility Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str Rolling window size to use Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rvol(P) """ - portfolio_rvol = portfolio_helper.rolling_volatility(portfolio.returns, window) + portfolio_rvol = portfolio_helper.rolling_volatility( + portfolio_engine.returns, window + ) if portfolio_rvol.empty: return pd.DataFrame() benchmark_rvol = portfolio_helper.rolling_volatility( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) if benchmark_rvol.empty: return pd.DataFrame() @@ -1469,7 +1701,7 @@ def get_rolling_volatility( def get_rolling_sharpe( - portfolio: pd.DataFrame, risk_free_rate: float = 0, window: str = "1y" + portfolio_engine: pd.DataFrame, risk_free_rate: float = 0, window: str = "1y" ) -> pd.DataFrame: """Get rolling sharpe ratio @@ -1487,16 +1719,22 @@ def get_rolling_sharpe( ------- pd.DataFrame Rolling sharpe ratio DataFrame + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rsharpe(P) """ portfolio_rsharpe = portfolio_helper.rolling_sharpe( - portfolio.returns, risk_free_rate, window + portfolio_engine.returns, risk_free_rate, window ) if portfolio_rsharpe.empty: return pd.DataFrame() benchmark_rsharpe = portfolio_helper.rolling_sharpe( - portfolio.benchmark_returns, risk_free_rate, window + portfolio_engine.benchmark_returns, risk_free_rate, window ) if benchmark_rsharpe.empty: return pd.DataFrame() @@ -1509,7 +1747,7 @@ def get_rolling_sharpe( def get_rolling_sortino( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, window: str = "1y", ) -> pd.DataFrame: @@ -1517,27 +1755,34 @@ def get_rolling_sortino( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object window: str interval for window to consider Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y risk_free_rate: float Value to use for risk free rate in sharpe/other calculations + Returns ------- pd.DataFrame Rolling sortino ratio DataFrame + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rsortino(P) """ portfolio_rsortino = portfolio_helper.rolling_sortino( - portfolio.returns, risk_free_rate, window + portfolio_engine.returns, risk_free_rate, window ) if portfolio_rsortino.empty: return pd.DataFrame() benchmark_rsortino = portfolio_helper.rolling_sortino( - portfolio.benchmark_returns, risk_free_rate, window + portfolio_engine.benchmark_returns, risk_free_rate, window ) if benchmark_rsortino.empty: return pd.DataFrame() @@ -1551,15 +1796,15 @@ def get_rolling_sortino( @log_start_end(log=logger) def get_rolling_beta( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "1y", ) -> pd.DataFrame: """Get rolling beta using portfolio and benchmark returns Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object window: string Interval used for rolling values. Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y. @@ -1568,10 +1813,16 @@ def get_rolling_beta( ------- pd.DataFrame DataFrame of the portfolio's rolling beta + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rbeta(P) """ df = portfolio_helper.rolling_beta( - portfolio.returns, portfolio.benchmark_returns, window + portfolio_engine.returns, portfolio_engine.benchmark_returns, window ) return df @@ -1579,7 +1830,7 @@ def get_rolling_beta( @log_start_end(log=logger) def get_performance_vs_benchmark( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, show_all_trades: bool = False, ) -> pd.DataFrame: @@ -1587,18 +1838,26 @@ def get_performance_vs_benchmark( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. show_all_trades: bool Whether to also show all trades made and their performance (default is False) + Returns ------- pd.DataFrame + DataFrame with portfolio performance vs the benchmark + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.perf(P) """ - portfolio_trades = portfolio.portfolio_trades - benchmark_trades = portfolio.benchmark_trades + portfolio_trades = portfolio_engine.portfolio_trades + benchmark_trades = portfolio_engine.benchmark_trades portfolio_trades.index = pd.to_datetime(portfolio_trades["Date"].values) benchmark_trades.index = pd.to_datetime(benchmark_trades["Date"].values) @@ -1683,7 +1942,7 @@ def get_performance_vs_benchmark( @log_start_end(log=logger) def get_var( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, use_mean: bool = False, adjusted_var: bool = False, student_t: bool = False, @@ -1694,8 +1953,9 @@ def get_var( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: bool if one should use the data mean return adjusted_var: bool @@ -1704,13 +1964,21 @@ def get_var( If one should use the student-t distribution percentile: float var percentile (%) + Returns ------- pd.DataFrame + DataFrame with portfolio VaR + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.var(P) """ + return qa_model.get_var( - data=portfolio.returns, + data=portfolio_engine.returns, use_mean=use_mean, adjusted_var=adjusted_var, student_t=student_t, @@ -1721,7 +1989,7 @@ def get_var( @log_start_end(log=logger) def get_es( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, use_mean: bool = False, distribution: str = "normal", percentile: float = 99.9, @@ -1730,22 +1998,30 @@ def get_es( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: if one should use the data mean return distribution: str choose distribution to use: logistic, laplace, normal percentile: float es percentile (%) + Returns ------- pd.DataFrame + DataFrame with portfolio expected shortfall + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.es(P) """ return qa_model.get_es( - data=portfolio.returns, + data=portfolio_engine.returns, use_mean=use_mean, distribution=distribution, percentile=percentile, @@ -1755,55 +2031,75 @@ def get_es( @log_start_end(log=logger) def get_omega( - portfolio: PortfolioModel, threshold_start: float = 0, threshold_end: float = 1.5 + portfolio_engine: PortfolioEngine, + threshold_start: float = 0, + threshold_end: float = 1.5, ) -> pd.DataFrame: """Get omega ratio Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. threshold_start: float annualized target return threshold start of plotted threshold range threshold_end: float annualized target return threshold end of plotted threshold range + Returns ------- pd.DataFrame + DataFrame with portfolio omega ratio + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.om(P) """ return qa_model.get_omega( - data=portfolio.returns, + data=portfolio_engine.returns, threshold_start=threshold_start, threshold_end=threshold_end, ) def get_summary( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", risk_free_rate: float = 0, ) -> pd.DataFrame: - """Get summary portfolio and benchmark returns + """Get portfolio and benchmark returns summary Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark risk_free_rate : float Risk free rate for calculations + Returns ------- pd.DataFrame + DataFrame with portfolio and benchmark returns summary + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.summary(P) """ - portfolio_returns = portfolio_helper.filter_df_by_period(portfolio.returns, window) + portfolio_returns = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, window + ) benchmark_returns = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) metrics = { @@ -1849,21 +2145,36 @@ def get_summary( @log_start_end(log=logger) def get_yearly_returns( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", -): +) -> pd.DataFrame: """Get yearly returns Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark + + Returns + ------- + pd.DataFrame + DataFrame with yearly returns + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.yret(P) """ - portfolio_returns = portfolio_helper.filter_df_by_period(portfolio.returns, window) + + portfolio_returns = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, window + ) benchmark_returns = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) creturns_year_val = list() @@ -1898,25 +2209,36 @@ def get_yearly_returns( @log_start_end(log=logger) def get_monthly_returns( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", ) -> pd.DataFrame: """Get monthly returns Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark + Returns ------- pd.DataFrame + DataFrame with monthly returns + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.mret(P) """ - portfolio_returns = portfolio_helper.filter_df_by_period(portfolio.returns, window) + + portfolio_returns = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, window + ) benchmark_returns = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) creturns_month_val = list() @@ -1993,25 +2315,36 @@ def get_monthly_returns( @log_start_end(log=logger) def get_daily_returns( - portfolio: PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", ) -> pd.DataFrame: """Get daily returns Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark + Returns ------- pd.DataFrame + DataFrame with daily returns + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.dret(P) """ - portfolio_returns = portfolio_helper.filter_df_by_period(portfolio.returns, window) + + portfolio_returns = portfolio_helper.filter_df_by_period( + portfolio_engine.returns, window + ) benchmark_returns = portfolio_helper.filter_df_by_period( - portfolio.benchmark_returns, window + portfolio_engine.benchmark_returns, window ) df = portfolio_returns.to_frame() @@ -2022,6 +2355,316 @@ def get_daily_returns( return df +@log_start_end(log=logger) +def generate_portfolio( + transactions_file_path: str, + benchmark_symbol: str = "SPY", + full_shares: bool = False, + risk_free_rate: float = 0, +) -> PortfolioEngine: + """Get PortfolioEngine object + + Parameters + ---------- + transactions_file_path : str + Path to transactions file + benchmark_symbol : str + Benchmark ticker to download data + full_shares : bool + Whether to mimic the portfolio trades exactly (partial shares) or round down the + quantity to the nearest number + risk_free_rate : float + Risk free rate in float format + + Returns + ------- + PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + """ + + transactions = PortfolioEngine.read_transactions(transactions_file_path) + portfolio_engine = PortfolioEngine(transactions) + portfolio_engine.generate_portfolio_data() + portfolio_engine.set_benchmark(symbol=benchmark_symbol, full_shares=full_shares) + portfolio_engine.set_risk_free_rate(risk_free_rate) + + return portfolio_engine + + +@log_start_end(log=logger) +def get_transactions(portfolio_engine: PortfolioEngine) -> pd.DataFrame: + """Get portfolio transactions + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine object + + Returns + ------- + pd.DataFrame + Portfolio transactions + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.show(P) + """ + + return portfolio_engine.get_transactions() + + +@log_start_end(log=logger) +def set_benchmark( + portfolio_engine: PortfolioEngine, symbol: str, full_shares: bool = False +): + """Load benchmark into portfolio + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine object + symbol: str + Benchmark symbol to download data + full_shares: bool + Whether to mimic the portfolio trades exactly (partial shares) or round down the + quantity to the nearest number + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.bench(P, symbol="SPY") + """ + + portfolio_engine.set_benchmark(symbol=symbol, full_shares=full_shares) + + +@log_start_end(log=logger) +def set_risk_free_rate(portfolio_engine: PortfolioEngine, risk_free_rate: float): + """Set risk-free rate + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine object + risk_free_rate: float + Risk free rate in float format + """ + + portfolio_engine.set_risk_free_rate(risk_free_rate=risk_free_rate) + + +def join_allocation( + portfolio: pd.DataFrame, benchmark: pd.DataFrame, column: str +) -> pd.DataFrame: + """Helper method to join portfolio and benchmark allocation by column + + Parameters + ---------- + portfolio: pd.DataFrame + Portfolio allocation + benchmark: pd.DataFrame + Benchmark allocation + column: str + Column to join DataFrames + + Returns + ------- + pd.DataFrame + DataFrame with portfolio and benchmark allocations + """ + combined = pd.merge(portfolio, benchmark, on=column, how="left") + combined["Difference"] = combined["Portfolio"] - combined["Benchmark"] + combined = combined.replace(np.nan, "-") + combined = combined.replace(0, "-") + + return combined + + +@log_start_end(log=logger) +def get_assets_allocation( + portfolio_engine: PortfolioEngine, + tables: bool = False, + limit: int = 10, + recalculate: bool = False, +) -> Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]]: + """Display portfolio asset allocation compared to the benchmark + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + + Returns + ------- + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.assets(P) + """ + + portfolio_engine.calculate_allocation(category="Asset", recalculate=recalculate) + + benchmark_allocation = portfolio_engine.benchmark_assets_allocation.iloc[:limit] + portfolio_allocation = portfolio_engine.portfolio_assets_allocation.iloc[:limit] + + combined = join_allocation(portfolio_allocation, benchmark_allocation, "Symbol") + + if tables: + return combined, portfolio_allocation, benchmark_allocation + return combined + + +def get_sectors_allocation( + portfolio_engine=None, + limit: int = 10, + tables: bool = False, + recalculate: bool = False, +): + """Display portfolio sector allocation compared to the benchmark + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + + Returns + ------- + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.sectors(P) + """ + + portfolio_engine.calculate_allocation(category="Sector", recalculate=recalculate) + + benchmark_allocation = portfolio_engine.benchmark_sectors_allocation.iloc[:limit] + portfolio_allocation = portfolio_engine.portfolio_sectors_allocation.iloc[:limit] + + combined = join_allocation(portfolio_allocation, benchmark_allocation, "Sector") + + if tables: + return combined, portfolio_allocation, benchmark_allocation + return combined + + +def get_countries_allocation( + portfolio_engine=None, + limit: int = 10, + tables: bool = False, + recalculate: bool = False, +): + """Display portfolio country allocation compared to the benchmark + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + + Returns + ------- + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.countries(P) + """ + + portfolio_engine.calculate_allocation(category="Country", recalculate=recalculate) + + benchmark_allocation = portfolio_engine.benchmark_countries_allocation.iloc[:limit] + portfolio_allocation = portfolio_engine.portfolio_countries_allocation.iloc[:limit] + + combined = join_allocation(portfolio_allocation, benchmark_allocation, "Country") + + if tables: + return combined, portfolio_allocation, benchmark_allocation + return combined + + +def get_regions_allocation( + portfolio_engine=None, + limit: int = 10, + tables: bool = False, + recalculate: bool = False, +): + """Display portfolio region allocation compared to the benchmark + + Parameters + ---------- + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + + Returns + ------- + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.regions(P) + """ + + portfolio_engine.calculate_allocation(category="Region", recalculate=recalculate) + + benchmark_allocation = portfolio_engine.benchmark_regions_allocation.iloc[:limit] + portfolio_allocation = portfolio_engine.portfolio_regions_allocation.iloc[:limit] + + combined = join_allocation(portfolio_allocation, benchmark_allocation, "Region") + + if tables: + return combined, portfolio_allocation, benchmark_allocation + return combined + + # Old code @log_start_end(log=logger) def get_main_text(data: pd.DataFrame) -> str: diff --git a/openbb_terminal/portfolio/portfolio_view.py b/openbb_terminal/portfolio/portfolio_view.py index c4a36e3e2be6..7880a2945d9a 100644 --- a/openbb_terminal/portfolio/portfolio_view.py +++ b/openbb_terminal/portfolio/portfolio_view.py @@ -14,7 +14,45 @@ from openbb_terminal.common.quantitative_analysis import qa_view from openbb_terminal.config_terminal import theme from openbb_terminal.config_plot import PLOT_DPI -from openbb_terminal.portfolio import portfolio_model +from openbb_terminal.portfolio.portfolio_model import ( + PortfolioEngine, + get_transactions, + get_daily_returns, + get_performance_vs_benchmark, + get_yearly_returns, + get_monthly_returns, + get_distribution_returns, + get_holdings_value, + get_holdings_percentage, + get_rolling_volatility, + get_rolling_sharpe, + get_rolling_sortino, + get_rolling_beta, + get_maximum_drawdown, + get_r2_score, + get_skewness, + get_kurtosis, + get_stats, + get_assets_allocation, + get_sectors_allocation, + get_countries_allocation, + get_regions_allocation, + get_volatility, + get_sharpe_ratio, + get_sortino_ratio, + get_maximum_drawdown_ratio, + get_gaintopain_ratio, + get_tracking_error, + get_information_ratio, + get_tail_ratio, + get_common_sense_ratio, + get_jensens_alpha, + get_calmar_ratio, + get_kelly_criterion, + get_payoff_ratio, + get_profit_factor, + get_summary, +) from openbb_terminal.helper_funcs import ( export_data, @@ -62,7 +100,7 @@ def load_info(): @log_start_end(log=logger) def display_transactions( - portfolio=None, + portfolio_engine=None, show_index=False, limit: int = 10, export: str = "", @@ -71,8 +109,8 @@ def display_transactions( Parameters ---------- - portfolio: Portfolio - Instance of Portfolio class + portfolio_engine: PortfolioEngine + Instance of PortfolioEngine class show_index: bool Defaults to False. limit: int @@ -81,11 +119,12 @@ def display_transactions( Export certain type of data """ - if portfolio.empty: + if portfolio_engine.empty: logger.warning("No transactions file loaded.") console.print("[red]No transactions file loaded.[/red]\n") + else: - df = portfolio.get_transactions() + df = get_transactions(portfolio_engine) print_rich_table( df=df[:limit], show_index=show_index, @@ -102,156 +141,204 @@ def display_transactions( @log_start_end(log=logger) def display_assets_allocation( - portfolio_allocation: pd.DataFrame, - benchmark_allocation: pd.DataFrame, + portfolio_engine=None, limit: int = 10, - include_separate_tables: bool = False, + tables: bool = False, ): """Display portfolio asset allocation compared to the benchmark Parameters ---------- - portfolio_allocation: pd.DataFrame - The asset allocation of the portfolio - benchmark_allocation: pd.DataFrame - The asset allocation of the benchmark - limit: int - The amount of assets you wish to show, by default this is set to 10. - include_separate_tables: bool + portfolio_engine: PortfolioEngine + Instance of PortfolioEngine class + tables: bool Whether to include separate asset allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 """ - benchmark_allocation = benchmark_allocation.iloc[:limit] - portfolio_allocation = portfolio_allocation.iloc[:limit] + combined, portfolio_allocation, benchmark_allocation = get_assets_allocation( + portfolio_engine=portfolio_engine, + limit=limit, + tables=True, + ) - combined = pd.merge( - portfolio_allocation, benchmark_allocation, on="Symbol", how="left" + display_category( + category="assets", + df0=combined, + df1=portfolio_allocation, + df2=benchmark_allocation, + tables=tables, + limit=limit, ) - combined["Difference"] = combined["Portfolio"] - combined["Benchmark"] - combined = combined.replace(np.nan, "-") - combined = combined.replace(0, "-") - print_rich_table( - combined, - headers=list(combined.columns), - title=f"Portfolio vs. Benchmark - Top {len(combined) if len(combined) < limit else limit} Assets Allocation", - floatfmt=["", ".2%", ".2%", ".2%"], - show_index=False, + +@log_start_end(log=logger) +def display_sectors_allocation( + portfolio_engine=None, + limit: int = 10, + tables: bool = False, +): + """Display portfolio sector allocation compared to the benchmark + + Parameters + ---------- + portfolio_engine: PortfolioEngine + Instance of PortfolioEngine class + limit: int + The amount of assets you wish to show, by default this is set to 10 + tables: bool + Whether to include separate asset allocation tables + """ + + combined, portfolio_allocation, benchmark_allocation = get_sectors_allocation( + portfolio_engine=portfolio_engine, + limit=limit, + tables=True, ) - if include_separate_tables: - console.print("") - print_rich_table( - portfolio_allocation, - headers=list(portfolio_allocation.columns), - title=f"Portfolio - Top {len(portfolio_allocation) if len(benchmark_allocation) < limit else limit} " - f"Assets Allocation", - floatfmt=[".2%", ".2%"], - show_index=False, - ) - console.print("") - print_rich_table( - benchmark_allocation, - headers=list(benchmark_allocation.columns), - title=f"Benchmark - Top {len(benchmark_allocation) if len(benchmark_allocation) < limit else limit} " - f"Assets Allocation", - floatfmt=[".2%", ".2%"], - show_index=False, - ) + display_category( + category="sectors", + df0=combined, + df1=portfolio_allocation, + df2=benchmark_allocation, + tables=tables, + limit=limit, + ) @log_start_end(log=logger) -def display_category_allocation( - portfolio_allocation: pd.DataFrame, - benchmark_allocation: pd.DataFrame, - category: str = "sectors", +def display_countries_allocation( + portfolio_engine=None, limit: int = 10, - include_separate_tables: bool = False, + tables: bool = False, ): - """Display portfolio sector, country or region allocation compared to the benchmark + """Display portfolio country allocation compared to the benchmark Parameters ---------- - portfolio_allocation: pd.DataFrame - The allocation to the set category of the portfolio - benchmark_allocation: pd.DataFrame - The allocation to the set category of the benchmark - category: str - Whether you want to show sectors, countries or regions + portfolio_engine: PortfolioEngine + Instance of PortfolioEngine class limit: int - The amount of assets you wish to show, by default this is set to 10. - include_separate_tables: bool + The amount of assets you wish to show, by default this is set to 10 + tables: bool Whether to include separate asset allocation tables """ - if benchmark_allocation.empty: - console.print(f"[red]Benchmark data for {category} is empty.\n[/red]") - return + combined, portfolio_allocation, benchmark_allocation = get_countries_allocation( + portfolio_engine=portfolio_engine, + limit=limit, + tables=True, + ) - if portfolio_allocation.empty: - console.print(f"[red]Portfolio data for {category} is empty.\n[/red]") - return + display_category( + category="countries", + df0=combined, + df1=portfolio_allocation, + df2=benchmark_allocation, + tables=tables, + limit=limit, + ) - benchmark_allocation = benchmark_allocation.iloc[:limit] - portfolio_allocation = portfolio_allocation.iloc[:limit] - combined = pd.DataFrame() +@log_start_end(log=logger) +def display_regions_allocation( + portfolio_engine=None, + limit: int = 10, + tables: bool = False, +): + """Display portfolio region allocation compared to the benchmark - for category_name, allocation in portfolio_allocation.items(): - if category_name in benchmark_allocation.index: - benchmark_allocation_value = float( - benchmark_allocation[benchmark_allocation.index == category_name] - ) - else: - benchmark_allocation_value = 0 - - combined = combined.append( - [ - [ - category_name, - allocation, - benchmark_allocation_value, - allocation - benchmark_allocation_value, - ] - ] - ) + Parameters + ---------- + portfolio_engine: PortfolioEngine + Instance of PortfolioEngine class + limit: int + The amount of assets you wish to show, by default this is set to 10 + tables: bool + Whether to include separate asset allocation tables + """ - combined.columns = [category.capitalize(), "Portfolio", "Benchmark", "Difference"] + combined, portfolio_allocation, benchmark_allocation = get_regions_allocation( + portfolio_engine=portfolio_engine, + limit=limit, + tables=True, + ) - print_rich_table( - combined.replace(0, "-"), - headers=list(combined.columns), - title=f"Portfolio vs. Benchmark - Top {len(combined) if len(combined) < limit else limit} " - f"{category.capitalize()} Allocation", - floatfmt=[".2f", ".2%", ".2%", ".2%"], - show_index=False, + display_category( + category="regions", + df0=combined, + df1=portfolio_allocation, + df2=benchmark_allocation, + tables=tables, + limit=limit, ) - if include_separate_tables: +def display_category(**kwargs): + """Display category tables + + Parameters + ---------- + **kwargs + """ + + category = kwargs["category"] + combined = kwargs["df0"] + portfolio_allocation = kwargs["df1"] + benchmark_allocation = kwargs["df2"] + tables = kwargs["tables"] + limit = kwargs["limit"] + + if benchmark_allocation.empty: + console.print(f"[red]Benchmark data for {category} is empty.[/red]") + return + + if portfolio_allocation.empty: + console.print(f"[red]Portfolio data for {category} is empty.[/red]") + return + + if tables: + print_rich_table( + combined.replace(0, "-"), + headers=list(combined.columns), + title=f"Portfolio vs. Benchmark - Top {len(combined) if len(combined) < limit else limit} " + f"{category.capitalize()} Allocation", + floatfmt=[".2f", ".2%", ".2%", ".2%"], + show_index=False, + ) + console.print("") print_rich_table( pd.DataFrame(portfolio_allocation), - headers=list(["Allocation"]), + headers=["Symbol", "Allocation"], title=f"Portfolio - Top {len(portfolio_allocation) if len(portfolio_allocation) < limit else limit} " f"{category.capitalize()} Allocation", - floatfmt=[".2%"], - show_index=True, + floatfmt=["", ".2%"], + show_index=False, ) - + console.print("") print_rich_table( pd.DataFrame(benchmark_allocation), - headers=list(["Allocation"]), + headers=["Symbol", "Allocation"], title=f"Benchmark - Top {len(benchmark_allocation) if len(benchmark_allocation) < limit else limit} " f"{category.capitalize()} Allocation", - floatfmt=[".2%"], - show_index=True, + floatfmt=["", ".2%"], + show_index=False, + ) + else: + print_rich_table( + combined.replace(0, "-"), + headers=list(combined.columns), + title=f"Portfolio vs. Benchmark - Top {len(combined) if len(combined) < limit else limit} " + f"{category.capitalize()} Allocation", + floatfmt=[".2f", ".2%", ".2%", ".2%"], + show_index=False, ) - console.print("\n") @log_start_end(log=logger) def display_performance_vs_benchmark( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, show_all_trades: bool = False, ): """Display portfolio performance vs the benchmark @@ -266,7 +353,7 @@ def display_performance_vs_benchmark( Whether to also show all trades made and their performance (default is False) """ - df = portfolio_model.get_performance_vs_benchmark(portfolio, show_all_trades) + df = get_performance_vs_benchmark(portfolio_engine, show_all_trades) if show_all_trades: print_rich_table( @@ -287,7 +374,7 @@ def display_performance_vs_benchmark( @log_start_end(log=logger) def display_yearly_returns( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", raw: bool = False, export: str = "", @@ -297,8 +384,9 @@ def display_yearly_returns( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False @@ -309,7 +397,7 @@ def display_yearly_returns( Optional axes to display plot on """ - df = portfolio_model.get_yearly_returns(portfolio, window) + df = get_yearly_returns(portfolio_engine, window) if raw: print_rich_table( @@ -367,7 +455,7 @@ def display_yearly_returns( @log_start_end(log=logger) def display_monthly_returns( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", raw: bool = False, show_vals: bool = False, @@ -378,8 +466,9 @@ def display_monthly_returns( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False @@ -392,9 +481,7 @@ def display_monthly_returns( Optional axes to display plot on """ - portfolio_returns, benchmark_returns = portfolio_model.get_monthly_returns( - portfolio, window - ) + portfolio_returns, benchmark_returns = get_monthly_returns(portfolio_engine, window) if raw: print_rich_table( @@ -469,7 +556,7 @@ def display_monthly_returns( @log_start_end(log=logger) def display_daily_returns( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", raw: bool = False, limit: int = 10, @@ -480,8 +567,9 @@ def display_daily_returns( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False @@ -494,7 +582,7 @@ def display_daily_returns( Optional axes to display plot on """ - df = portfolio_model.get_daily_returns(portfolio, window) + df = get_daily_returns(portfolio_engine, window) if raw: print_rich_table( @@ -537,7 +625,7 @@ def display_daily_returns( @log_start_end(log=logger) def display_distribution_returns( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", raw: bool = False, export: str = "", @@ -561,7 +649,7 @@ def display_distribution_returns( Optional axes to display plot on """ - df = portfolio_model.get_distribution_returns(portfolio, window) + df = get_distribution_returns(portfolio_engine, window) df_portfolio = df["portfolio"] df_benchmark = df["benchmark"] @@ -624,7 +712,7 @@ def display_distribution_returns( @log_start_end(log=logger) def display_holdings_value( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, unstack: bool = False, raw: bool = False, limit: int = 10, @@ -635,8 +723,9 @@ def display_holdings_value( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. unstack: bool Individual assets over time raw : bool @@ -649,7 +738,7 @@ def display_holdings_value( Optional axes to display plot on """ - all_holdings = portfolio_model.get_holdings_value(portfolio) + all_holdings = get_holdings_value(portfolio_engine) if raw: print_rich_table( @@ -702,7 +791,7 @@ def display_holdings_value( @log_start_end(log=logger) def display_holdings_percentage( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, unstack: bool = False, raw: bool = False, limit: int = 10, @@ -713,8 +802,9 @@ def display_holdings_percentage( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. unstack: bool Individual assets over time raw : bool @@ -727,7 +817,7 @@ def display_holdings_percentage( Optional axes to display plot on """ - all_holdings = portfolio_model.get_holdings_percentage(portfolio) + all_holdings = get_holdings_percentage(portfolio_engine) if raw: # No need to account for time since this is daily data @@ -785,7 +875,7 @@ def display_holdings_percentage( @log_start_end(log=logger) def display_rolling_volatility( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "1y", export: str = "", external_axes: Optional[List[plt.Axes]] = None, @@ -794,8 +884,8 @@ def display_rolling_volatility( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object interval: str interval for window to consider export: str @@ -805,7 +895,7 @@ def display_rolling_volatility( """ metric = "volatility" - df = portfolio_model.get_rolling_volatility(portfolio, window) + df = get_rolling_volatility(portfolio_engine, window) if df.empty: return @@ -841,7 +931,7 @@ def display_rolling_volatility( @log_start_end(log=logger) def display_rolling_sharpe( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, window: str = "1y", export: str = "", @@ -851,8 +941,8 @@ def display_rolling_sharpe( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object risk_free_rate: float Value to use for risk free rate in sharpe/other calculations window: str @@ -864,7 +954,7 @@ def display_rolling_sharpe( """ metric = "sharpe" - df = portfolio_model.get_rolling_sharpe(portfolio, risk_free_rate, window) + df = get_rolling_sharpe(portfolio_engine, risk_free_rate, window) if df.empty: return @@ -900,7 +990,7 @@ def display_rolling_sharpe( @log_start_end(log=logger) def display_rolling_sortino( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, window: str = "1y", export: str = "", @@ -910,8 +1000,8 @@ def display_rolling_sortino( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object risk_free_rate: float Value to use for risk free rate in sharpe/other calculations window: str @@ -923,7 +1013,7 @@ def display_rolling_sortino( """ metric = "sortino" - df = portfolio_model.get_rolling_sortino(portfolio, risk_free_rate, window) + df = get_rolling_sortino(portfolio_engine, risk_free_rate, window) if df.empty: return @@ -959,7 +1049,7 @@ def display_rolling_sortino( @log_start_end(log=logger) def display_rolling_beta( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "1y", export: str = "", external_axes: Optional[List[plt.Axes]] = None, @@ -968,8 +1058,8 @@ def display_rolling_beta( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object window: str interval for window to consider Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y. @@ -979,7 +1069,7 @@ def display_rolling_beta( Optional axes to display plot on """ - rolling_beta = portfolio_model.get_rolling_beta(portfolio, window) + rolling_beta = get_rolling_beta(portfolio_engine, window) if rolling_beta.empty: return @@ -1020,7 +1110,7 @@ def display_rolling_beta( @log_start_end(log=logger) def display_maximum_drawdown( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", external_axes: Optional[List[plt.Axes]] = None, ): @@ -1028,14 +1118,14 @@ def display_maximum_drawdown( Parameters ---------- - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object export: str Format to export data external_axes: plt.Axes Optional axes to display plot on """ - holdings, drawdown = portfolio_model.get_maximum_drawdown(portfolio) + holdings, drawdown = get_maximum_drawdown(portfolio_engine) if external_axes is None: _, ax = plt.subplots(2, 1, figsize=plot_autoscale(), dpi=PLOT_DPI, sharex=True) else: @@ -1065,20 +1155,21 @@ def display_maximum_drawdown( @log_start_end(log=logger) def display_rsquare( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display R-square Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_r2_score(portfolio).fillna("-") + df = get_r2_score(portfolio_engine).fillna("-") print_rich_table( df, @@ -1097,20 +1188,21 @@ def display_rsquare( @log_start_end(log=logger) def display_skewness( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display skewness Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_skewness(portfolio).fillna("-") + df = get_skewness(portfolio_engine).fillna("-") print_rich_table( df, @@ -1127,20 +1219,21 @@ def display_skewness( @log_start_end(log=logger) def display_kurtosis( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display kurtosis Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_kurtosis(portfolio).fillna("-") + df = get_kurtosis(portfolio_engine).fillna("-") print_rich_table( df, @@ -1157,7 +1250,7 @@ def display_kurtosis( @log_start_end(log=logger) def display_stats( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", export: str = "", ): @@ -1165,15 +1258,16 @@ def display_stats( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to consider. Choices are: mtd, qtd, ytd, 3m, 6m, 1y, 3y, 5y, 10y, all export : str Export data format """ - df = portfolio_model.get_stats(portfolio, window) + df = get_stats(portfolio_engine, window) print_rich_table( df, @@ -1190,19 +1284,21 @@ def display_stats( @log_start_end(log=logger) def display_volatility( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display volatility for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_volatility(portfolio).fillna("-") + + df = get_volatility(portfolio_engine).fillna("-") print_rich_table( df, title="Volatility for Portfolio and Benchmark", @@ -1216,7 +1312,7 @@ def display_volatility( @log_start_end(log=logger) def display_sharpe_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, export: str = "", ): @@ -1224,14 +1320,16 @@ def display_sharpe_ratio( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. risk_free_rate: float Risk free rate value export : str Export data format """ - df = portfolio_model.get_sharpe_ratio(portfolio, risk_free_rate).fillna("-") + + df = get_sharpe_ratio(portfolio_engine, risk_free_rate).fillna("-") print_rich_table( df, title="Sharpe ratio for Portfolio and Benchmark", @@ -1248,7 +1346,7 @@ def display_sharpe_ratio( @log_start_end(log=logger) def display_sortino_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, export: str = "", ): @@ -1256,14 +1354,16 @@ def display_sortino_ratio( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. risk_free_rate: float Risk free rate value export : str Export data format """ - df = portfolio_model.get_sortino_ratio(portfolio, risk_free_rate).fillna("-") + + df = get_sortino_ratio(portfolio_engine, risk_free_rate).fillna("-") print_rich_table( df, title="Sortino ratio for Portfolio and Benchmark", @@ -1280,19 +1380,21 @@ def display_sortino_ratio( @log_start_end(log=logger) def display_maximum_drawdown_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display maximum drawdown for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_maximum_drawdown_ratio(portfolio).fillna("-") + + df = get_maximum_drawdown_ratio(portfolio_engine).fillna("-") print_rich_table( df, title="Maximum drawdown for Portfolio and Benchmark", @@ -1306,19 +1408,20 @@ def display_maximum_drawdown_ratio( @log_start_end(log=logger) def display_gaintopain_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display gain-to-pain ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded export : str Export data format """ - df = portfolio_model.get_gaintopain_ratio(portfolio).fillna("-") + + df = get_gaintopain_ratio(portfolio_engine).fillna("-") print_rich_table( df, title="Gain-to-pain ratio for portfolio and benchmark", @@ -1335,19 +1438,20 @@ def display_gaintopain_ratio( @log_start_end(log=logger) def display_tracking_error( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display tracking error for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded export : str Export data format """ - df, _ = portfolio_model.get_tracking_error(portfolio) + + df, _ = get_tracking_error(portfolio_engine) df = df.fillna("-") print_rich_table( df, @@ -1362,19 +1466,20 @@ def display_tracking_error( @log_start_end(log=logger) def display_information_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display information ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded export : str Export data format """ - df = portfolio_model.get_information_ratio(portfolio).fillna("-") + + df = get_information_ratio(portfolio_engine).fillna("-") print_rich_table( df, title="Information ratio for portfolio", @@ -1391,21 +1496,22 @@ def display_information_ratio( @log_start_end(log=logger) def display_tail_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display tail ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded window: str interval for window to consider export : str Export data format """ - df, _, _ = portfolio_model.get_tail_ratio(portfolio) + + df, _, _ = get_tail_ratio(portfolio_engine) df = df.fillna("-") print_rich_table( df, @@ -1420,19 +1526,20 @@ def display_tail_ratio( @log_start_end(log=logger) def display_common_sense_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display common sense ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded export : str Export data format """ - df = portfolio_model.get_common_sense_ratio(portfolio).fillna("-") + + df = get_common_sense_ratio(portfolio_engine).fillna("-") print_rich_table( df, title="Common sense ratio for portfolio and benchmark", @@ -1449,7 +1556,7 @@ def display_common_sense_ratio( @log_start_end(log=logger) def display_jensens_alpha( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, risk_free_rate: float = 0, export: str = "", ): @@ -1457,14 +1564,15 @@ def display_jensens_alpha( Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded risk_free_rate: float Risk free rate export : str Export data format """ - df, _ = portfolio_model.get_jensens_alpha(portfolio, risk_free_rate) + + df, _ = get_jensens_alpha(portfolio_engine, risk_free_rate) df = df.fillna("-") print_rich_table( df, @@ -1479,19 +1587,20 @@ def display_jensens_alpha( @log_start_end(log=logger) def display_calmar_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display calmar ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with returns and benchmark loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with returns and benchmark loaded export : str Export data format """ - df, _ = portfolio_model.get_calmar_ratio(portfolio) + + df, _ = get_calmar_ratio(portfolio_engine) df = df.fillna("-") print_rich_table( df, @@ -1506,19 +1615,20 @@ def display_calmar_ratio( @log_start_end(log=logger) def display_kelly_criterion( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display kelly criterion for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with trades and returns loaded + portfolio_engine: PortfolioEngine + PortfolioEngine object with trades and returns loaded export : str Export data format """ - df = portfolio_model.get_kelly_criterion(portfolio).fillna("-") + + df = get_kelly_criterion(portfolio_engine).fillna("-") print_rich_table( df, title="Kelly criterion of the portfolio", @@ -1531,19 +1641,21 @@ def display_kelly_criterion( def display_payoff_ratio( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display payoff ratio for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_payoff_ratio(portfolio).fillna("-") + + df = get_payoff_ratio(portfolio_engine).fillna("-") print_rich_table( df, title="Portfolio's payoff ratio", @@ -1556,19 +1668,21 @@ def display_payoff_ratio( def display_profit_factor( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, export: str = "", ): """Display profit factor for multiple intervals Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. export : str Export data format """ - df = portfolio_model.get_profit_factor(portfolio).fillna("-") + + df = get_profit_factor(portfolio_engine).fillna("-") print_rich_table( df, title="Portfolio's profit factor", @@ -1582,7 +1696,7 @@ def display_profit_factor( @log_start_end(log=logger) def display_summary( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, window: str = "all", risk_free_rate: float = 0, export: str = "", @@ -1591,8 +1705,9 @@ def display_summary( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark risk_free_rate : float @@ -1600,8 +1715,8 @@ def display_summary( export : str Export certain type of data """ - summary = portfolio_model.get_summary(portfolio, window, risk_free_rate) + summary = get_summary(portfolio_engine, window, risk_free_rate) print_rich_table( summary, title=f"Summary of Portfolio vs Benchmark for {window} period", @@ -1618,7 +1733,7 @@ def display_summary( @log_start_end(log=logger) def display_var( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, use_mean: bool = True, adjusted_var: bool = False, student_t: bool = False, @@ -1628,8 +1743,9 @@ def display_var( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: bool if one should use the data mean return adjusted_var: bool @@ -1641,7 +1757,7 @@ def display_var( """ qa_view.display_var( - data=portfolio.returns, + data=portfolio_engine.returns, symbol="Portfolio", use_mean=use_mean, adjusted_var=adjusted_var, @@ -1653,7 +1769,7 @@ def display_var( @log_start_end(log=logger) def display_es( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, use_mean: bool = True, distribution: str = "normal", percentile: float = 99.9, @@ -1662,8 +1778,9 @@ def display_es( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: if one should use the data mean return distribution: str @@ -1673,7 +1790,7 @@ def display_es( """ qa_view.display_es( - data=portfolio.returns, + data=portfolio_engine.returns, symbol="Portfolio", use_mean=use_mean, distribution=distribution, @@ -1684,7 +1801,7 @@ def display_es( @log_start_end(log=logger) def display_omega( - portfolio: portfolio_model.PortfolioModel, + portfolio_engine: PortfolioEngine, threshold_start: float = 0, threshold_end: float = 1.5, ): @@ -1692,8 +1809,9 @@ def display_omega( Parameters ---------- - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. threshold_start: float annualized target return threshold start of plotted threshold range threshold_end: float @@ -1701,7 +1819,7 @@ def display_omega( """ qa_view.display_omega( - data=portfolio.returns, + data=portfolio_engine.returns, threshold_start=threshold_start, threshold_end=threshold_end, ) diff --git a/openbb_terminal/reports/templates/portfolio.ipynb b/openbb_terminal/reports/templates/portfolio.ipynb index bd38c5d74ed7..ce12b934970c 100644 --- a/openbb_terminal/reports/templates/portfolio.ipynb +++ b/openbb_terminal/reports/templates/portfolio.ipynb @@ -35,8 +35,7 @@ "\n", "from openbb_terminal.reports import widget_helpers as widgets\n", "from openbb_terminal.sdk import openbb\n", - "from openbb_terminal.sdk import openbb import helper\n", - "from openbb_terminal.sdk import openbb import Portfolio\n", + "from openbb_terminal.sdk import helper\n", "from openbb_terminal.helper_classes import TerminalStyle\n", "from openbb_terminal.core.config.paths import REPOSITORY_DIRECTORY\n", "\n", @@ -90,7 +89,7 @@ "source": [ "# Parameters that will be replaced when calling this notebook\n", "# Do not leave parameters blank as notebook will not run otherwise\n", - "transactions = \"Public_Equity_Orderbook.xlsx\"\n", + "transactions = \"market.csv\"\n", "report_name = \"Portfolio Report\"" ] }, @@ -138,11 +137,8 @@ "outputs": [], "source": [ "try:\n", - " transactions = Portfolio.read_transactions(transactions_path)\n", - " P = Portfolio(transactions)\n", - " P.generate_portfolio_data()\n", - " P.load_benchmark()\n", - " P.get_transactions()\n", + " P = openbb.portfolio.load(transactions_path)\n", + " openbb.portfolio.show(P)\n", "except ValueError:\n", " raise ValueError(\n", " \"Failed to load the transactions. Is this file inside the 'holdings' folder?\"\n", @@ -205,7 +201,7 @@ "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(11, 5), dpi=150)\n", - "openbb.portfolio.rsortino(P, chart=True, external_axes=[ax])\n", + "openbb.portfolio.rsort(P, chart=True, external_axes=[ax])\n", "\n", "fig.tight_layout()\n", "f = io.BytesIO()\n", @@ -236,19 +232,17 @@ "metadata": {}, "outputs": [], "source": [ - "P.calculate_allocations(\"country\")\n", + "country_allocation = openbb.portfolio.alloc.countries(P)\n", "\n", - "country_allocation = pd.DataFrame(\n", - " [P.portfolio_country_allocation, P.benchmark_country_allocation]\n", - ").T\n", - "country_allocation.columns = [\"Portfolio\", \"Benchmark\"]\n", - "country_allocation.fillna(\"-\", inplace=True)\n", "country_allocation[\"Portfolio\"] = (country_allocation[\"Portfolio\"] * 100).map(\n", " \"{:.3}%\".format\n", ")\n", "country_allocation[\"Benchmark\"] = (country_allocation[\"Benchmark\"] * 100).map(\n", " \"{:.3}%\".format\n", ")\n", + "country_allocation[\"Difference\"] = (country_allocation[\"Difference\"] * 100).map(\n", + " \"{:.3}pp\".format\n", + ")\n", "\n", "country_allocation" ] @@ -260,19 +254,17 @@ "metadata": {}, "outputs": [], "source": [ - "P.calculate_allocations(\"sector\")\n", + "sector_allocation = openbb.portfolio.alloc.sectors(P)\n", "\n", - "sector_allocation = pd.DataFrame(\n", - " [P.portfolio_sectors_allocation, P.benchmark_sectors_allocation]\n", - ").T\n", - "sector_allocation.columns = [\"Portfolio\", \"Benchmark\"]\n", - "sector_allocation.fillna(\"-\", inplace=True)\n", "sector_allocation[\"Portfolio\"] = (sector_allocation[\"Portfolio\"] * 100).map(\n", " \"{:.3}%\".format\n", ")\n", "sector_allocation[\"Benchmark\"] = (sector_allocation[\"Benchmark\"] * 100).map(\n", " \"{:.3}%\".format\n", ")\n", + "sector_allocation[\"Difference\"] = (sector_allocation[\"Difference\"] * 100).map(\n", + " \"{:.3}pp\".format\n", + ")\n", "\n", "sector_allocation" ] @@ -413,24 +405,24 @@ ")\n", "\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Tracking Error\") + openbb.portfolio.trackerr(P)[0].to_html()]\n", + " [widgets.h(3, \"Tracking Error\") + openbb.portfolio.metric.trackerr(P)[0].to_html()]\n", ")\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Information Ratio\") + openbb.portfolio.information(P).to_html()]\n", + " [widgets.h(3, \"Information Ratio\") + openbb.portfolio.metric.information(P).to_html()]\n", ")\n", "\n", "htmlcode += widgets.row([widgets.h(3, \"Beta Chart\") + beta_chart])\n", "\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Sharpe Ratio\") + openbb.portfolio.sharpe(P).to_html()]\n", + " [widgets.h(3, \"Sharpe Ratio\") + openbb.portfolio.metric.sharpe(P).to_html()]\n", ")\n", "htmlcode += widgets.row([widgets.h(3, \"Sharpe Ratio Chart\") + sharpe_chart])\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Volatility\") + openbb.portfolio.volatility(P).to_html()]\n", + " [widgets.h(3, \"Volatility\") + openbb.portfolio.metric.volatility(P).to_html()]\n", ")\n", "htmlcode += widgets.row([widgets.h(3, \"Volatility Chart\") + volatility_chart])\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Sortino Ratio\") + openbb.portfolio.sortino(P).to_html()]\n", + " [widgets.h(3, \"Sortino Ratio\") + openbb.portfolio.metric.sortino(P).to_html()]\n", ")\n", "htmlcode += widgets.row([widgets.h(3, \"Sortino Chart\") + sortino_chart])\n", "\n", @@ -443,12 +435,12 @@ "htmlcode = widgets.row([widgets.h(3, \"Distribution\") + distr_chart])\n", "htmlcode += widgets.row([widgets.h(3, \"Daily Returns\") + dret_chart])\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Volatility\") + openbb.portfolio.volatility(P).to_html()]\n", + " [widgets.h(3, \"Volatility\") + openbb.portfolio.metric.volatility(P).to_html()]\n", ")\n", "htmlcode += widgets.row(\n", - " [widgets.h(3, \"Kurtosis\") + openbb.portfolio.kurtosis(P).to_html()]\n", + " [widgets.h(3, \"Kurtosis\") + openbb.portfolio.metric.kurtosis(P).to_html()]\n", ")\n", - "htmlcode += widgets.row([widgets.h(3, \"Skew\") + openbb.portfolio.skew(P).to_html()])\n", + "htmlcode += widgets.row([widgets.h(3, \"Skew\") + openbb.portfolio.metric.skew(P).to_html()])\n", "htmlcode += widgets.row(\n", " [widgets.h(3, \"Value at Risk (VaR)\") + openbb.portfolio.var(P).to_html()]\n", ")\n", @@ -474,7 +466,7 @@ "metadata": { "celltoolbar": "Tags", "kernelspec": { - "display_name": "Python 3.10.4 ('obb')", + "display_name": "Python 3.9.13 ('obb')", "language": "python", "name": "python3" }, @@ -488,11 +480,11 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.9.13" }, "vscode": { "interpreter": { - "hash": "1a8cc6b6e60740679b24fc1ea93bdeb94d949a22102a80c99b7fd3f0d572afd6" + "hash": "e784374cc4f9a84ed6af2983247aaf351b155c82bcc2188134a65f3c99031000" } } }, diff --git a/openbb_terminal/sdk.py b/openbb_terminal/sdk.py index fd838fd1135f..913c9a41c697 100644 --- a/openbb_terminal/sdk.py +++ b/openbb_terminal/sdk.py @@ -3,9 +3,6 @@ from openbb_terminal.helper_classes import TerminalStyle from openbb_terminal import helper_funcs as helper # noqa: F401 from openbb_terminal.reports import widget_helpers as widgets # noqa: F401 -from openbb_terminal.portfolio.portfolio_model import ( # noqa: F401 - PortfolioModel as Portfolio, -) from openbb_terminal.cryptocurrency.due_diligence.pycoingecko_model import ( # noqa: F401 Coin, ) diff --git a/website/content/SDK/crypto/dd/active/_index.rst b/website/content/SDK/crypto/dd/active/_index.rst index 1d5b9292644e..2088b5531917 100644 --- a/website/content/SDK/crypto/dd/active/_index.rst +++ b/website/content/SDK/crypto/dd/active/_index.rst @@ -17,7 +17,7 @@ crypto.dd.active( symbol: str, interval: str = '24h', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -60,7 +60,7 @@ crypto.dd.active( crypto.dd.active( symbol: str, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', interval: str = '24h', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/dd/change/_index.rst b/website/content/SDK/crypto/dd/change/_index.rst index 627aecf0ccf1..191a3c983be6 100644 --- a/website/content/SDK/crypto/dd/change/_index.rst +++ b/website/content/SDK/crypto/dd/change/_index.rst @@ -17,7 +17,7 @@ crypto.dd.change( symbol: str, exchange: str = 'binance', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -61,7 +61,7 @@ crypto.dd.change( symbol: str, exchange: str = 'binance', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/crypto/dd/close/_index.rst b/website/content/SDK/crypto/dd/close/_index.rst index 4644b8e1ccb6..8d5f7cf75146 100644 --- a/website/content/SDK/crypto/dd/close/_index.rst +++ b/website/content/SDK/crypto/dd/close/_index.rst @@ -14,7 +14,7 @@ crypto.dd.close( symbol: str, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', print_errors: bool = True, chart: bool = False, ) -> pandas.core.frame.DataFrame diff --git a/website/content/SDK/crypto/dd/eb/_index.rst b/website/content/SDK/crypto/dd/eb/_index.rst index d11de6ae2c8e..89bd4fd7d345 100644 --- a/website/content/SDK/crypto/dd/eb/_index.rst +++ b/website/content/SDK/crypto/dd/eb/_index.rst @@ -17,7 +17,7 @@ crypto.dd.eb( symbol: str, exchange: str = 'binance', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -61,7 +61,7 @@ crypto.dd.eb( symbol: str, exchange: str = 'binance', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', percentage: bool = False, export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/dd/gh/_index.rst b/website/content/SDK/crypto/dd/gh/_index.rst index d360c1105d4a..3bcc379f76b5 100644 --- a/website/content/SDK/crypto/dd/gh/_index.rst +++ b/website/content/SDK/crypto/dd/gh/_index.rst @@ -17,8 +17,8 @@ crypto.dd.gh( symbol: str, dev_activity: bool = False, interval: str = '1d', - start_date: str = '2021-11-10T20:12:25Z', - end_date: str = '2022-11-10T20:12:25Z', + start_date: str = '2021-11-14T14:32:50Z', + end_date: str = '2022-11-14T14:32:50Z', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -63,9 +63,9 @@ crypto.dd.gh( {{< highlight python >}} crypto.dd.gh( symbol: str, - start_date: str = '2021-11-10T20:12:25Z', + start_date: str = '2021-11-14T14:32:50Z', dev_activity: bool = False, - end_date: str = '2022-11-10T20:12:25Z', + end_date: str = '2022-11-14T14:32:50Z', interval: str = '1d', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/dd/mcapdom/_index.rst b/website/content/SDK/crypto/dd/mcapdom/_index.rst index eed095de1c13..82285526b749 100644 --- a/website/content/SDK/crypto/dd/mcapdom/_index.rst +++ b/website/content/SDK/crypto/dd/mcapdom/_index.rst @@ -16,8 +16,8 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. crypto.dd.mcapdom( symbol: str, interval: str = '1d', - start_date: str = '2021-11-10', - end_date: str = '2022-11-10', + start_date: str = '2021-11-14', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -59,8 +59,8 @@ crypto.dd.mcapdom( {{< highlight python >}} crypto.dd.mcapdom( symbol: str, - start_date: str = '2021-11-10', - end_date: str = '2022-11-10', + start_date: str = '2021-11-14', + end_date: str = '2022-11-14', interval: str = '1d', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/dd/mt/_index.rst b/website/content/SDK/crypto/dd/mt/_index.rst index a83999212fb3..6d4c129e4360 100644 --- a/website/content/SDK/crypto/dd/mt/_index.rst +++ b/website/content/SDK/crypto/dd/mt/_index.rst @@ -17,8 +17,8 @@ crypto.dd.mt( symbol: str, timeseries_id: str, interval: str = '1d', - start_date: str = '2021-11-10', - end_date: str = '2022-11-10', + start_date: str = '2021-11-14', + end_date: str = '2022-11-14', chart: bool = False, ) -> Tuple[pandas.core.frame.DataFrame, str] {{< /highlight >}} @@ -65,8 +65,8 @@ crypto.dd.mt( crypto.dd.mt( symbol: str, timeseries_id: str, - start_date: str = '2021-11-10', - end_date: str = '2022-11-10', + start_date: str = '2021-11-14', + end_date: str = '2022-11-14', interval: str = '1d', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/dd/nonzero/_index.rst b/website/content/SDK/crypto/dd/nonzero/_index.rst index 940847ef3a7b..deed90bb61a4 100644 --- a/website/content/SDK/crypto/dd/nonzero/_index.rst +++ b/website/content/SDK/crypto/dd/nonzero/_index.rst @@ -16,7 +16,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. crypto.dd.nonzero( symbol: str, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -57,7 +57,7 @@ crypto.dd.nonzero( crypto.dd.nonzero( symbol: str, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/crypto/dd/oi/_index.rst b/website/content/SDK/crypto/dd/oi/_index.rst index 7c2ddbdd4510..1d0b0fdb8bae 100644 --- a/website/content/SDK/crypto/dd/oi/_index.rst +++ b/website/content/SDK/crypto/dd/oi/_index.rst @@ -73,7 +73,7 @@ crypto.dd.oi( interval : int Frequency (possible values are: 0 for ALL, 2 for 1H, 1 for 4H, 4 for 12H), by default 0 export : str - Export dataframe data to csv,json,xlsx fil + Export dataframe data to csv,json,xlsx file chart: bool Flag to display chart diff --git a/website/content/SDK/crypto/load/_index.rst b/website/content/SDK/crypto/load/_index.rst index c1784c7a945e..be774c025355 100644 --- a/website/content/SDK/crypto/load/_index.rst +++ b/website/content/SDK/crypto/load/_index.rst @@ -13,12 +13,10 @@ {{< highlight python >}} crypto.load( symbol: 'str', - start_date: 'Optional[Union[datetime, str]]' = None, - interval: 'str' = '1440', + start_date: 'datetime | str | None' = None, interval: 'str' = '1440', exchange: 'str' = 'binance', vs_currency: 'str' = 'usdt', - end_date: 'Optional[Union[datetime, str]]' = None, - source: 'str' = 'CCXT', + end_date: 'datetime | str | None' = None, source: 'str' = 'CCXT', chart: bool = False, ) -> 'pd.DataFrame' {{< /highlight >}} diff --git a/website/content/SDK/crypto/onchain/btc_supply/_index.rst b/website/content/SDK/crypto/onchain/btc_supply/_index.rst index 709447b6fa09..9efd666b7300 100644 --- a/website/content/SDK/crypto/onchain/btc_supply/_index.rst +++ b/website/content/SDK/crypto/onchain/btc_supply/_index.rst @@ -38,7 +38,7 @@ crypto.onchain.btc_supply() -> pandas.core.frame.DataFrame {{< highlight python >}} crypto.onchain.btc_supply( start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/crypto/onchain/btc_transac/_index.rst b/website/content/SDK/crypto/onchain/btc_transac/_index.rst index 558642af7c18..fa025f933550 100644 --- a/website/content/SDK/crypto/onchain/btc_transac/_index.rst +++ b/website/content/SDK/crypto/onchain/btc_transac/_index.rst @@ -38,7 +38,7 @@ crypto.onchain.btc_transac() -> pandas.core.frame.DataFrame {{< highlight python >}} crypto.onchain.btc_transac( start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/crypto/onchain/hr/_index.rst b/website/content/SDK/crypto/onchain/hr/_index.rst index b071a0485e37..329ab74d7977 100644 --- a/website/content/SDK/crypto/onchain/hr/_index.rst +++ b/website/content/SDK/crypto/onchain/hr/_index.rst @@ -17,7 +17,7 @@ crypto.onchain.hr( symbol: str, interval: str = '24h', start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -60,7 +60,7 @@ crypto.onchain.hr( crypto.onchain.hr( symbol: str, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', interval: str = '24h', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/crypto/ov/altindex/_index.rst b/website/content/SDK/crypto/ov/altindex/_index.rst index f3043fc27aec..f298ca86adba 100644 --- a/website/content/SDK/crypto/ov/altindex/_index.rst +++ b/website/content/SDK/crypto/ov/altindex/_index.rst @@ -16,7 +16,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. crypto.ov.altindex( period: int = 30, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -59,7 +59,7 @@ crypto.ov.altindex( crypto.ov.altindex( period: int = 365, start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/crypto/ov/btcrb/_index.rst b/website/content/SDK/crypto/ov/btcrb/_index.rst index beb41ecbcfde..b5528de7637d 100644 --- a/website/content/SDK/crypto/ov/btcrb/_index.rst +++ b/website/content/SDK/crypto/ov/btcrb/_index.rst @@ -15,7 +15,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} crypto.ov.btcrb( start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) {{< /highlight >}} @@ -49,7 +49,7 @@ crypto.ov.btcrb( {{< highlight python >}} crypto.ov.btcrb( start_date: str = '2010-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/economy/events/_index.rst b/website/content/SDK/economy/events/_index.rst index 16836a2e383f..1080059ba6e0 100644 --- a/website/content/SDK/economy/events/_index.rst +++ b/website/content/SDK/economy/events/_index.rst @@ -13,8 +13,8 @@ {{< highlight python >}} economy.events( countries: Union[List[str], str] = '', - start_date: str = '2022-11-10', - end_date: str = '2022-11-10', + start_date: str = '2022-11-14', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} diff --git a/website/content/SDK/economy/macro/_index.rst b/website/content/SDK/economy/macro/_index.rst index 8e9f0830adf7..4d8d2bbba38b 100644 --- a/website/content/SDK/economy/macro/_index.rst +++ b/website/content/SDK/economy/macro/_index.rst @@ -19,7 +19,7 @@ economy.macro( transform: str = '', start_date: str = '1900-01-01', end_date=datetime.date( - 2022, 11, 10, chart: bool = False, + 2022, 11, 14, chart: bool = False, ), symbol: str = '', chart: bool = False, ) -> Tuple[Any, Dict[Any, Dict[Any, Any]], str] @@ -72,7 +72,7 @@ economy.macro( countries: list = None, transform: str = '', start_date: str = '1900-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', symbol: str = '', raw: bool = False, external_axes: Optional[List[axes]] = None, diff --git a/website/content/SDK/economy/treasury/_index.rst b/website/content/SDK/economy/treasury/_index.rst index ef3949159b7f..f67d86a82a28 100644 --- a/website/content/SDK/economy/treasury/_index.rst +++ b/website/content/SDK/economy/treasury/_index.rst @@ -18,7 +18,7 @@ economy.treasury( maturities: list = None, frequency: str = 'monthly', start_date: str = '1900-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -65,7 +65,7 @@ economy.treasury( maturities: list = None, frequency: str = 'monthly', start_date: str = '1900-01-01', - end_date: str = '2022-11-10', + end_date: str = '2022-11-14', raw: bool = False, external_axes: Optional[List[axes]] = None, export: str = '', diff --git a/website/content/SDK/etf/candle/_index.rst b/website/content/SDK/etf/candle/_index.rst index fbd1746d544a..56ad7059297c 100644 --- a/website/content/SDK/etf/candle/_index.rst +++ b/website/content/SDK/etf/candle/_index.rst @@ -19,9 +19,9 @@ etf.candle( add_trend: bool = False, ma: Optional[Iterable[int]] = None, asset_type: str = '', - start_date: Union[datetime.datetime, str, NoneType] = '2019-11-06', + start_date: Union[datetime.datetime, str, NoneType] = '2019-11-10', interval: int = 1440, - end_date: Union[datetime.datetime, str, NoneType] = '2022-11-10', + end_date: Union[datetime.datetime, str, NoneType] = '2022-11-14', prepost: bool = False, source: str = 'YahooFinance', iexrange: str = 'ytd', diff --git a/website/content/SDK/etf/load/_index.rst b/website/content/SDK/etf/load/_index.rst index 971dd3eff1ff..724970c7f1b2 100644 --- a/website/content/SDK/etf/load/_index.rst +++ b/website/content/SDK/etf/load/_index.rst @@ -13,9 +13,9 @@ {{< highlight python >}} etf.load( symbol: str, - start_date: Union[datetime.datetime, str, NoneType] = '2019-11-06', + start_date: Union[datetime.datetime, str, NoneType] = '2019-11-10', interval: int = 1440, - end_date: Union[datetime.datetime, str, NoneType] = '2022-11-10', + end_date: Union[datetime.datetime, str, NoneType] = '2022-11-14', prepost: bool = False, source: str = 'YahooFinance', iexrange: str = 'ytd', diff --git a/website/content/SDK/etf/news/_index.rst b/website/content/SDK/etf/news/_index.rst index 77288c7903ec..12f1dfb226f2 100644 --- a/website/content/SDK/etf/news/_index.rst +++ b/website/content/SDK/etf/news/_index.rst @@ -16,7 +16,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. etf.news( query: str, limit: int = 10, - start_date: str = '2022-11-03', + start_date: str = '2022-11-07', show_newest: bool = True, sources: str = '', chart: bool = False, @@ -60,7 +60,7 @@ etf.news( etf.news( query: str, limit: int = 3, - start_date: str = '2022-11-03', + start_date: str = '2022-11-07', show_newest: bool = True, sources: str = '', export: str = '', diff --git a/website/content/SDK/forex/get_currency_list/_index.rst b/website/content/SDK/forex/get_currency_list/_index.rst index d3900f6c25f8..52f4987530e8 100644 --- a/website/content/SDK/forex/get_currency_list/_index.rst +++ b/website/content/SDK/forex/get_currency_list/_index.rst @@ -17,5 +17,5 @@ forex.get_currency_list() -> List .. raw:: html

- Load AV currency codes from a local file + Load AV currency codes from a local file.

diff --git a/website/content/SDK/forex/load/_index.rst b/website/content/SDK/forex/load/_index.rst index 655d20099719..f5ed31f71996 100644 --- a/website/content/SDK/forex/load/_index.rst +++ b/website/content/SDK/forex/load/_index.rst @@ -16,7 +16,7 @@ forex.load( from_symbol: str, resolution: str = 'd', interval: str = '1day', - start_date: str = '2021-11-10', + start_date: str = '2021-11-14', source: str = 'YahooFinance', verbose: bool = False, chart: bool = False, diff --git a/website/content/SDK/futures/historical/_index.rst b/website/content/SDK/futures/historical/_index.rst index 7e9f2210832a..1aaf400620a9 100644 --- a/website/content/SDK/futures/historical/_index.rst +++ b/website/content/SDK/futures/historical/_index.rst @@ -53,7 +53,7 @@ futures.historical( futures.historical( symbols: List[str], expiry: str = '', - start_date: str = '2019-11-11', + start_date: str = '2019-11-15', raw: bool = False, export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, diff --git a/website/content/SDK/portfolio/_index.md b/website/content/SDK/portfolio/_index.md index 3000aeb6e526..9a73484e311d 100644 --- a/website/content/SDK/portfolio/_index.md +++ b/website/content/SDK/portfolio/_index.md @@ -1,7 +1,7 @@ --- title: Introduction to Portfolio keywords: "portfolio, attribution, optimization, pnl, benchmark, return, volatility, metrics, broker, integration, report" -excerpt: "The Introduction to Portfolio explains how to use the +excerpt: "The Introduction to Portfolio explains how to use the menu and provides a brief description of its sub-menus" geekdocCollapseSection: true --- @@ -33,7 +33,7 @@ The SDK commands of the the menu: .portfolio.maxdd .portfolio.rvol .portfolio.rsharpe - .portfolio.rsortino + .portfolio.rsort .portfolio.rbeta .portfolio.summary .portfolio.skew @@ -50,7 +50,7 @@ in the following: from openbb_terminal.sdk import Portfolio # Define your own orderbook location here -orderbook_path = "Public_Equity_Orderbook.xlsx" +orderbook_path = "Public_Equity_Orderbook.xlsx" # Load in the transactions transactions = Portfolio.read_orderbook(orderbook_path) @@ -58,7 +58,7 @@ P = Portfolio(transactions) P.generate_portfolio_data() # Load in the benchmark, by default this is the SPY ETF -P.load_benchmark() +P.set_benchmark() ``` Note that the Excel sheet requires the following columns: @@ -134,7 +134,7 @@ takes a bit longer to load. from openbb_terminal.sdk import Portfolio # Define your own orderbook location here -orderbook_path = "Public_Equity_Orderbook_No_Categorization.xlsx" +orderbook_path = "Public_Equity_Orderbook_No_Categorization.xlsx" # Load in the transactions transactions = Portfolio.read_orderbook(orderbook_path) @@ -142,7 +142,7 @@ P = Portfolio(transactions) P.generate_portfolio_data() # Load in the benchmark, by default this is the SPY ETF -P.load_benchmark() +P.set_benchmark() ``` Then, we can show our performance compared to that of the benchmark. diff --git a/website/content/SDK/portfolio/alloc/_index.md b/website/content/SDK/portfolio/alloc/_index.md new file mode 100644 index 000000000000..754aa89dd96f --- /dev/null +++ b/website/content/SDK/portfolio/alloc/_index.md @@ -0,0 +1,6 @@ +--- +title: alloc +keywords: "" +excerpt: "" +geekdocCollapseSection: true +--- diff --git a/website/content/SDK/portfolio/alloc/assets/_index.rst b/website/content/SDK/portfolio/alloc/assets/_index.rst new file mode 100644 index 000000000000..bb1faf243cda --- /dev/null +++ b/website/content/SDK/portfolio/alloc/assets/_index.rst @@ -0,0 +1,52 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.alloc.assets( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + tables: bool = False, + limit: int = 10, + recalculate: bool = False, + chart: bool = False, +) -> Union[pandas.core.frame.DataFrame, Tuple[pandas.core.frame.DataFrame, pandas.core.frame.DataFrame, pandas.core.frame.DataFrame]] +{{< /highlight >}} + +.. raw:: html + +

+ Display portfolio asset allocation compared to the benchmark +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + +* **Returns** + + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.assets(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/alloc/countries/_index.rst b/website/content/SDK/portfolio/alloc/countries/_index.rst new file mode 100644 index 000000000000..51140335748a --- /dev/null +++ b/website/content/SDK/portfolio/alloc/countries/_index.rst @@ -0,0 +1,51 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.alloc.countries( + portfolio_engine=None, limit: int = 10, + tables: bool = False, + recalculate: bool = False, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Display portfolio country allocation compared to the benchmark +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + +* **Returns** + + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.countries(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/alloc/regions/_index.rst b/website/content/SDK/portfolio/alloc/regions/_index.rst new file mode 100644 index 000000000000..77dd8e32c8d6 --- /dev/null +++ b/website/content/SDK/portfolio/alloc/regions/_index.rst @@ -0,0 +1,51 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.alloc.regions( + portfolio_engine=None, limit: int = 10, + tables: bool = False, + recalculate: bool = False, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Display portfolio region allocation compared to the benchmark +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + +* **Returns** + + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.regions(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/alloc/sectors/_index.rst b/website/content/SDK/portfolio/alloc/sectors/_index.rst new file mode 100644 index 000000000000..cb28354fd26a --- /dev/null +++ b/website/content/SDK/portfolio/alloc/sectors/_index.rst @@ -0,0 +1,51 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.alloc.sectors( + portfolio_engine=None, limit: int = 10, + tables: bool = False, + recalculate: bool = False, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Display portfolio sector allocation compared to the benchmark +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + tables: bool + Whether to include separate allocation tables + limit: int + The amount of assets you wish to show, by default this is set to 10 + recalculate: bool + Flag to force recalculate allocation if already exists + +* **Returns** + + Union[pd.DataFrame, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]] + DataFrame with combined allocation plus individual allocation if tables is `True`. + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.alloc.sectors(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/bench/_index.rst b/website/content/SDK/portfolio/bench/_index.rst new file mode 100644 index 000000000000..7a943ff85072 --- /dev/null +++ b/website/content/SDK/portfolio/bench/_index.rst @@ -0,0 +1,44 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.bench( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + symbol: str, + full_shares: bool = False, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Load benchmark into portfolio +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine object + symbol: str + Benchmark symbol to download data + full_shares: bool + Whether to mimic the portfolio trades exactly (partial shares) or round down the + quantity to the nearest number + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.bench(P, symbol="SPY") + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/calmar/_index.rst b/website/content/SDK/portfolio/calmar/_index.rst deleted file mode 100644 index 10e515f4da7a..000000000000 --- a/website/content/SDK/portfolio/calmar/_index.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.calmar( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - window: int = 756, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Get calmar ratio -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - window: int - Interval used for rolling values - -* **Returns** - - pd.DataFrame - DataFrame of calmar ratio of the benchmark and portfolio during different time periods - pd.Series - Series of calmar ratio data diff --git a/website/content/SDK/portfolio/commonsense/_index.rst b/website/content/SDK/portfolio/commonsense/_index.rst deleted file mode 100644 index 74808b8e8a5c..000000000000 --- a/website/content/SDK/portfolio/commonsense/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.commonsense( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Get common sense ratio -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame of the portfolios and the benchmarks common sense ratio during different time periods diff --git a/website/content/SDK/portfolio/distr/_index.rst b/website/content/SDK/portfolio/distr/_index.rst index 1fe98accefd6..8ec59d03f3ae 100644 --- a/website/content/SDK/portfolio/distr/_index.rst +++ b/website/content/SDK/portfolio/distr/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.distr( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', chart: bool = False, ) @@ -28,14 +28,23 @@ portfolio.distr( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark chart: bool Flag to display chart +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.distr(P) + {{< /highlight >}} + | .. raw:: html @@ -46,7 +55,7 @@ portfolio.distr( {{< highlight python >}} portfolio.distr( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', raw: bool = False, export: str = '', diff --git a/website/content/SDK/portfolio/dret/_index.rst b/website/content/SDK/portfolio/dret/_index.rst index a4c7b1890e3b..52cbb0a25246 100644 --- a/website/content/SDK/portfolio/dret/_index.rst +++ b/website/content/SDK/portfolio/dret/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.dret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -28,8 +28,9 @@ portfolio.dret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark chart: bool @@ -39,6 +40,15 @@ portfolio.dret( * **Returns** pd.DataFrame + DataFrame with daily returns + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.dret(P) + {{< /highlight >}} | @@ -50,7 +60,7 @@ portfolio.dret( {{< highlight python >}} portfolio.dret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', raw: bool = False, limit: int = 10, @@ -68,8 +78,9 @@ portfolio.dret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False diff --git a/website/content/SDK/portfolio/es/_index.rst b/website/content/SDK/portfolio/es/_index.rst index 53341a81d3a2..c952b8684d39 100644 --- a/website/content/SDK/portfolio/es/_index.rst +++ b/website/content/SDK/portfolio/es/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} portfolio.es( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, use_mean: bool = False, distribution: str = 'normal', percentile: float = 99.9, @@ -28,8 +28,9 @@ portfolio.es( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: if one should use the data mean return distribution: str @@ -40,3 +41,12 @@ portfolio.es( * **Returns** pd.DataFrame + DataFrame with portfolio expected shortfall + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.es(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/gaintopain/_index.rst b/website/content/SDK/portfolio/gaintopain/_index.rst deleted file mode 100644 index 1b1445675ef6..000000000000 --- a/website/content/SDK/portfolio/gaintopain/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.gaintopain( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Get Pain-to-Gain ratio based on historical data -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame of the portfolio's gain-to-pain ratio diff --git a/website/content/SDK/portfolio/holdp/_index.rst b/website/content/SDK/portfolio/holdp/_index.rst index 4e48e5b5c765..d3ca3a64736f 100644 --- a/website/content/SDK/portfolio/holdp/_index.rst +++ b/website/content/SDK/portfolio/holdp/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.holdp( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, chart: bool = False, ) {{< /highlight >}} @@ -27,12 +27,21 @@ portfolio.holdp( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. chart: bool Flag to display chart +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.holdp(P) + {{< /highlight >}} + | .. raw:: html @@ -43,7 +52,7 @@ portfolio.holdp( {{< highlight python >}} portfolio.holdp( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, unstack: bool = False, raw: bool = False, limit: int = 10, @@ -61,8 +70,9 @@ portfolio.holdp( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. unstack: bool Individual assets over time raw : bool diff --git a/website/content/SDK/portfolio/holdv/_index.rst b/website/content/SDK/portfolio/holdv/_index.rst index bcc0c1489f84..b7abd742b057 100644 --- a/website/content/SDK/portfolio/holdv/_index.rst +++ b/website/content/SDK/portfolio/holdv/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.holdv( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -27,8 +27,9 @@ portfolio.holdv( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. chart: bool Flag to display chart @@ -38,6 +39,14 @@ portfolio.holdv( pd.DataFrame DataFrame of holdings +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.holdv(P) + {{< /highlight >}} + | .. raw:: html @@ -48,7 +57,7 @@ portfolio.holdv( {{< highlight python >}} portfolio.holdv( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, unstack: bool = False, raw: bool = False, limit: int = 10, @@ -66,8 +75,9 @@ portfolio.holdv( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. unstack: bool Individual assets over time raw : bool diff --git a/website/content/SDK/portfolio/information/_index.rst b/website/content/SDK/portfolio/information/_index.rst deleted file mode 100644 index c5bb7347dd5b..000000000000 --- a/website/content/SDK/portfolio/information/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.information( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Get information ratio -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame of the information ratio during different time periods diff --git a/website/content/SDK/portfolio/kelly/_index.rst b/website/content/SDK/portfolio/kelly/_index.rst deleted file mode 100644 index ea7fab686cd6..000000000000 --- a/website/content/SDK/portfolio/kelly/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.kelly( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Gets kelly criterion -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame of kelly criterion of the portfolio during different time periods diff --git a/website/content/SDK/portfolio/kurtosis/_index.rst b/website/content/SDK/portfolio/kurtosis/_index.rst deleted file mode 100644 index 41efd5a45463..000000000000 --- a/website/content/SDK/portfolio/kurtosis/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.kurtosis( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves kurtosis for portfolio and benchmark selected -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame with kurtosis for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/load/_index.rst b/website/content/SDK/portfolio/load/_index.rst new file mode 100644 index 000000000000..1f6afb11403a --- /dev/null +++ b/website/content/SDK/portfolio/load/_index.rst @@ -0,0 +1,51 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.load( + transactions_file_path: str, + benchmark_symbol: str = 'SPY', + full_shares: bool = False, + risk_free_rate: float = 0, + chart: bool = False, +) -> openbb_terminal.portfolio.portfolio_model.PortfolioEngine +{{< /highlight >}} + +.. raw:: html + +

+ Get PortfolioEngine object +

+ +* **Parameters** + + transactions_file_path : str + Path to transactions file + benchmark_symbol : str + Benchmark ticker to download data + full_shares : bool + Whether to mimic the portfolio trades exactly (partial shares) or round down the + quantity to the nearest number + risk_free_rate : float + Risk free rate in float format + +* **Returns** + + PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/max_drawdown_ratio/_index.rst b/website/content/SDK/portfolio/max_drawdown_ratio/_index.rst deleted file mode 100644 index 155f09468bed..000000000000 --- a/website/content/SDK/portfolio/max_drawdown_ratio/_index.rst +++ /dev/null @@ -1,79 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -To obtain charts, make sure to add :python:`chart = True` as the last parameter. - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.max_drawdown_ratio( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - is_returns: bool = False, - chart: bool = False, -) -> pandas.core.series.Series -{{< /highlight >}} - -.. raw:: html - -

- Calculate the drawdown (MDD) of historical series. Note that the calculation is done - on cumulative returns (or prices). The definition of drawdown is - - DD = (current value - rolling maximum) / rolling maximum -

- -* **Parameters** - - data: pd.Series - Series of input values - is_returns: bool - Flag to indicate inputs are returns - chart: bool - Flag to display chart - - -* **Returns** - - pd.Series - Holdings series - pd.Series - Drawdown series - -| - -.. raw:: html - -

- > Getting charts -

- -{{< highlight python >}} -portfolio.max_drawdown_ratio( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - export: str = '', - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Display maximum drawdown for multiple intervals -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - export : str - Export data format - chart: bool - Flag to display chart - diff --git a/website/content/SDK/portfolio/maxdd/_index.rst b/website/content/SDK/portfolio/maxdd/_index.rst index 36e2bc27d88f..5d8d61ffb7ed 100644 --- a/website/content/SDK/portfolio/maxdd/_index.rst +++ b/website/content/SDK/portfolio/maxdd/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.maxdd( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, is_returns: bool = False, chart: bool = False, ) -> pandas.core.series.Series @@ -46,6 +46,14 @@ portfolio.maxdd( pd.Series Drawdown series +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.maxdd(P) + {{< /highlight >}} + | .. raw:: html @@ -56,7 +64,7 @@ portfolio.maxdd( {{< highlight python >}} portfolio.maxdd( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, @@ -71,8 +79,8 @@ portfolio.maxdd( * **Parameters** - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object export: str Format to export data external_axes: plt.Axes diff --git a/website/content/SDK/portfolio/maxdrawdown/_index.rst b/website/content/SDK/portfolio/maxdrawdown/_index.rst deleted file mode 100644 index bb6c5e2e4b43..000000000000 --- a/website/content/SDK/portfolio/maxdrawdown/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.maxdrawdown( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves maximum drawdown ratio for portfolio and benchmark selected -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame with maximum drawdown for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/metric/_index.md b/website/content/SDK/portfolio/metric/_index.md new file mode 100644 index 000000000000..d55ad10c586f --- /dev/null +++ b/website/content/SDK/portfolio/metric/_index.md @@ -0,0 +1,6 @@ +--- +title: metric +keywords: "" +excerpt: "" +geekdocCollapseSection: true +--- diff --git a/website/content/SDK/portfolio/metric/calmar/_index.rst b/website/content/SDK/portfolio/metric/calmar/_index.rst new file mode 100644 index 000000000000..60511e2ef835 --- /dev/null +++ b/website/content/SDK/portfolio/metric/calmar/_index.rst @@ -0,0 +1,48 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.calmar( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + window: int = 756, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Get calmar ratio +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + window: int + Interval used for rolling values + +* **Returns** + + pd.DataFrame + DataFrame of calmar ratio of the benchmark and portfolio during different time periods + pd.Series + Series of calmar ratio data + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.calmar(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/commonsense/_index.rst b/website/content/SDK/portfolio/metric/commonsense/_index.rst new file mode 100644 index 000000000000..bd33934e741e --- /dev/null +++ b/website/content/SDK/portfolio/metric/commonsense/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.commonsense( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Get common sense ratio +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame of the portfolios and the benchmarks common sense ratio during different time periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.commonsense(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/gaintopain/_index.rst b/website/content/SDK/portfolio/metric/gaintopain/_index.rst new file mode 100644 index 000000000000..1cfa9afda0f6 --- /dev/null +++ b/website/content/SDK/portfolio/metric/gaintopain/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.gaintopain( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Get Pain-to-Gain ratio based on historical data +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame of the portfolio's gain-to-pain ratio + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.gaintopain(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/information/_index.rst b/website/content/SDK/portfolio/metric/information/_index.rst new file mode 100644 index 000000000000..9f8f7a315c94 --- /dev/null +++ b/website/content/SDK/portfolio/metric/information/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.information( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Get information ratio +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame of the information ratio during different time periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.information(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/jensens/_index.rst b/website/content/SDK/portfolio/metric/jensens/_index.rst similarity index 50% rename from website/content/SDK/portfolio/jensens/_index.rst rename to website/content/SDK/portfolio/metric/jensens/_index.rst index 7b86a21cf62d..3661be76ef24 100644 --- a/website/content/SDK/portfolio/jensens/_index.rst +++ b/website/content/SDK/portfolio/metric/jensens/_index.rst @@ -11,8 +11,8 @@ {{< highlight python >}} -portfolio.jensens( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, +portfolio.metric.jensens( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, risk_free_rate: float = 0, window: str = '1y', chart: bool = False, @@ -27,8 +27,9 @@ portfolio.jensens( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: str Interval used for rolling values risk_free_rate: float @@ -40,3 +41,11 @@ portfolio.jensens( DataFrame of jensens's alpha during different time windows pd.Series Series of jensens's alpha data + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.jensens(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/kelly/_index.rst b/website/content/SDK/portfolio/metric/kelly/_index.rst new file mode 100644 index 000000000000..b108eba6f384 --- /dev/null +++ b/website/content/SDK/portfolio/metric/kelly/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.kelly( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Gets kelly criterion +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame of kelly criterion of the portfolio during different time periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.kelly(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/kurtosis/_index.rst b/website/content/SDK/portfolio/metric/kurtosis/_index.rst new file mode 100644 index 000000000000..30243cfbf069 --- /dev/null +++ b/website/content/SDK/portfolio/metric/kurtosis/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.kurtosis( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves kurtosis for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame with kurtosis for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.kurtosis(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/maxdrawdown/_index.rst b/website/content/SDK/portfolio/metric/maxdrawdown/_index.rst new file mode 100644 index 000000000000..62ae7bed3171 --- /dev/null +++ b/website/content/SDK/portfolio/metric/maxdrawdown/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.maxdrawdown( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves maximum drawdown ratio for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame with maximum drawdown for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.maxdrawdown(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/payoff/_index.rst b/website/content/SDK/portfolio/metric/payoff/_index.rst new file mode 100644 index 000000000000..c11008305ec7 --- /dev/null +++ b/website/content/SDK/portfolio/metric/payoff/_index.rst @@ -0,0 +1,48 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.payoff( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Gets payoff ratio + + Returns + ------- + pd.DataFrame + DataFrame of payoff ratio of the portfolio during different time periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.payoff(P) +

+ +* **Returns** + + pd.DataFrame + DataFrame of payoff ratio of the portfolio during different time periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.payoff(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/profitfactor/_index.rst b/website/content/SDK/portfolio/metric/profitfactor/_index.rst new file mode 100644 index 000000000000..2858e21ee5e5 --- /dev/null +++ b/website/content/SDK/portfolio/metric/profitfactor/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.profitfactor( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Gets profit factor +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame of profit factor of the portfolio during different time periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.profitfactor(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/rsquare/_index.rst b/website/content/SDK/portfolio/metric/rsquare/_index.rst new file mode 100644 index 000000000000..6156e6e90d85 --- /dev/null +++ b/website/content/SDK/portfolio/metric/rsquare/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.rsquare( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves R2 Score for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame with R2 Score between portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.rsquare(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/sharpe/_index.rst b/website/content/SDK/portfolio/metric/sharpe/_index.rst new file mode 100644 index 000000000000..1e7891848389 --- /dev/null +++ b/website/content/SDK/portfolio/metric/sharpe/_index.rst @@ -0,0 +1,46 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.sharpe( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + risk_free_rate: float = 0, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves sharpe ratio for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + risk_free_rate: float + Risk free rate value + +* **Returns** + + pd.DataFrame + DataFrame with sharpe ratio for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.sharpe(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/skew/_index.rst b/website/content/SDK/portfolio/metric/skew/_index.rst new file mode 100644 index 000000000000..8d76238904cd --- /dev/null +++ b/website/content/SDK/portfolio/metric/skew/_index.rst @@ -0,0 +1,52 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.skew( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves skewness for portfolio and benchmark selected + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + + Returns + ------- + pd.DataFrame + DataFrame with skewness for portfolio and benchmark for different periods + + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.skew(P) +

+ +* **Returns** + + pd.DataFrame + DataFrame with skewness for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.skew(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/sortino/_index.rst b/website/content/SDK/portfolio/metric/sortino/_index.rst new file mode 100644 index 000000000000..134d422c4df2 --- /dev/null +++ b/website/content/SDK/portfolio/metric/sortino/_index.rst @@ -0,0 +1,46 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.sortino( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + risk_free_rate: float = 0, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves sortino ratio for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + risk_free_rate: float + Risk free rate value + +* **Returns** + + pd.DataFrame + DataFrame with sortino ratio for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.sortino(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/tail/_index.rst b/website/content/SDK/portfolio/metric/tail/_index.rst similarity index 52% rename from website/content/SDK/portfolio/tail/_index.rst rename to website/content/SDK/portfolio/metric/tail/_index.rst index bfc405e20d3f..1aebf1363cf5 100644 --- a/website/content/SDK/portfolio/tail/_index.rst +++ b/website/content/SDK/portfolio/metric/tail/_index.rst @@ -11,8 +11,8 @@ {{< highlight python >}} -portfolio.tail( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, +portfolio.metric.tail( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: int = 252, chart: bool = False, ) @@ -26,9 +26,9 @@ portfolio.tail( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded - + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window: int Interval used for rolling values @@ -40,3 +40,11 @@ portfolio.tail( Series of the portfolios rolling tail ratio pd.Series Series of the benchmarks rolling tail ratio + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.tail(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/trackerr/_index.rst b/website/content/SDK/portfolio/metric/trackerr/_index.rst new file mode 100644 index 000000000000..24205227e680 --- /dev/null +++ b/website/content/SDK/portfolio/metric/trackerr/_index.rst @@ -0,0 +1,48 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.trackerr( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + window: int = 252, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Get tracking error +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + window: int + Interval used for rolling values + +* **Returns** + + pd.DataFrame + DataFrame of tracking errors during different time windows + pd.Series + Series of rolling tracking error + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.trackerr(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/metric/volatility/_index.rst b/website/content/SDK/portfolio/metric/volatility/_index.rst new file mode 100644 index 000000000000..3f64a79e54e6 --- /dev/null +++ b/website/content/SDK/portfolio/metric/volatility/_index.rst @@ -0,0 +1,43 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.metric.volatility( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Method that retrieves volatility for portfolio and benchmark selected +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. + +* **Returns** + + pd.DataFrame + DataFrame with volatility for portfolio and benchmark for different periods + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.metric.volatility(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/mret/_index.rst b/website/content/SDK/portfolio/mret/_index.rst index d1784df3d7fd..6004058aff7a 100644 --- a/website/content/SDK/portfolio/mret/_index.rst +++ b/website/content/SDK/portfolio/mret/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.mret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -28,8 +28,9 @@ portfolio.mret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark chart: bool @@ -39,6 +40,15 @@ portfolio.mret( * **Returns** pd.DataFrame + DataFrame with monthly returns + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.mret(P) + {{< /highlight >}} | @@ -50,7 +60,7 @@ portfolio.mret( {{< highlight python >}} portfolio.mret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', raw: bool = False, show_vals: bool = False, @@ -68,8 +78,9 @@ portfolio.mret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False diff --git a/website/content/SDK/portfolio/om/_index.rst b/website/content/SDK/portfolio/om/_index.rst index 26fddd6593b1..e69bb74cbf7a 100644 --- a/website/content/SDK/portfolio/om/_index.rst +++ b/website/content/SDK/portfolio/om/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.om( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, threshold_start: float = 0, threshold_end: float = 1.5, chart: bool = False, @@ -29,8 +29,9 @@ portfolio.om( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. threshold_start: float annualized target return threshold start of plotted threshold range threshold_end: float @@ -42,6 +43,15 @@ portfolio.om( * **Returns** pd.DataFrame + DataFrame with portfolio omega ratio + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.om(P) + {{< /highlight >}} | @@ -53,7 +63,7 @@ portfolio.om( {{< highlight python >}} portfolio.om( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, threshold_start: float = 0, threshold_end: float = 1.5, chart: bool = False, @@ -68,8 +78,9 @@ portfolio.om( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. threshold_start: float annualized target return threshold start of plotted threshold range threshold_end: float diff --git a/website/content/SDK/portfolio/payoff/_index.rst b/website/content/SDK/portfolio/payoff/_index.rst deleted file mode 100644 index 1772a328f5fa..000000000000 --- a/website/content/SDK/portfolio/payoff/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.payoff( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Gets payoff ratio - - Returns - ------- - pd.DataFrame - DataFrame of payoff ratio of the portfolio during different time periods -

- -* **Returns** - - pd.DataFrame - DataFrame of payoff ratio of the portfolio during different time periods diff --git a/website/content/SDK/portfolio/perf/_index.rst b/website/content/SDK/portfolio/perf/_index.rst index 023bdd2d3ba8..2ef96c7701b4 100644 --- a/website/content/SDK/portfolio/perf/_index.rst +++ b/website/content/SDK/portfolio/perf/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} portfolio.perf( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, show_all_trades: bool = False, chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -26,11 +26,21 @@ portfolio.perf( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. show_all_trades: bool Whether to also show all trades made and their performance (default is False) * **Returns** pd.DataFrame + DataFrame with portfolio performance vs the benchmark + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.perf(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/profitfactor/_index.rst b/website/content/SDK/portfolio/profitfactor/_index.rst deleted file mode 100644 index b41440df5ebd..000000000000 --- a/website/content/SDK/portfolio/profitfactor/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.profitfactor( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Gets profit factor -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame of profit factor of the portfolio during different time periods diff --git a/website/content/SDK/portfolio/rbeta/_index.rst b/website/content/SDK/portfolio/rbeta/_index.rst index 440caafa2478..f86fed92b35e 100644 --- a/website/content/SDK/portfolio/rbeta/_index.rst +++ b/website/content/SDK/portfolio/rbeta/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.rbeta( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = '1y', chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -28,8 +28,8 @@ portfolio.rbeta( * **Parameters** - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object window: string Interval used for rolling values. Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y. @@ -42,6 +42,14 @@ portfolio.rbeta( pd.DataFrame DataFrame of the portfolio's rolling beta +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rbeta(P) + {{< /highlight >}} + | .. raw:: html @@ -52,7 +60,7 @@ portfolio.rbeta( {{< highlight python >}} portfolio.rbeta( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = '1y', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, @@ -68,8 +76,8 @@ portfolio.rbeta( * **Parameters** - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object window: str interval for window to consider Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y. diff --git a/website/content/SDK/portfolio/rsharpe/_index.rst b/website/content/SDK/portfolio/rsharpe/_index.rst index 18a4e2c7f93d..72338e388658 100644 --- a/website/content/SDK/portfolio/rsharpe/_index.rst +++ b/website/content/SDK/portfolio/rsharpe/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.rsharpe( - portfolio: pandas.core.frame.DataFrame, + portfolio_engine: pandas.core.frame.DataFrame, risk_free_rate: float = 0, window: str = '1y', chart: bool = False, @@ -45,6 +45,14 @@ portfolio.rsharpe( pd.DataFrame Rolling sharpe ratio DataFrame +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rsharpe(P) + {{< /highlight >}} + | .. raw:: html @@ -55,7 +63,7 @@ portfolio.rsharpe( {{< highlight python >}} portfolio.rsharpe( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, risk_free_rate: float = 0, window: str = '1y', export: str = '', @@ -72,8 +80,8 @@ portfolio.rsharpe( * **Parameters** - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object risk_free_rate: float Value to use for risk free rate in sharpe/other calculations window: str diff --git a/website/content/SDK/portfolio/rsort/_index.rst b/website/content/SDK/portfolio/rsort/_index.rst new file mode 100644 index 000000000000..1d767bbb7f0d --- /dev/null +++ b/website/content/SDK/portfolio/rsort/_index.rst @@ -0,0 +1,95 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +To obtain charts, make sure to add :python:`chart = True` as the last parameter. + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.rsort( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + risk_free_rate: float = 0, + window: str = '1y', + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Get rolling sortino +

+ +* **Parameters** + + portfolio : PortfolioEngine + PortfolioEngine object + window: str + interval for window to consider + Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y + risk_free_rate: float + Value to use for risk free rate in sharpe/other calculations + chart: bool + Flag to display chart + + +* **Returns** + + pd.DataFrame + Rolling sortino ratio DataFrame + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rsortino(P) + {{< /highlight >}} + +| + +.. raw:: html + +

+ > Getting charts +

+ +{{< highlight python >}} +portfolio.rsort( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + risk_free_rate: float = 0, + window: str = '1y', + export: str = '', + external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, + chart: bool = False, +) +{{< /highlight >}} + +.. raw:: html + +

+ Display rolling sortino +

+ +* **Parameters** + + portfolio : PortfolioEngine + PortfolioEngine object + risk_free_rate: float + Value to use for risk free rate in sharpe/other calculations + window: str + interval for window to consider + export: str + Export to file + external_axes: Optional[List[plt.Axes]] + Optional axes to display plot on + chart: bool + Flag to display chart + diff --git a/website/content/SDK/portfolio/rsortino/_index.rst b/website/content/SDK/portfolio/rsortino/_index.rst index 7ce79ba1534f..5c50e133218e 100644 --- a/website/content/SDK/portfolio/rsortino/_index.rst +++ b/website/content/SDK/portfolio/rsortino/_index.rst @@ -13,8 +13,8 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} -portfolio.rsortino( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, +portfolio.rsort( + portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, risk_free_rate: float = 0, window: str = '1y', chart: bool = False, @@ -29,7 +29,7 @@ portfolio.rsortino( * **Parameters** - portfolio : PortfolioModel + portfolio : PortfolioEngine Portfolio object window: str interval for window to consider @@ -54,8 +54,8 @@ portfolio.rsortino( {{< highlight python >}} -portfolio.rsortino( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, +portfolio.rsort( + portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, risk_free_rate: float = 0, window: str = '1y', export: str = '', @@ -72,7 +72,7 @@ portfolio.rsortino( * **Parameters** - portfolio : PortfolioModel + portfolio : PortfolioEngine Portfolio object risk_free_rate: float Value to use for risk free rate in sharpe/other calculations @@ -84,4 +84,3 @@ portfolio.rsortino( Optional axes to display plot on chart: bool Flag to display chart - diff --git a/website/content/SDK/portfolio/rsquare/_index.rst b/website/content/SDK/portfolio/rsquare/_index.rst index 728f36754f97..1b897089119e 100644 --- a/website/content/SDK/portfolio/rsquare/_index.rst +++ b/website/content/SDK/portfolio/rsquare/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} portfolio.rsquare( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} diff --git a/website/content/SDK/portfolio/rvol/_index.rst b/website/content/SDK/portfolio/rvol/_index.rst index d9686bb7c597..417289547b20 100644 --- a/website/content/SDK/portfolio/rvol/_index.rst +++ b/website/content/SDK/portfolio/rvol/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.rvol( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = '1y', chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -28,8 +28,9 @@ portfolio.rvol( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str Rolling window size to use Possible options: mtd, qtd, ytd, 1d, 5d, 10d, 1m, 3m, 6m, 1y, 3y, 5y, 10y @@ -37,6 +38,14 @@ portfolio.rvol( Flag to display chart +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.rvol(P) + {{< /highlight >}} + | .. raw:: html @@ -47,7 +56,7 @@ portfolio.rvol( {{< highlight python >}} portfolio.rvol( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = '1y', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, @@ -63,8 +72,8 @@ portfolio.rvol( * **Parameters** - portfolio : PortfolioModel - Portfolio object + portfolio : PortfolioEngine + PortfolioEngine object interval: str interval for window to consider export: str diff --git a/website/content/SDK/portfolio/sharpe/_index.rst b/website/content/SDK/portfolio/sharpe/_index.rst deleted file mode 100644 index f54860ab8b26..000000000000 --- a/website/content/SDK/portfolio/sharpe/_index.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.sharpe( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - risk_free_rate: float = 0, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves sharpe ratio for portfolio and benchmark selected -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - risk_free_rate: float - Risk free rate value - -* **Returns** - - pd.DataFrame - DataFrame with sharpe ratio for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/show/_index.rst b/website/content/SDK/portfolio/show/_index.rst new file mode 100644 index 000000000000..7cd8c86593b5 --- /dev/null +++ b/website/content/SDK/portfolio/show/_index.rst @@ -0,0 +1,42 @@ +.. role:: python(code) + :language: python + :class: highlight + +| + +.. raw:: html + +

+ > Getting data +

+ +{{< highlight python >}} +portfolio.show( + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, + chart: bool = False, +) -> pandas.core.frame.DataFrame +{{< /highlight >}} + +.. raw:: html + +

+ Get portfolio transactions +

+ +* **Parameters** + + portfolio_engine: PortfolioEngine + PortfolioEngine object + +* **Returns** + + pd.DataFrame + Portfolio transactions + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.show(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/skew/_index.rst b/website/content/SDK/portfolio/skew/_index.rst deleted file mode 100644 index 63010b46fe5a..000000000000 --- a/website/content/SDK/portfolio/skew/_index.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.skew( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves skewness for portfolio and benchmark selected - - portfolio: Portfolio - Portfolio object with trades loaded - - Returns - ------- - pd.DataFrame - DataFrame with skewness for portfolio and benchmark for different periods -

- -* **Returns** - - pd.DataFrame - DataFrame with skewness for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/sortino/_index.rst b/website/content/SDK/portfolio/sortino/_index.rst deleted file mode 100644 index 3ce251e66d11..000000000000 --- a/website/content/SDK/portfolio/sortino/_index.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.sortino( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - risk_free_rate: float = 0, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves sortino ratio for portfolio and benchmark selected -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - risk_free_rate: float - Risk free rate value - -* **Returns** - - pd.DataFrame - DataFrame with sortino ratio for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/summary/_index.rst b/website/content/SDK/portfolio/summary/_index.rst index fad9c2b55829..a13cf58c1989 100644 --- a/website/content/SDK/portfolio/summary/_index.rst +++ b/website/content/SDK/portfolio/summary/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} portfolio.summary( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', risk_free_rate: float = 0, chart: bool = False, @@ -22,13 +22,14 @@ portfolio.summary( .. raw:: html

- Get summary portfolio and benchmark returns + Get portfolio and benchmark returns summary

* **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark risk_free_rate : float @@ -37,3 +38,12 @@ portfolio.summary( * **Returns** pd.DataFrame + DataFrame with portfolio and benchmark returns summary + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.summary(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/trackerr/_index.rst b/website/content/SDK/portfolio/trackerr/_index.rst deleted file mode 100644 index 762631172779..000000000000 --- a/website/content/SDK/portfolio/trackerr/_index.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.trackerr( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - window: int = 252, - chart: bool = False, -) -{{< /highlight >}} - -.. raw:: html - -

- Get tracking error -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - window: int - Interval used for rolling values - -* **Returns** - - pd.DataFrame - DataFrame of tracking errors during different time windows - pd.Series - Series of rolling tracking error diff --git a/website/content/SDK/portfolio/var/_index.rst b/website/content/SDK/portfolio/var/_index.rst index fb91b8ab21d3..b22b147ffe18 100644 --- a/website/content/SDK/portfolio/var/_index.rst +++ b/website/content/SDK/portfolio/var/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} portfolio.var( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, use_mean: bool = False, adjusted_var: bool = False, student_t: bool = False, @@ -29,8 +29,9 @@ portfolio.var( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. use_mean: bool if one should use the data mean return adjusted_var: bool @@ -43,3 +44,12 @@ portfolio.var( * **Returns** pd.DataFrame + DataFrame with portfolio VaR + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.var(P) + {{< /highlight >}} diff --git a/website/content/SDK/portfolio/volatility/_index.rst b/website/content/SDK/portfolio/volatility/_index.rst deleted file mode 100644 index 8b369c64f1c3..000000000000 --- a/website/content/SDK/portfolio/volatility/_index.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: python(code) - :language: python - :class: highlight - -| - -.. raw:: html - -

- > Getting data -

- -{{< highlight python >}} -portfolio.volatility( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, - chart: bool = False, -) -> pandas.core.frame.DataFrame -{{< /highlight >}} - -.. raw:: html - -

- Class method that retrieves volatility for portfolio and benchmark selected -

- -* **Parameters** - - portfolio: Portfolio - Portfolio object with trades loaded - -* **Returns** - - pd.DataFrame - DataFrame with volatility for portfolio and benchmark for different periods diff --git a/website/content/SDK/portfolio/yret/_index.rst b/website/content/SDK/portfolio/yret/_index.rst index b34cac2e2e2b..c42e2b84a6ea 100644 --- a/website/content/SDK/portfolio/yret/_index.rst +++ b/website/content/SDK/portfolio/yret/_index.rst @@ -14,10 +14,10 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} portfolio.yret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', chart: bool = False, -) +) -> pandas.core.frame.DataFrame {{< /highlight >}} .. raw:: html @@ -28,14 +28,28 @@ portfolio.yret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark chart: bool Flag to display chart +* **Returns** + + pd.DataFrame + DataFrame with yearly returns + +* **Examples** + + {{< highlight python >}} + >>> from openbb_terminal.sdk import openbb + >>> P = openbb.portfolio.load("openbb_terminal/miscellaneous/portfolio_examples/holdings/example.csv") + >>> openbb.portfolio.yret(P) + {{< /highlight >}} + | .. raw:: html @@ -46,7 +60,7 @@ portfolio.yret( {{< highlight python >}} portfolio.yret( - portfolio: openbb_terminal.portfolio.portfolio_model.PortfolioModel, + portfolio_engine: openbb_terminal.portfolio.portfolio_model.PortfolioEngine, window: str = 'all', raw: bool = False, export: str = '', @@ -63,8 +77,9 @@ portfolio.yret( * **Parameters** - portfolio: Portfolio - Portfolio object with trades loaded + portfolio_engine: PortfolioEngine + PortfolioEngine class instance, this will hold transactions and perform calculations. + Use `portfolio.load` to create a PortfolioEngine. window : str interval to compare cumulative returns and benchmark raw : False diff --git a/website/content/SDK/stocks/ba/cnews/_index.rst b/website/content/SDK/stocks/ba/cnews/_index.rst index 1c1cb537c33b..9ee3fb2200b0 100644 --- a/website/content/SDK/stocks/ba/cnews/_index.rst +++ b/website/content/SDK/stocks/ba/cnews/_index.rst @@ -13,8 +13,8 @@ {{< highlight python >}} stocks.ba.cnews( symbol: str, - start_date: str = '2022-10-11', - end_date: str = '2022-11-10', + start_date: str = '2022-10-15', + end_date: str = '2022-11-14', chart: bool = False, ) -> List[Dict] {{< /highlight >}} diff --git a/website/content/SDK/stocks/ba/hist/_index.rst b/website/content/SDK/stocks/ba/hist/_index.rst index a269fea4275f..0213c933325f 100644 --- a/website/content/SDK/stocks/ba/hist/_index.rst +++ b/website/content/SDK/stocks/ba/hist/_index.rst @@ -15,8 +15,8 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.ba.hist( symbol: str, - start_date: str = '2022-11-03', - end_date: str = '2022-11-10', + start_date: str = '2022-11-07', + end_date: str = '2022-11-14', number: int = 100, chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -61,8 +61,8 @@ stocks.ba.hist( {{< highlight python >}} stocks.ba.hist( symbol: str, - start_date: str = '2022-11-03', - end_date: str = '2022-11-10', + start_date: str = '2022-11-07', + end_date: str = '2022-11-14', number: int = 100, raw: bool = False, limit: int = 10, diff --git a/website/content/SDK/stocks/ba/trend/_index.rst b/website/content/SDK/stocks/ba/trend/_index.rst index 9a87c9b81e87..ecd8834d51d1 100644 --- a/website/content/SDK/stocks/ba/trend/_index.rst +++ b/website/content/SDK/stocks/ba/trend/_index.rst @@ -14,7 +14,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.ba.trend( - start_date: str = '2022-11-10', + start_date: str = '2022-11-14', hour: int = 0, number: int = 10, chart: bool = False, @@ -58,7 +58,7 @@ stocks.ba.trend( {{< highlight python >}} stocks.ba.trend( - start_date: str = '2022-11-10', + start_date: str = '2022-11-14', hour: int = 0, number: int = 10, limit: int = 10, diff --git a/website/content/SDK/stocks/ca/hcorr/_index.rst b/website/content/SDK/stocks/ca/hcorr/_index.rst index 97e905431783..e8080cd9f22f 100644 --- a/website/content/SDK/stocks/ca/hcorr/_index.rst +++ b/website/content/SDK/stocks/ca/hcorr/_index.rst @@ -15,7 +15,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.ca.hcorr( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', candle_type: str = 'a', chart: bool = False, ) @@ -52,7 +52,7 @@ stocks.ca.hcorr( {{< highlight python >}} stocks.ca.hcorr( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', candle_type: str = 'a', display_full_matrix: bool = False, raw: bool = False, diff --git a/website/content/SDK/stocks/ca/hist/_index.rst b/website/content/SDK/stocks/ca/hist/_index.rst index 1b25bfa16ef8..97fe03576ca3 100644 --- a/website/content/SDK/stocks/ca/hist/_index.rst +++ b/website/content/SDK/stocks/ca/hist/_index.rst @@ -15,7 +15,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.ca.hist( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', candle_type: str = 'a', chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -57,7 +57,7 @@ stocks.ca.hist( {{< highlight python >}} stocks.ca.hist( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', candle_type: str = 'a', normalize: bool = True, export: str = '', diff --git a/website/content/SDK/stocks/ca/volume/_index.rst b/website/content/SDK/stocks/ca/volume/_index.rst index d2c39fcdd024..88c013fcc749 100644 --- a/website/content/SDK/stocks/ca/volume/_index.rst +++ b/website/content/SDK/stocks/ca/volume/_index.rst @@ -15,7 +15,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.ca.volume( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -49,7 +49,7 @@ stocks.ca.volume( {{< highlight python >}} stocks.ca.volume( similar: List[str], - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/stocks/candle/_index.rst b/website/content/SDK/stocks/candle/_index.rst index 59901a1afa40..d40fe8a60ad0 100644 --- a/website/content/SDK/stocks/candle/_index.rst +++ b/website/content/SDK/stocks/candle/_index.rst @@ -19,9 +19,9 @@ stocks.candle( add_trend: bool = False, ma: Optional[Iterable[int]] = None, asset_type: str = '', - start_date: Union[datetime.datetime, str, NoneType] = '2019-11-06', + start_date: Union[datetime.datetime, str, NoneType] = '2019-11-10', interval: int = 1440, - end_date: Union[datetime.datetime, str, NoneType] = '2022-11-10', + end_date: Union[datetime.datetime, str, NoneType] = '2022-11-14', prepost: bool = False, source: str = 'YahooFinance', iexrange: str = 'ytd', diff --git a/website/content/SDK/stocks/dd/pt/_index.rst b/website/content/SDK/stocks/dd/pt/_index.rst index 0ff3cc2a16ae..09360df65521 100644 --- a/website/content/SDK/stocks/dd/pt/_index.rst +++ b/website/content/SDK/stocks/dd/pt/_index.rst @@ -50,7 +50,7 @@ stocks.dd.pt( stocks.dd.pt( symbol: str, data: pandas.core.frame.DataFrame, - start_date: str = '2022-11-10', + start_date: str = '2022-11-14', limit: int = 10, raw: bool = False, export: str = '', diff --git a/website/content/SDK/stocks/disc/dividends/_index.rst b/website/content/SDK/stocks/disc/dividends/_index.rst index b0e5c32a57e1..50e8bfd2b20d 100644 --- a/website/content/SDK/stocks/disc/dividends/_index.rst +++ b/website/content/SDK/stocks/disc/dividends/_index.rst @@ -12,7 +12,7 @@ {{< highlight python >}} stocks.disc.dividends( - date: str = '2022-11-10', + date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} diff --git a/website/content/SDK/stocks/disc/ipo/_index.rst b/website/content/SDK/stocks/disc/ipo/_index.rst index 40c39f95e467..f45dc14802be 100644 --- a/website/content/SDK/stocks/disc/ipo/_index.rst +++ b/website/content/SDK/stocks/disc/ipo/_index.rst @@ -12,8 +12,8 @@ {{< highlight python >}} stocks.disc.ipo( - start_date: str = '2022-11-05', - end_date: str = '2022-11-10', + start_date: str = '2022-11-09', + end_date: str = '2022-11-14', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} diff --git a/website/content/SDK/stocks/dps/ftd/_index.rst b/website/content/SDK/stocks/dps/ftd/_index.rst index 8d31c0231253..72516c9fdd45 100644 --- a/website/content/SDK/stocks/dps/ftd/_index.rst +++ b/website/content/SDK/stocks/dps/ftd/_index.rst @@ -15,8 +15,8 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.dps.ftd( symbol: str, - start_date: str = '2022-09-11', - end_date: str = '2022-11-10', + start_date: str = '2022-09-15', + end_date: str = '2022-11-14', limit: int = 0, chart: bool = False, ) -> pandas.core.frame.DataFrame @@ -59,8 +59,8 @@ stocks.dps.ftd( stocks.dps.ftd( symbol: str, data: pandas.core.frame.DataFrame, - start_date: str = '2022-09-11', - end_date: str = '2022-11-10', + start_date: str = '2022-09-15', + end_date: str = '2022-11-14', limit: int = 0, raw: bool = False, export: str = '', diff --git a/website/content/SDK/stocks/fa/mktcap/_index.rst b/website/content/SDK/stocks/fa/mktcap/_index.rst index ff59eac27581..ac33ebb82e51 100644 --- a/website/content/SDK/stocks/fa/mktcap/_index.rst +++ b/website/content/SDK/stocks/fa/mktcap/_index.rst @@ -15,7 +15,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. {{< highlight python >}} stocks.fa.mktcap( symbol: str, - start_date: str = '2019-11-08', + start_date: str = '2019-11-12', chart: bool = False, ) -> Tuple[pandas.core.frame.DataFrame, str] {{< /highlight >}} @@ -54,7 +54,7 @@ stocks.fa.mktcap( {{< highlight python >}} stocks.fa.mktcap( symbol: str, - start_date: str = '2019-11-08', + start_date: str = '2019-11-12', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/stocks/ins/act/_index.rst b/website/content/SDK/stocks/ins/act/_index.rst index eb806443c39b..f32f0de270c6 100644 --- a/website/content/SDK/stocks/ins/act/_index.rst +++ b/website/content/SDK/stocks/ins/act/_index.rst @@ -50,7 +50,7 @@ stocks.ins.act( stocks.ins.act( data: pandas.core.frame.DataFrame, symbol: str, - start_date: str = '2019-11-06', + start_date: str = '2019-11-10', interval: str = '1440min', limit: int = 10, raw: bool = False, diff --git a/website/content/SDK/stocks/load/_index.rst b/website/content/SDK/stocks/load/_index.rst index 3b8e9fe73e56..93a3f6319cec 100644 --- a/website/content/SDK/stocks/load/_index.rst +++ b/website/content/SDK/stocks/load/_index.rst @@ -13,9 +13,9 @@ {{< highlight python >}} stocks.load( symbol: str, - start_date: Union[datetime.datetime, str, NoneType] = '2019-11-06', + start_date: Union[datetime.datetime, str, NoneType] = '2019-11-10', interval: int = 1440, - end_date: Union[datetime.datetime, str, NoneType] = '2022-11-10', + end_date: Union[datetime.datetime, str, NoneType] = '2022-11-14', prepost: bool = False, source: str = 'YahooFinance', iexrange: str = 'ytd', diff --git a/website/content/SDK/stocks/options/pcr/_index.rst b/website/content/SDK/stocks/options/pcr/_index.rst index 80cd448b8066..e6fc4a5dc965 100644 --- a/website/content/SDK/stocks/options/pcr/_index.rst +++ b/website/content/SDK/stocks/options/pcr/_index.rst @@ -16,7 +16,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. stocks.options.pcr( symbol: str, window: int = 30, - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', chart: bool = False, ) -> pandas.core.frame.DataFrame {{< /highlight >}} @@ -51,7 +51,7 @@ stocks.options.pcr( stocks.options.pcr( symbol: str, window: int = 30, - start_date: str = '2021-11-09', + start_date: str = '2021-11-13', export: str = '', external_axes: Optional[List[matplotlib.axes._axes.Axes]] = None, chart: bool = False, diff --git a/website/content/SDK/stocks/screener/historical/_index.rst b/website/content/SDK/stocks/screener/historical/_index.rst index a6ee8cb61c2b..bd2c8c1b332d 100644 --- a/website/content/SDK/stocks/screener/historical/_index.rst +++ b/website/content/SDK/stocks/screener/historical/_index.rst @@ -16,7 +16,7 @@ To obtain charts, make sure to add :python:`chart = True` as the last parameter. stocks.screener.historical( preset_loaded: str = 'top_gainers', limit: int = 10, - start_date: str = '2022-05-14', + start_date: str = '2022-05-18', type_candle: str = 'a', normalize: bool = True, chart: bool = False, @@ -66,7 +66,7 @@ stocks.screener.historical( stocks.screener.historical( preset_loaded: str = 'top_gainers', limit: int = 10, - start_date: str = '2022-05-14', + start_date: str = '2022-05-18', type_candle: str = 'a', normalize: bool = True, export: str = '', diff --git a/website/content/terminal/portfolio/perf/_index.md b/website/content/terminal/portfolio/perf/_index.md index 393aaf160b36..02e32475d840 100644 --- a/website/content/terminal/portfolio/perf/_index.md +++ b/website/content/terminal/portfolio/perf/_index.md @@ -29,7 +29,7 @@ Example: Portfolio vs. Benchmark - Individual Trades ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓ -┃ Date ┃ Name ┃ Portfolio Value ┃ % Portfolio Return ┃ Benchmark Value ┃ % Benchmark Return ┃ Alpha ┃ +┃ Date ┃ Name ┃ Portfolio Value ┃ Portfolio % Return ┃ Benchmark Value ┃ % Benchmark Return ┃ Alpha ┃ ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩ │ 2010-05-03 00:00:00 │ CASH │ 0.00e+00 │ 0.00e+00 │ 0.00e+00 │ 0.00e+00 │ 0.00e+00 │ ├─────────────────────┼───────┼─────────────────┼────────────────────┼─────────────────┼────────────────────┼──────────┤ diff --git a/website/data/menu/main.yml b/website/data/menu/main.yml index a0d1d56ed78f..5c54e3b0a709 100644 --- a/website/data/menu/main.yml +++ b/website/data/menu/main.yml @@ -2491,42 +2491,74 @@ main: - name: portfolio ref: /SDK/portfolio sub: - - name: calmar - ref: /SDK/portfolio/calmar - - name: commonsense - ref: /SDK/portfolio/commonsense + - name: alloc + ref: /SDK/portfolio/alloc + sub: + - name: assets + ref: /SDK/portfolio/alloc/assets + - name: countries + ref: /SDK/portfolio/alloc/countries + - name: regions + ref: /SDK/portfolio/alloc/regions + - name: sectors + ref: /SDK/portfolio/alloc/sectors + - name: bench + ref: /SDK/portfolio/bench - name: distr ref: /SDK/portfolio/distr - name: dret ref: /SDK/portfolio/dret - name: es ref: /SDK/portfolio/es - - name: gaintopain - ref: /SDK/portfolio/gaintopain - name: holdp ref: /SDK/portfolio/holdp - name: holdv ref: /SDK/portfolio/holdv - - name: information - ref: /SDK/portfolio/information - - name: jensens - ref: /SDK/portfolio/jensens - - name: kelly - ref: /SDK/portfolio/kelly - - name: kurtosis - ref: /SDK/portfolio/kurtosis - - name: max_drawdown_ratio - ref: /SDK/portfolio/max_drawdown_ratio + - name: load + ref: /SDK/portfolio/load - name: maxdd ref: /SDK/portfolio/maxdd - - name: maxdrawdown - ref: /SDK/portfolio/maxdrawdown + - name: metric + ref: /SDK/portfolio/metric + sub: + - name: calmar + ref: /SDK/portfolio/metric/calmar + - name: commonsense + ref: /SDK/portfolio/metric/commonsense + - name: gaintopain + ref: /SDK/portfolio/metric/gaintopain + - name: information + ref: /SDK/portfolio/metric/information + - name: jensens + ref: /SDK/portfolio/metric/jensens + - name: kelly + ref: /SDK/portfolio/metric/kelly + - name: kurtosis + ref: /SDK/portfolio/metric/kurtosis + - name: maxdrawdown + ref: /SDK/portfolio/metric/maxdrawdown + - name: payoff + ref: /SDK/portfolio/metric/payoff + - name: profitfactor + ref: /SDK/portfolio/metric/profitfactor + - name: rsquare + ref: /SDK/portfolio/metric/rsquare + - name: sharpe + ref: /SDK/portfolio/metric/sharpe + - name: skew + ref: /SDK/portfolio/metric/skew + - name: sortino + ref: /SDK/portfolio/metric/sortino + - name: tail + ref: /SDK/portfolio/metric/tail + - name: trackerr + ref: /SDK/portfolio/metric/trackerr + - name: volatility + ref: /SDK/portfolio/metric/volatility - name: mret ref: /SDK/portfolio/mret - name: om ref: /SDK/portfolio/om - - name: payoff - ref: /SDK/portfolio/payoff - name: perf ref: /SDK/portfolio/perf - name: po @@ -2574,34 +2606,24 @@ main: ref: /SDK/portfolio/po/relriskparity - name: riskparity ref: /SDK/portfolio/po/riskparity - - name: profitfactor - ref: /SDK/portfolio/profitfactor - name: rbeta ref: /SDK/portfolio/rbeta - name: rsharpe ref: /SDK/portfolio/rsharpe + - name: rsort + ref: /SDK/portfolio/rsort - name: rsortino ref: /SDK/portfolio/rsortino - name: rsquare ref: /SDK/portfolio/rsquare - name: rvol ref: /SDK/portfolio/rvol - - name: sharpe - ref: /SDK/portfolio/sharpe - - name: skew - ref: /SDK/portfolio/skew - - name: sortino - ref: /SDK/portfolio/sortino + - name: show + ref: /SDK/portfolio/show - name: summary ref: /SDK/portfolio/summary - - name: tail - ref: /SDK/portfolio/tail - - name: trackerr - ref: /SDK/portfolio/trackerr - name: var ref: /SDK/portfolio/var - - name: volatility - ref: /SDK/portfolio/volatility - name: yret ref: /SDK/portfolio/yret - name: stocks diff --git a/website/generate.py b/website/generate.py index 738f6817a074..e0cb67df070c 100644 --- a/website/generate.py +++ b/website/generate.py @@ -86,8 +86,8 @@ def write_section( if code_snippet: file.write(" {{< highlight python >}}\n") - file.write(" " + text) - file.write("{{< /highlight >}}") + file.write(" " + text + "\n") + file.write(" {{< /highlight >}}") else: file.write(" " + text) @@ -218,13 +218,19 @@ def write_docstring(name: str, func, file, chart: bool): title="Parameters\n ----------\n", docstring=formatted_docstring ) + has_returns = False returns_title_start, returns_title_end = locate_section( title="Returns\n -------\n", docstring=formatted_docstring ) + if returns_title_start > -1: + has_returns = True + has_examples = False examples_title_start, examples_title_end = locate_section( title="Examples\n --------\n", docstring=formatted_docstring ) + if examples_title_start > -1: + has_examples = True has_parameters = False if signature(func[2]).parameters: @@ -244,8 +250,10 @@ def write_docstring(name: str, func, file, chart: bool): # Summary if has_parameters: bottom = parameters_title_start - else: + elif has_returns: bottom = returns_title_start + else: + bottom = len(formatted_docstring) write_summary( bottom=bottom, @@ -255,10 +263,18 @@ def write_docstring(name: str, func, file, chart: bool): # Parameters if parameters_title_start > 0: + + if has_returns: + end = returns_title_start + elif has_examples: + end = examples_title_start + else: + end = len(formatted_docstring) + write_section( title="Parameters", start=parameters_title_end, - end=returns_title_start, + end=end, docstring=formatted_docstring.replace("_:", r"\_:"), file=file, ) @@ -270,6 +286,12 @@ def write_docstring(name: str, func, file, chart: bool): # Returns if returns_title_start > 0: + + if has_examples: + end = examples_title_start + else: + end = len(formatted_docstring) + write_section( title="Returns", start=returns_title_end,