def generate_random_portfolios(stocks: List[str],
                               period: str = "3mo",
                               n_portfolios: int = 300):
    """[summary]

    Parameters
    ----------
    stocks : List[str]
        [description]
    period : str, optional
        [description], by default "3mo"
    n_portfolios : int, optional
        [description], by default 300
    """
    stock_prices = yahoo_finance_model.process_stocks(stocks, period)
    mu = expected_returns.mean_historical_return(stock_prices)
    S = risk_models.sample_cov(stock_prices)
    ef = EfficientFrontier(mu, S)

    # Generate random portfolios
    n_samples = n_portfolios
    w = np.random.dirichlet(np.ones(len(mu)), n_samples)
    rets = w.dot(mu)
    stds = np.sqrt(np.diag(w @ S @ w.T))

    return ef, rets, stds
def get_maxquadutil_portfolio(
    stocks: List[str],
    period: str = "3mo",
    risk_aversion: float = 1.0,
    market_neutral: bool = False,
) -> Tuple[Dict, EfficientFrontier]:
    """Get portfolio maximizing quadratic utility at a given risk aversion

    Parameters
    ----------
    stocks : List[str]
        List of portfolio stocks
    period : str, optional
        Period to get stock data, by default "3mo"
    risk_aversion : float, optional
        Risk aversion level, by default 1.0
    market_neutral : bool, optional
        Whether portfolio is market neutral, by default False

    Returns
    -------
    Dict
        Dictionary of portfolio weights
    EfficientFrontier
        EfficientFrontier object
    """
    stock_prices = yahoo_finance_model.process_stocks(stocks, period)
    ef = prepare_efficient_frontier(stock_prices)
    return ef.max_quadratic_utility(risk_aversion, market_neutral), ef
def get_efficient_return_portfolio(
    stocks: List[str],
    period: str = "3mo",
    target_return: float = 0.1,
    market_neutral: bool = False,
) -> Tuple[Dict, EfficientFrontier]:
    """Get portfolio that minimizes volatility at given return

    Parameters
    ----------
    stocks : List[str]
        List of portfolio stocks
    period : str, optional
        Period to get stock data, by default "3mo"
    target_return : float, optional
        Target return level, by default 0.1
    market_neutral : bool, optional
        Whether portfolio is market neutral, by default False

    Returns
    -------
    Dict
        Dictionary of weights
    EfficientFrontier
        Efficient Frontier object
    """
    stock_prices = yahoo_finance_model.process_stocks(stocks, period)
    ef = prepare_efficient_frontier(stock_prices)
    return ef.efficient_return(target_return, market_neutral), ef
def get_minvol_portfolio(
        stocks: List[str],
        period: str = "3mo") -> Tuple[Dict, EfficientFrontier]:
    """Generate weights for minimum volatility portfolio

    Parameters
    ----------
    stocks : List[str]
        List of portfolio tickers
    period : str, optional
        Period to get stock data, by default "3mo"

    Returns
    -------
    Dict
        Dictionary of tickers and weights
    EfficientFrontier
        EfficientFrontier object
    """
    stock_prices = yahoo_finance_model.process_stocks(stocks, period)
    ef = prepare_efficient_frontier(stock_prices)
    return dict(ef.min_volatility()), ef
def get_maxsharpe_portfolio(stocks: List[str], period: str,
                            rfrate: float) -> Tuple[Dict, EfficientFrontier]:
    """Generate weights for max sharpe portfolio

    Parameters
    ----------
    stocks : List[str]
        List of portfolio tickers
    period : str, optional
        Period to get stock data, by default "3mo"
    rfrate : float, optional
        Risk free rate, by default 0.02

    Returns
    -------
    Dict
        Dictionary of tickers and weights
    EfficientFrontier
        EfficientFrontier object
    """
    stock_prices = yahoo_finance_model.process_stocks(stocks, period)
    ef = prepare_efficient_frontier(stock_prices)
    return dict(ef.max_sharpe(rfrate)), ef