mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-07 09:52:13 +00:00
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* Update _index.md
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* configure portfolio optimization parameters ini
* minor improvement
* Revert "New-Portfolio-Optimization-Menu"
This reverts commit b4b7169cfb.
* Add in Excel functionality and improve the capabilities
* Add Excel load function
* Tidying up the functions
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* Re-add my code
* Some spacing and details
* Add folder structure for portfolio
* Update terminal file loading
* New-Portfolio-Optimization-Menu
* Make it possible to move from params to po with loaded file
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* Making the connection between the parameters file and the functions
* Add in allocation and new params files
* Improve params default settings
* New-Portfolio-Optimization-Menu
* Update Portfolios and Params sheets
* Update sheets
* Update command to load in correct sheet
* Adjust function to only read specific columns
* Update portfolio
* Small correction
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* Patched up show error
* Add Equity portfolio
* Make functions more robust
* New-Portfolio-Optimization-Menu
* New-Portfolio-Optimization-Menu
* Add in Params documentation
* Fixing Linting
* Add in Requirements and Poetry Updates
* Update website
* linting
* Update tests
* Minor fix
* remove unneccesary READMEs
* Remove expected variable type
* Improve documentation
* Clean up the code
* Refractoring
* Adjust names to make it OS friendly
Co-authored-by: Jeroen Bouma <jer.bouma@gmail.com>
Co-authored-by: jmaslek <jmaslek11@gmail.com>
Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com>
Co-authored-by: DidierRLopes <dro.lopes@campus.fct.unl.pt>
180 lines
5.1 KiB
Python
180 lines
5.1 KiB
Python
"""Excel Model"""
|
|
__docformat__ = "numpy"
|
|
|
|
# pylint: disable=abstract-class-instantiated
|
|
|
|
import logging
|
|
|
|
import pandas as pd
|
|
|
|
from openbb_terminal.decorators import log_start_end
|
|
from openbb_terminal.rich_config import console
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@log_start_end(log=logger)
|
|
def load_configuration(excel_file: str):
|
|
"""
|
|
Load in the Excel file to determine the configuration that needs to be set.
|
|
|
|
Parameters
|
|
----------
|
|
excel_file: str
|
|
The location of the Excel file that needs to be loaded.
|
|
|
|
Returns
|
|
-------
|
|
configuration: dictionary
|
|
Returns a dictionary with the configurations set.
|
|
"""
|
|
# Read in the Optimization template
|
|
df = pd.read_excel(
|
|
excel_file,
|
|
sheet_name="Optimization",
|
|
skiprows=2,
|
|
usecols="B:D",
|
|
names=["Parameter", "Value", "Description"],
|
|
index_col="Parameter",
|
|
)
|
|
|
|
# Remove completely empty NaN rows
|
|
cleaned_df = df.dropna(axis="rows", thresh=2)
|
|
|
|
# Filter out any general columns
|
|
filtered_df = cleaned_df[cleaned_df["Description"] != "Description"]
|
|
|
|
# Convert to Dictionary
|
|
configuration = filtered_df.to_dict()
|
|
|
|
return configuration["Value"], configuration["Description"]
|
|
|
|
|
|
@log_start_end(log=logger)
|
|
def load_allocation(excel_file: str):
|
|
"""
|
|
Load in the Excel file to determine the allocation that needs to be set.
|
|
|
|
Parameters
|
|
----------
|
|
excel_file: str
|
|
The location of the Excel file that needs to be loaded.
|
|
|
|
Returns
|
|
-------
|
|
tickers: list
|
|
Returns a list with ticker symbols
|
|
categories: dictionary
|
|
Returns a dictionary that specifies each category
|
|
"""
|
|
if str(excel_file).endswith(".xlsx"):
|
|
categories = pd.read_excel(excel_file, sheet_name="Allocation", usecols="A:G")
|
|
categories = categories.dropna(axis="rows")
|
|
elif str(excel_file).endswith(".csv"):
|
|
categories = pd.read_excel(excel_file)
|
|
categories = categories.dropna(axis="rows")
|
|
else:
|
|
console.print("Only Excel (.xlsx and .csv) files are accepted.\n")
|
|
return [], {}
|
|
|
|
categories.columns = [
|
|
col.upper().strip().replace(" ", "_") for col in categories.columns
|
|
]
|
|
categories = categories.apply(lambda x: x.astype(str).str.upper())
|
|
categories = categories[~categories.index.duplicated(keep="first")]
|
|
|
|
try:
|
|
categories.set_index("TICKER", inplace=True)
|
|
categories.sort_index(inplace=True)
|
|
except KeyError:
|
|
console.print("Allocation table needs a TICKER column\n")
|
|
return [], {}
|
|
|
|
tickers = list(categories.index)
|
|
tickers.sort()
|
|
categories = categories.to_dict()
|
|
|
|
return tickers, categories
|
|
|
|
|
|
@log_start_end(log=logger)
|
|
def load_bl_views(excel_file: str):
|
|
"""
|
|
Load a Excel file with views for Black Litterman model.
|
|
|
|
Parameters
|
|
----------
|
|
excel_file: str
|
|
The location of the Excel file that needs to be loaded.
|
|
|
|
Returns
|
|
-------
|
|
p_views: list
|
|
Returns a list with p_views matrix
|
|
q_views: list
|
|
Returns a list with q_views matrix
|
|
"""
|
|
if str(excel_file).endswith(".xlsx"):
|
|
try:
|
|
p_views = pd.read_excel(excel_file, sheet_name="p_views", index_col=0)
|
|
p_views = p_views.fillna(0)
|
|
p_views = p_views.dropna(axis="rows")
|
|
except KeyError:
|
|
console.print("Excel file needs a p_views sheet\n")
|
|
return {}, {}
|
|
try:
|
|
q_views = pd.read_excel(excel_file, sheet_name="q_views", index_col=0)
|
|
q_views = q_views.dropna(axis="rows")
|
|
except KeyError:
|
|
console.print("Excel file needs a p_views sheet\n")
|
|
return {}, {}
|
|
else:
|
|
console.print("Only Excel (.xlsx) files are accepted.\n")
|
|
return {}, {}
|
|
|
|
p_views = p_views.T.sort_index()
|
|
p_views = p_views.T.to_csv(index=False, header=0).replace("\n", ";")
|
|
p_views = p_views[:-1]
|
|
p_views = [[float(item) for item in row.split(",")] for row in p_views.split(";")]
|
|
q_views = q_views.to_csv(index=False, header=0).replace("\n", ",")
|
|
q_views = q_views[:-1]
|
|
q_views = [float(item) for item in q_views.split(",")]
|
|
|
|
return p_views, q_views
|
|
|
|
|
|
@log_start_end(log=logger)
|
|
def excel_bl_views(file: str, stocks: str, n: int = 3):
|
|
"""
|
|
Create an Excel file with required format to build n views for Black Litterman cmd.
|
|
|
|
Parameters
|
|
----------
|
|
stocks: str
|
|
List of stocks used to build the Black Litterman model views.
|
|
n: int
|
|
The number of views that will be created.
|
|
|
|
Returns
|
|
-------
|
|
file: excel
|
|
Returns a list with ticker symbols
|
|
"""
|
|
if len(stocks) < 2:
|
|
console.print("Please have at least 2 loaded tickers to create views.\n")
|
|
|
|
p_views = [[""] * len(stocks) for i in range(n)]
|
|
p_views_df = pd.DataFrame(p_views, columns=stocks)
|
|
|
|
q_views = [[""] for i in range(n)]
|
|
q_views_df = pd.DataFrame(q_views, columns=["Returns"])
|
|
|
|
if file.endswith(".xlsx"):
|
|
pass
|
|
else:
|
|
file += ".xlsx"
|
|
|
|
with pd.ExcelWriter(file) as writer:
|
|
p_views_df.to_excel(writer, sheet_name="p_views")
|
|
q_views_df.to_excel(writer, sheet_name="q_views")
|