mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 05:21:48 +00:00
some more minor refactoring cuz im picky
This commit is contained in:
@@ -347,7 +347,7 @@ def patch_pandas_text_adjustment():
|
||||
|
||||
def parse_known_args_and_warn(parser, l_args):
|
||||
parser.add_argument(
|
||||
"-h", "--help", action="store_true", dest="help", help="show this help message"
|
||||
"-h", "--help", action="store_true", help="show this help message"
|
||||
)
|
||||
|
||||
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
|
||||
|
||||
@@ -15,15 +15,107 @@ from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale, parse_known_args_and_warn
|
||||
|
||||
title_maps = {
|
||||
"max_sharpe": "Maximum Sharpe Portfolio",
|
||||
"min_volatility": "Minimum Volatility Portfolio",
|
||||
"eff_risk": "Maximum Return Portfolio at Risk = {:1f} %",
|
||||
"eff_ret": "Minimum Volatility Portfolio at Target Return = {:.1f} %",
|
||||
"equal": "Equally Weighted Portfolio",
|
||||
"marketCap": "MarketCap Weighted Portfolio",
|
||||
"dividendYield": "Dividend Yield Weighted Portfolio",
|
||||
}
|
||||
l_valid_property_infos = [
|
||||
"previousClose",
|
||||
"regularMarketOpen",
|
||||
"twoHundredDayAverage",
|
||||
"trailingAnnualDividendYield",
|
||||
"payoutRatio",
|
||||
"volume24Hr",
|
||||
"regularMarketDayHigh",
|
||||
"navPrice",
|
||||
"averageDailyVolume10Day",
|
||||
"totalAssets",
|
||||
"regularMarketPreviousClose",
|
||||
"fiftyDayAverage",
|
||||
"trailingAnnualDividendRate",
|
||||
"open",
|
||||
"toCurrency",
|
||||
"averageVolume10days",
|
||||
"expireDate",
|
||||
"yield",
|
||||
"algorithm",
|
||||
"dividendRate",
|
||||
"exDividendDate",
|
||||
"beta",
|
||||
"circulatingSupply",
|
||||
"regularMarketDayLow",
|
||||
"priceHint",
|
||||
"currency",
|
||||
"trailingPE",
|
||||
"regularMarketVolume",
|
||||
"lastMarket",
|
||||
"maxSupply",
|
||||
"openInterest",
|
||||
"marketCap",
|
||||
"volumeAllCurrencies",
|
||||
"strikePrice",
|
||||
"averageVolume",
|
||||
"priceToSalesTrailing12Months",
|
||||
"dayLow",
|
||||
"ask",
|
||||
"ytdReturn",
|
||||
"askSize",
|
||||
"volume",
|
||||
"fiftyTwoWeekHigh",
|
||||
"forwardPE",
|
||||
"fromCurrency",
|
||||
"fiveYearAvgDividendYield",
|
||||
"fiftyTwoWeekLow",
|
||||
"bid",
|
||||
"dividendYield",
|
||||
"bidSize",
|
||||
"dayHigh",
|
||||
"annualHoldingsTurnover",
|
||||
"enterpriseToRevenue",
|
||||
"beta3Year",
|
||||
"profitMargins",
|
||||
"enterpriseToEbitda",
|
||||
"52WeekChange",
|
||||
"morningStarRiskRating",
|
||||
"forwardEps",
|
||||
"revenueQuarterlyGrowth",
|
||||
"sharesOutstanding",
|
||||
"fundInceptionDate",
|
||||
"annualReportExpenseRatio",
|
||||
"bookValue",
|
||||
"sharesShort",
|
||||
"sharesPercentSharesOut",
|
||||
"fundFamily",
|
||||
"lastFiscalYearEnd",
|
||||
"heldPercentInstitutions",
|
||||
"netIncomeToCommon",
|
||||
"trailingEps",
|
||||
"lastDividendValue",
|
||||
"SandP52WeekChange",
|
||||
"priceToBook",
|
||||
"heldPercentInsiders",
|
||||
"shortRatio",
|
||||
"sharesShortPreviousMonthDate",
|
||||
"floatShares",
|
||||
"enterpriseValue",
|
||||
"threeYearAverageReturn",
|
||||
"lastSplitFactor",
|
||||
"legalType",
|
||||
"lastDividendDate",
|
||||
"morningStarOverallRating",
|
||||
"earningsQuarterlyGrowth",
|
||||
"pegRatio",
|
||||
"lastCapGain",
|
||||
"shortPercentOfFloat",
|
||||
"sharesShortPriorMonth",
|
||||
"impliedSharesOutstanding",
|
||||
"fiveYearAverageReturn",
|
||||
"regularMarketPrice",
|
||||
]
|
||||
|
||||
|
||||
def check_valid_property_type(property: str) -> str:
|
||||
""" Check that the property selected is valid """
|
||||
if property in l_valid_property_infos:
|
||||
return property
|
||||
else:
|
||||
raise argparse.ArgumentTypeError(f"{property} is not a valid info")
|
||||
|
||||
|
||||
def process_stocks(list_of_stocks: List[str], period: str = "3mo") -> pd.DataFrame:
|
||||
@@ -97,15 +189,15 @@ def my_autopct(x):
|
||||
return ""
|
||||
|
||||
|
||||
def pie_chart_weights(weights: dict, optimizer: str, value: float):
|
||||
"""
|
||||
Show a pie chart of holdings
|
||||
def pie_chart_weights(weights: dict, title_opt: str):
|
||||
"""Show a pie chart of holdings
|
||||
|
||||
Parameters
|
||||
----------
|
||||
weights: dict
|
||||
weights to display. Keys are stocks. Values are either weights or values if -v specified
|
||||
optimzer: str
|
||||
Optimization technique used for title
|
||||
Weights to display, where keys are tickers, and values are either weights or values if -v specified
|
||||
title: str
|
||||
Title to be used on the plot title
|
||||
"""
|
||||
if not weights:
|
||||
return
|
||||
@@ -176,10 +268,7 @@ def pie_chart_weights(weights: dict, optimizer: str, value: float):
|
||||
|
||||
plt.setp(autotexts, size=8, weight="bold")
|
||||
|
||||
if optimizer in ["eff_ret", "eff_risk"]:
|
||||
plt.gca().set_title(title_maps[optimizer].format(100 * value), pad=20)
|
||||
else:
|
||||
plt.gca().set_title(title_maps[optimizer], pad=20)
|
||||
plt.gca().set_title(title_opt, pad=20)
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
@@ -188,52 +277,3 @@ def pie_chart_weights(weights: dict, optimizer: str, value: float):
|
||||
|
||||
plt.show()
|
||||
print("")
|
||||
|
||||
|
||||
def parse_from_port_type(
|
||||
parser_in: argparse.ArgumentParser, port_type: str, other_args: List[str]
|
||||
):
|
||||
"""
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parser_in: ArgumentParser
|
||||
parser to get data from
|
||||
port_type: str
|
||||
Type of optimization that will be done. One of ["max_sharpe","min_vol", "eff_risk", "eff_ret"]
|
||||
other_args: List[str]
|
||||
Arguments passed to function
|
||||
Returns
|
||||
-------
|
||||
|
||||
ns_parser:
|
||||
Parsed arguments
|
||||
"""
|
||||
|
||||
if port_type in ["max_sharpe", "min_volatility"]:
|
||||
ns_parser = parse_known_args_and_warn(parser_in, other_args)
|
||||
if not ns_parser:
|
||||
return None
|
||||
return ns_parser
|
||||
|
||||
elif port_type == "eff_risk":
|
||||
parser_in.add_argument(
|
||||
"-r", "--risk", type=float, dest="risk_level", default=0.1
|
||||
)
|
||||
ns_parser = parse_known_args_and_warn(parser_in, other_args)
|
||||
if not ns_parser:
|
||||
return None
|
||||
return ns_parser
|
||||
|
||||
elif port_type == "eff_ret":
|
||||
parser_in.add_argument(
|
||||
"-r", "--return", type=float, dest="target_return", default=0.1
|
||||
)
|
||||
|
||||
ns_parser = parse_known_args_and_warn(parser_in, other_args)
|
||||
if not ns_parser:
|
||||
return None
|
||||
return ns_parser
|
||||
else:
|
||||
print("Incorrect portfolio optimizer type\n")
|
||||
return None
|
||||
|
||||
@@ -16,7 +16,7 @@ from gamestonk_terminal.portfolio_optimization.optimizer_helper import (
|
||||
prepare_efficient_frontier,
|
||||
pie_chart_weights,
|
||||
display_weights,
|
||||
parse_from_port_type,
|
||||
check_valid_property_type,
|
||||
)
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
@@ -35,6 +35,20 @@ period_choices = [
|
||||
"max",
|
||||
]
|
||||
|
||||
d_period = {
|
||||
"1d": "[1 Day]",
|
||||
"5d": "[5 Days]",
|
||||
"1mo": "[1 Month]",
|
||||
"3mo": "[3 Months]",
|
||||
"6mo": "[6 Months]",
|
||||
"1y": "[1 Year]",
|
||||
"2y": "[2 Years]",
|
||||
"5y": "[5 Years]",
|
||||
"10y": "[10 Years]",
|
||||
"ytd": "[Year-to-Date]",
|
||||
"max": "[All-time]",
|
||||
}
|
||||
|
||||
|
||||
def equal_weight(stocks: List[str], other_args: List[str]):
|
||||
"""
|
||||
@@ -53,8 +67,8 @@ def equal_weight(stocks: List[str], other_args: List[str]):
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
prog="equal_weight",
|
||||
description="Return equally weighted portfolio holdings",
|
||||
prog="equal",
|
||||
description="Returns an equally weighted portfolio",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
@@ -83,7 +97,7 @@ def equal_weight(stocks: List[str], other_args: List[str]):
|
||||
for stock in stocks:
|
||||
values[stock] = ns_parser.value * round(1 / len(stocks), 5)
|
||||
if ns_parser.pie:
|
||||
pie_chart_weights(values, "equal", 0)
|
||||
pie_chart_weights(values, "Equally Weighted Portfolio")
|
||||
else:
|
||||
display_weights(values)
|
||||
print("")
|
||||
@@ -93,16 +107,15 @@ def equal_weight(stocks: List[str], other_args: List[str]):
|
||||
print("")
|
||||
|
||||
|
||||
def property_weighting(stocks: List[str], property_type: str, other_args: List[str]):
|
||||
"""
|
||||
Property weighted portfolio where each weight is the relative fraction.
|
||||
def property_weighting(stocks: List[str], other_args: List[str]):
|
||||
"""Weighted portfolio where each weight is the relative fraction of a specified info property.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
stocks: List[str]
|
||||
List of tickers to be included in optimization
|
||||
property_type: str
|
||||
Property to weight by. Can be anything in yfinance.Ticker().info. Examples:
|
||||
"marketCap", "dividendYield", etc
|
||||
other_args : List[str]
|
||||
Command line arguments to be processed with argparse
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -111,10 +124,32 @@ def property_weighting(stocks: List[str], property_type: str, other_args: List[s
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
prog="market_cap_weighted",
|
||||
description="Return portfolio weights/values that are weighted by marketcap",
|
||||
prog="property",
|
||||
description="Returns a portfolio that is weighted based on a selected property info",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--property",
|
||||
required=True,
|
||||
type=check_valid_property_type,
|
||||
dest="property",
|
||||
help="""Property info to weigh. Use one of:
|
||||
previousClose, regularMarketOpen, twoHundredDayAverage, trailingAnnualDividendYield,
|
||||
payoutRatio, volume24Hr, regularMarketDayHigh, navPrice, averageDailyVolume10Day, totalAssets,
|
||||
regularMarketPreviousClose, fiftyDayAverage, trailingAnnualDividendRate, open, toCurrency, averageVolume10days,
|
||||
expireDate, yield, algorithm, dividendRate, exDividendDate, beta, circulatingSupply, regularMarketDayLow,
|
||||
priceHint, currency, trailingPE, regularMarketVolume, lastMarket, maxSupply, openInterest, marketCap,
|
||||
volumeAllCurrencies, strikePrice, averageVolume, priceToSalesTrailing12Months, dayLow, ask, ytdReturn, askSize,
|
||||
volume, fiftyTwoWeekHigh, forwardPE, fromCurrency, fiveYearAvgDividendYield, fiftyTwoWeekLow, bid, dividendYield,
|
||||
bidSize, dayHigh, annualHoldingsTurnover, enterpriseToRevenue, beta3Year, profitMargins, enterpriseToEbitda,
|
||||
52WeekChange, morningStarRiskRating, forwardEps, revenueQuarterlyGrowth, sharesOutstanding, fundInceptionDate,
|
||||
annualReportExpenseRatio, bookValue, sharesShort, sharesPercentSharesOut, fundFamily, lastFiscalYearEnd,
|
||||
heldPercentInstitutions, netIncomeToCommon, trailingEps, lastDividendValue, SandP52WeekChange, priceToBook,
|
||||
heldPercentInsiders, shortRatio, sharesShortPreviousMonthDate, floatShares, enterpriseValue,
|
||||
threeYearAverageReturn, lastSplitFactor, legalType, lastDividendDate, morningStarOverallRating,
|
||||
earningsQuarterlyGrowth, pegRatio, lastCapGain, shortPercentOfFloat, sharesShortPriorMonth,
|
||||
impliedSharesOutstanding, fiveYearAverageReturn, and regularMarketPrice.""",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--value",
|
||||
@@ -130,19 +165,24 @@ def property_weighting(stocks: List[str], property_type: str, other_args: List[s
|
||||
default=False,
|
||||
help="Display a pie chart for weights",
|
||||
)
|
||||
weights = {}
|
||||
prop = {}
|
||||
prop_sum = 0
|
||||
|
||||
try:
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-p")
|
||||
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
if len(stocks) < 2:
|
||||
print("Please have at least 2 loaded tickers to calculate weights.\n")
|
||||
return
|
||||
|
||||
weights = {}
|
||||
prop = {}
|
||||
prop_sum = 0
|
||||
for stock in stocks:
|
||||
stock_prop = yf.Ticker(stock).info[property_type]
|
||||
stock_prop = yf.Ticker(stock).info[ns_parser.property]
|
||||
if stock_prop is None:
|
||||
stock_prop = 0
|
||||
prop[stock] = stock_prop
|
||||
@@ -151,7 +191,9 @@ def property_weighting(stocks: List[str], property_type: str, other_args: List[s
|
||||
weights[k] = round(v / prop_sum, 5) * ns_parser.value
|
||||
|
||||
if ns_parser.pie:
|
||||
pie_chart_weights(weights, property_type, 0)
|
||||
pie_chart_weights(
|
||||
weights, "Weighted Portfolio based on " + ns_parser.property
|
||||
)
|
||||
else:
|
||||
display_weights(weights)
|
||||
print("")
|
||||
@@ -165,20 +207,37 @@ def property_weighting(stocks: List[str], property_type: str, other_args: List[s
|
||||
def ef_portfolio(stocks: List[str], port_type: str, other_args: List[str]):
|
||||
"""
|
||||
Return a portfolio based on condition in port_type Defaults to 3m of historical data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
stocks: List[str]
|
||||
List of the stocks to be included in the weights
|
||||
port_type: str
|
||||
Method to be used on ef object (example: max_sharpe, min_volatility)
|
||||
Method to be used on ef object (example: max_sharpe, min_volatility, eff_risk, eff_ret)
|
||||
|
||||
Returns
|
||||
-------
|
||||
weights: dict
|
||||
Dictionary of weights where keys are the tickers.
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(add_help=False, prog=port_type)
|
||||
d_descriptions = {
|
||||
"max_sharpe": """Maximise the Sharpe Ratio. The result is also referred to as the tangency portfolio,
|
||||
as it is the portfolio for which the capital market line is tangent to the efficient frontier.
|
||||
|
||||
This is a convex optimization problem after making a certain variable substitution. See
|
||||
Cornuejols and Tutuncu (2006) <http://web.math.ku.dk/~rolf/CT_FinOpt.pdf> for more.""",
|
||||
"min_volatility": "optimizes for minimum volatility",
|
||||
"max_quadratic_utility": "maximises the quadratic utility, given some risk aversion",
|
||||
"efficient_risk": """Maximise return for a target risk. The resulting portfolio will have
|
||||
a volatility less than the target (but not guaranteed to be equal).""",
|
||||
"efficient_return": "Calculate the 'Markowitz portfolio', minimising volatility for a given target return.",
|
||||
"max_quadratic_utility": "Maximise the given quadratic utility, i.e: max_w w^T \mu - \frac \delta 2 w^T \Sigma w",
|
||||
}
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False, prog=port_type, description=d_descriptions[port_type]
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--period",
|
||||
@@ -187,7 +246,6 @@ def ef_portfolio(stocks: List[str], port_type: str, other_args: List[str]):
|
||||
help="period to get yfinance data from",
|
||||
choices=period_choices,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--value",
|
||||
@@ -204,68 +262,144 @@ def ef_portfolio(stocks: List[str], port_type: str, other_args: List[str]):
|
||||
help="Display a pie chart for weights",
|
||||
)
|
||||
|
||||
if port_type == "max_sharpe":
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-r")
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--risk_free_rate",
|
||||
type=float,
|
||||
dest="risk_free_rate",
|
||||
default=0.02,
|
||||
help="""Risk-free rate of borrowing/lending. The period of the risk-free rate
|
||||
should correspond to the frequency of expected returns.""",
|
||||
)
|
||||
|
||||
elif port_type == "efficient_risk":
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-t")
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--target_volatility",
|
||||
type=float,
|
||||
dest="target_volatility",
|
||||
default=0.1,
|
||||
help="The desired maximum volatility of the resulting portfolio",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--market_neutral",
|
||||
action="store_true",
|
||||
default=False,
|
||||
dest="market_neutral",
|
||||
help="""whether the portfolio should be market neutral (weights sum to zero), defaults to False.
|
||||
Requires negative lower weight bound.""",
|
||||
)
|
||||
|
||||
elif port_type == "efficient_return":
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-t")
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--target_return",
|
||||
type=float,
|
||||
dest="target_return",
|
||||
default=0.1,
|
||||
help="the desired return of the resulting portfolio",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--market_neutral",
|
||||
action="store_true",
|
||||
default=False,
|
||||
dest="market_neutral",
|
||||
help="""whether the portfolio should be market neutral (weights sum to zero), defaults to False.
|
||||
Requires negative lower weight bound.""",
|
||||
)
|
||||
|
||||
elif port_type == "max_quadratic_utility":
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-r")
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--risk_aversion",
|
||||
type=float,
|
||||
dest="risk_aversion",
|
||||
default=1,
|
||||
help="risk aversion parameter",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--market_neutral",
|
||||
action="store_true",
|
||||
default=False,
|
||||
dest="market_neutral",
|
||||
help="""whether the portfolio should be market neutral (weights sum to zero), defaults to False.
|
||||
Requires negative lower weight bound.""",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_from_port_type(parser, port_type, other_args)
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return
|
||||
return None
|
||||
if len(stocks) < 2:
|
||||
print("Please have at least 2 loaded tickers to calculate weights.\n")
|
||||
return
|
||||
|
||||
period = ns_parser.period
|
||||
stock_prices = process_stocks(stocks, period)
|
||||
ef = prepare_efficient_frontier(stock_prices)
|
||||
|
||||
if port_type == "max_sharpe":
|
||||
sp = d_period[ns_parser.period]
|
||||
|
||||
ef_sharpe = dict(ef.max_sharpe())
|
||||
weights = {
|
||||
key: ns_parser.value * round(value, 5)
|
||||
for key, value in ef_sharpe.items()
|
||||
}
|
||||
val = 0
|
||||
print("Weights that maximize Sharpe Ratio:")
|
||||
if port_type == "max_sharpe":
|
||||
ef_opt = dict(ef.max_sharpe(ns_parser.risk_free_rate))
|
||||
s_title = f"{sp} Weights that maximize Sharpe ration with risk free level of {ns_parser.risk_free_rate}"
|
||||
|
||||
elif port_type == "min_volatility":
|
||||
ef_opt = dict(ef.min_volatility())
|
||||
s_title = f"{sp} Weights that minimize volatility"
|
||||
|
||||
ef_min_vol = dict(ef.min_volatility())
|
||||
weights = {
|
||||
key: ns_parser.value * round(value, 5)
|
||||
for key, value in ef_min_vol.items()
|
||||
}
|
||||
val = 0
|
||||
print("Weights that minimize volatility")
|
||||
elif port_type == "efficient_risk":
|
||||
ef_opt = dict(
|
||||
ef.efficient_risk(ns_parser.target_volatility, ns_parser.market_neutral)
|
||||
)
|
||||
s_title = f"{sp} Weights that maximize return with a maximum volatility of {ns_parser.target_volatility}"
|
||||
|
||||
elif port_type == "eff_risk":
|
||||
elif port_type == "efficient_return":
|
||||
ef_opt = dict(
|
||||
ef.efficient_return(ns_parser.target_return, ns_parser.market_neutral)
|
||||
)
|
||||
s_title = f"{sp} Weights that minimise volatility for a given target return of {ns_parser.target_return}"
|
||||
|
||||
ef_eff_risk = dict(ef.efficient_risk(ns_parser.risk_level))
|
||||
weights = {
|
||||
key: ns_parser.value * round(value, 5)
|
||||
for key, value in ef_eff_risk.items()
|
||||
}
|
||||
val = ns_parser.risk_level
|
||||
print(f"Weights for maximizing returns at risk = {100*val:.1f} %")
|
||||
|
||||
elif port_type == "eff_ret":
|
||||
|
||||
ef_eff_risk = dict(ef.efficient_return(ns_parser.target_return))
|
||||
weights = {
|
||||
key: ns_parser.value * round(value, 5)
|
||||
for key, value in ef_eff_risk.items()
|
||||
}
|
||||
val = ns_parser.target_return
|
||||
print(f"Weights for minimizing risk at target return = {100*val:.1f} %")
|
||||
elif port_type == "max_quadratic_utility":
|
||||
ef_opt = dict(
|
||||
ef.max_quadratic_utility(
|
||||
ns_parser.risk_aversion, ns_parser.market_neutral
|
||||
)
|
||||
)
|
||||
s_title = f"{sp} Weights that maximise the quadratic utility with risk aversion of {ns_parser.risk_aversion}"
|
||||
|
||||
else:
|
||||
raise ValueError("EF Method not found")
|
||||
|
||||
if ns_parser.pie:
|
||||
pie_chart_weights(weights, port_type, val)
|
||||
weights = {
|
||||
key: ns_parser.value * round(value, 5) for key, value in ef_opt.items()
|
||||
}
|
||||
|
||||
if ns_parser.pie:
|
||||
pie_chart_weights(weights, s_title)
|
||||
else:
|
||||
print(s_title)
|
||||
display_weights(weights)
|
||||
print("")
|
||||
|
||||
print("")
|
||||
ef.portfolio_performance(verbose=True)
|
||||
print("")
|
||||
display_weights(weights)
|
||||
print("")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@@ -21,12 +21,12 @@ class PortfolioOptimization:
|
||||
"select",
|
||||
"add",
|
||||
"equal",
|
||||
"mktcap",
|
||||
"dividend",
|
||||
"property",
|
||||
"maxsharpe",
|
||||
"minvol",
|
||||
"maxret",
|
||||
"minrisk",
|
||||
"effret",
|
||||
"effrisk",
|
||||
"maxquadutil",
|
||||
"ef",
|
||||
"yolo",
|
||||
]
|
||||
@@ -57,12 +57,20 @@ class PortfolioOptimization:
|
||||
print("")
|
||||
print("Optimization:")
|
||||
print(" equal equally weighted")
|
||||
print(" mktcap market cap weighted")
|
||||
print(" dividend dividend weighted")
|
||||
print(" maxsharpe maximum sharpe ratio")
|
||||
print(" minvol minimum volatility")
|
||||
print(" maxret maximizes returns at given risk")
|
||||
print(" minrisk minimizes risk at given return")
|
||||
print(
|
||||
" property weight according to selected info property (e.g. marketCap)"
|
||||
)
|
||||
print("")
|
||||
print(
|
||||
" maxsharpe optimizes for maximal Sharpe ratio (a.k.a the tangency portfolio)"
|
||||
)
|
||||
print(" minvol optimizes for minimum volatility")
|
||||
print(
|
||||
" maxquadutil maximises the quadratic utility, given some risk aversion"
|
||||
)
|
||||
print(" effret maximises return for a given target risk")
|
||||
print(" effrisk minimises risk for a given target return")
|
||||
print("")
|
||||
print(" ef show the efficient frontier")
|
||||
print("")
|
||||
|
||||
@@ -107,13 +115,9 @@ class PortfolioOptimization:
|
||||
"""Process equal command"""
|
||||
optimizer_view.equal_weight(self.tickers, other_args)
|
||||
|
||||
def call_mktcap(self, other_args: List[str]):
|
||||
"""Process mktcap command"""
|
||||
optimizer_view.property_weighting(self.tickers, "marketCap", other_args)
|
||||
|
||||
def call_dividend(self, other_args: List[str]):
|
||||
"""Process dividend command"""
|
||||
optimizer_view.property_weighting(self.tickers, "dividendYield", other_args)
|
||||
def call_property(self, other_args: List[str]):
|
||||
"""Process property command"""
|
||||
optimizer_view.property_weighting(self.tickers, other_args)
|
||||
|
||||
def call_maxsharpe(self, other_args: List[str]):
|
||||
"""Process maxsharpe command"""
|
||||
@@ -123,13 +127,17 @@ class PortfolioOptimization:
|
||||
"""Process minvol command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "min_volatility", other_args)
|
||||
|
||||
def call_maxret(self, other_args: List[str]):
|
||||
"""Process maxret command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "eff_risk", other_args)
|
||||
def call_maxquadutil(self, other_args: List[str]):
|
||||
"""Process maxquadutil command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "max_quadratic_utility", other_args)
|
||||
|
||||
def call_minrisk(self, other_args: List[str]):
|
||||
"""Process minrisk command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "eff_ret", other_args)
|
||||
def call_effrisk(self, other_args: List[str]):
|
||||
"""Process effrisk command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "efficient_risk", other_args)
|
||||
|
||||
def call_effret(self, other_args: List[str]):
|
||||
"""Process effret command"""
|
||||
optimizer_view.ef_portfolio(self.tickers, "efficient_return", other_args)
|
||||
|
||||
def call_ef(self, other_args):
|
||||
"""Process ef command"""
|
||||
@@ -158,7 +166,6 @@ class PortfolioOptimization:
|
||||
help="add tickers to optimzation.",
|
||||
)
|
||||
try:
|
||||
|
||||
if other_args:
|
||||
if "-" not in other_args[0]:
|
||||
other_args.insert(0, "-t")
|
||||
|
||||
Reference in New Issue
Block a user