Updated Portfolio Rf rate. (#781)

* Began better rf

* Continued updates

* Added James' suggestion

* Fixed glitch, removed prints

* Kept rate consistency

Co-authored-by: Colin Delahunty <colindelahunty@Colins-Air.indiana.edu>
Co-authored-by: Colin Delahunty <colindelahunty@Colins-MacBook-Air.local>
This commit is contained in:
Colin Delahunty
2021-10-04 16:37:00 -04:00
committed by GitHub
parent 67e23c4340
commit 5be35554c2
4 changed files with 30 additions and 10 deletions

View File

@@ -2,6 +2,7 @@
__docformat__ = "numpy"
import argparse
import requests
# These are all the possible yfinance properties
l_valid_property_infos = [
@@ -105,3 +106,16 @@ def check_valid_property_type(aproperty: str) -> str:
return aproperty
raise argparse.ArgumentTypeError(f"{aproperty} is not a valid info")
def get_rf() -> float:
"""Uses the fiscaldata.gov API to get most recent T-Bill rate"""
try:
base = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service"
end = "/v2/accounting/od/avg_interest_rates"
filters = "?filter=security_desc:eq:Treasury Bills&sort=-record_date"
response = requests.get(base + end + filters)
latest = response.json()["data"][0]
return round(float(latest["avg_interest_rate_amt"]) / 100, 8)
except Exception:
return 0.02

View File

@@ -65,7 +65,7 @@ def get_property_weights(
def get_maxsharpe_portfolio(
stocks: List[str], period: str = "3mo", rfrate: float = 0.02
stocks: List[str], period: str, rfrate: float
) -> Tuple[Dict, EfficientFrontier]:
"""Generate weights for max sharpe portfolio

View File

@@ -14,6 +14,7 @@ from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.helper_funcs import plot_autoscale
from gamestonk_terminal.portfolio.portfolio_optimization import optimizer_model
from gamestonk_terminal.portfolio.portfolio_optimization.optimizer_helper import get_rf
d_period = {
"1d": "[1 Day]",
@@ -131,8 +132,8 @@ def display_property_weighting(
def display_max_sharpe(
stocks: List[str],
period: str,
value: float = 1.0,
rfrate: float = 0.02,
value: float,
rfrate: float,
pie: bool = False,
):
"""Display portfolio that maximizes Sharpe Ratio over stocks
@@ -146,11 +147,12 @@ def display_max_sharpe(
value : float, optional
Amount to allocate to portfolio, by default 1.0
rfrate : float, optional
Risk Free Rate, by default 0.02
Risk Free Rate, by default current US T-Bill rate
pie : bool, optional
Boolean to show weights as a pie chart, by default False
"""
s_title = f"{d_period[period]} Weights that maximize Sharpe ratio with risk free level of {rfrate}"
p = d_period[period]
s_title = f"{p} Weights that maximize Sharpe ratio with risk free level of {rfrate*100:.2f}%"
ef_opt, ef = optimizer_model.get_maxsharpe_portfolio(stocks, period, rfrate)
weights = {key: value * round(port_value, 5) for key, port_value in ef_opt.items()}
if pie:
@@ -158,7 +160,7 @@ def display_max_sharpe(
else:
print("\n", s_title)
display_weights(weights)
ef.portfolio_performance(verbose=True)
ef.portfolio_performance(verbose=True, risk_free_rate=rfrate)
print("")
@@ -337,8 +339,11 @@ def display_ef(stocks: List[str], period: str = "3mo", n_portfolios: int = 300):
ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)
# Find the tangency portfolio
ef.max_sharpe()
ret_sharpe, std_sharpe, _ = ef.portfolio_performance()
rfrate = get_rf()
ef.max_sharpe(risk_free_rate=rfrate)
ret_sharpe, std_sharpe, _ = ef.portfolio_performance(
verbose=True, risk_free_rate=rfrate
)
ax.scatter(std_sharpe, ret_sharpe, marker="*", s=100, c="r", label="Max Sharpe")
ax.set_title(f"Efficient Frontier simulating {n_portfolios} portfolios")
ax.legend()

View File

@@ -18,6 +18,8 @@ from gamestonk_terminal.portfolio.portfolio_optimization import (
optimizer_helper,
)
from gamestonk_terminal.portfolio.portfolio_optimization.optimizer_helper import get_rf
period_choices = [
"1d",
"5d",
@@ -372,7 +374,7 @@ Mean Variance Optimization:
"--risk-free-rate",
type=float,
dest="risk_free_rate",
default=0.02,
default=get_rf(),
help="""Risk-free rate of borrowing/lending. The period of the risk-free rate
should correspond to the frequency of expected returns.""",
)
@@ -385,7 +387,6 @@ Mean Variance Optimization:
if len(self.tickers) < 2:
print("Please have at least 2 loaded tickers to calculate weights.\n")
return
optimizer_view.display_max_sharpe(
stocks=self.tickers,
period=ns_parser.period,