def gmv_monthly(self) -> Tuple[float, float]: """ Returns the monthly risk and return of the Global Minimum Volatility portfolio """ return ( Frame.get_portfolio_risk(self.gmv_weights, self.ror), Frame.get_portfolio_mean_return(self.gmv_weights, self.ror), )
def optimize_return(self, option: str = "max") -> dict: """ Finds global max or min for the rate of return. Returns monthly values for the risk, mean return and the weights. 'max' - search for global maximum 'min' - search for global minimum """ n = self.ror.shape[1] # Number of assets init_guess = np.repeat(1 / n, n) # Set the objective function if option == "max": def objective_function(w, ror): month_return_value = Frame.get_portfolio_mean_return(w, ror) return -month_return_value elif option == "min": def objective_function(w, ror): month_return_value = Frame.get_portfolio_mean_return(w, ror) return month_return_value else: raise ValueError('option should be "max" or "min"') # construct the constraints weights_sum_to_1 = {"type": "eq", "fun": lambda weights: np.sum(weights) - 1} weights = minimize( objective_function, init_guess, args=(self.ror,), method="SLSQP", constraints=(weights_sum_to_1,), bounds=self.bounds, options={ "disp": False, "ftol": 1e-08, }, # 1e-06 is not enough to optimize monthly returns ) if weights.success: portfolio_risk = Frame.get_portfolio_risk(weights.x, self.ror) if option.lower() == "max": optimized_return = -weights.fun else: optimized_return = weights.fun point = { "Weights": weights.x, "Mean_return_monthly": optimized_return, "Risk_monthly": portfolio_risk, } return point else: raise Exception("No solutions where found")
def get_monte_carlo(self, n: int = 100, kind: str = "mean") -> pd.DataFrame: """ Generate N random risk / cagr point for portfolios. Risk and cagr are calculated for a set of random weights. """ weights_series = Float.get_random_weights(n, self.ror.shape[1]) # Portfolio risk and return for each set of weights random_portfolios = pd.DataFrame(dtype=float) for weights in weights_series: risk_monthly = Frame.get_portfolio_risk(weights, self.ror) mean_return_monthly = Frame.get_portfolio_mean_return(weights, self.ror) risk = Float.annualize_risk(risk_monthly, mean_return_monthly) mean_return = Float.annualize_return(mean_return_monthly) if kind.lower() == "cagr": cagr = Float.approx_return_risk_adjusted(mean_return, risk) row = dict(Risk=risk, CAGR=cagr) elif kind.lower() == "mean": row = dict(Risk=risk, Return=mean_return) else: raise ValueError('kind should be "mean" or "cagr"') random_portfolios = random_portfolios.append(row, ignore_index=True) return random_portfolios
def objective_function(w): return Frame.get_portfolio_risk(w, ror)