<jupyter_start><jupyter_text>Get data from yfinancePython library, but it has certain limitaitons.<jupyter_code>df = YFinanceDataset().get_multiple_tickers(
     ticker_names=[
         'MSFT', 
         'IBM',
         'KO', 
         'AAPL', 
         'AMZN', 
         'GOOG', 
         'NVDA'
     ])
ticker_names=[
    'MSFT', 
    'IBM',
    'KO', 
    'AAPL', 
    'AMZN', 
    'GOOG', 
    'NVDA'
]

def calc_portfolio_perf(weights, mean_returns, cov, rf):
    portfolio_return = np.sum(mean_returns * weights) * 252
    portfolio_std = np.sqrt(np.dot(weights.T, np.dot(cov, weights))) * np.sqrt(252)
    sharpe_ratio = (portfolio_return - rf) / portfolio_std
    return portfolio_return, portfolio_std, sharpe_ratio


def simulate_random_portfolios(num_portfolios, mean_returns, cov, rf):
    results_matrix = np.zeros((len(mean_returns) + 3, num_portfolios))
    for i in range(num_portfolios):
        weights = np.random.random(len(mean_returns))
        weights /= np.sum(weights)
        portfolio_return, portfolio_std, sharpe_ratio = calc_portfolio_perf(weights, mean_returns, cov, rf)
        results_matrix[0, i] = portfolio_return
        results_matrix[1, i] = portfolio_std
        results_matrix[2, i] = sharpe_ratio
        #iterate through the weight vector and add data to results array
        for j in range(len(weights)):
            results_matrix[j + 3, i] = weights[j]
            
    results_df = pd.DataFrame(
        results_matrix.T, 
        columns=['ret', 'stdev', 'sharpe'] + [ticker for ticker in ticker_names]
    )
        
    return results_df
mean_returns = df.pct_change().mean()
cov = df.pct_change().cov()
num_portfolios = 100000
rf = 0.0
results_frame = simulate_random_portfolios(num_portfolios, mean_returns, cov, rf)
#locate position of portfolio with highest Sharpe Ratio
max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]

#locate positon of portfolio with minimum standard deviation
min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]

#create scatter plot coloured by Sharpe Ratio
plt.subplots(figsize=(15, 10))
plt.scatter(
    results_frame.stdev, 
    results_frame.ret, 
    c=results_frame.sharpe, 
    cmap='RdYlBu'
)
plt.xlabel('Standard Deviation')
plt.ylabel('Returns')
plt.colorbar()

#plot red star to highlight position of portfolio with highest Sharpe Ratio
plt.scatter(
    max_sharpe_port[1], 
    max_sharpe_port[0],
    marker=(5, 1, 0), 
    color='r', 
    s=500
)

#plot green star to highlight position of minimum variance portfolio
plt.scatter(
    min_vol_port[1], 
    min_vol_port[0], 
    marker=(5, 1, 0), 
    color='g', s=500
)
plt.show()
max_sharpe_port.to_frame().T
min_vol_port.to_frame().T
def calc_neg_sharpe(weights, mean_returns, cov, rf):
    portfolio_return = np.sum(mean_returns * weights) * 252
    portfolio_std = np.sqrt(np.dot(weights.T, np.dot(cov, weights))) * np.sqrt(252)
    sharpe_ratio = (portfolio_return - rf) / portfolio_std
    return -sharpe_ratio

constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})

def max_sharpe_ratio(mean_returns, cov, rf):
    num_assets = len(mean_returns)
    args = (mean_returns, cov, rf)
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bound = (0.0, 1.0)
    bounds = tuple(bound for asset in range(num_assets))
    result = sco.minimize(
        calc_neg_sharpe, 
        num_assets * [1./num_assets,], 
        args=args,
        method='SLSQP', 
        bounds=bounds, 
        constraints=constraints
    )
    return result

optimal_port_sharpe = max_sharpe_ratio(mean_returns, cov, rf)


pd.DataFrame([round(x,2) for x in optimal_port_sharpe['x']], index=ticker_names).T
def calc_portfolio_std(weights, mean_returns, cov):
    portfolio_std = np.sqrt(np.dot(weights.T, np.dot(cov, weights))) * np.sqrt(252)
    return portfolio_std  

def min_variance(mean_returns, cov):
    num_assets = len(mean_returns)
    args = (mean_returns, cov)
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bound = (0.0,1.0)
    bounds = tuple(bound for asset in range(num_assets))
    
    result = sco.minimize(
        calc_portfolio_std, 
        num_assets * [1./num_assets,], 
        args=args,
        method='SLSQP', 
        bounds=bounds, 
        constraints=constraints
    )
    return result

min_port_variance = min_variance(mean_returns, cov)
pd.DataFrame([round(x, 2) for x in min_port_variance['x']], index=ticker_names).T

def calc_portfolio_perf_VaR(
    weights, 
    mean_returns,
    cov, 
    alpha,
    days
):
    portfolio_return = np.sum(mean_returns * weights) * days
    
    portfolio_std = np.sqrt(
        np.dot(weights.T, np.dot(cov, weights))
    ) * np.sqrt(days)
    
    portfolio_var = abs(portfolio_return - (portfolio_std * stats.norm.ppf(1 - alpha)))
    
    return (
        portfolio_return, 
        portfolio_std,
        portfolio_var
    )


def simulate_random_portfolios_VaR(
    num_portfolios,
    mean_returns,
    cov, 
    alpha, 
    days
):
    results_matrix = np.zeros((len(mean_returns) + 3, num_portfolios))
    
    for i in range(num_portfolios):
        weights = np.random.random(len(mean_returns))
        weights /= np.sum(weights)
        
        portfolio_return, portfolio_std, portfolio_VaR = calc_portfolio_perf_VaR(
            weights,
            mean_returns, 
            cov, alpha, 
            days
        )
        results_matrix[0, i] = portfolio_return
        results_matrix[1, i] = portfolio_std
        results_matrix[2, i] = portfolio_VaR
        #iterate through the weight vector and add data to results array
        for j in range(len(weights)):
            results_matrix[j + 3, i] = weights[j]
            
    results_df = pd.DataFrame(
        results_matrix.T,columns=['ret','stdev','VaR'] + [ticker for ticker in ticker_names]
    )
        
    return results_df
mean_returns = df.pct_change().mean()
cov = df.pct_change().cov()
num_portfolios = 100000
rf = 0.0
days = 252
alpha = 0.05
results_frame = simulate_random_portfolios_VaR(
    num_portfolios, 
    mean_returns, 
    cov, 
    alpha, 
    days
)
#locate positon of portfolio with minimum VaR
min_VaR_port = results_frame.iloc[results_frame['VaR'].idxmin()]
#create scatter plot coloured by VaR
plt.subplots(figsize=(15,10))
plt.scatter(results_frame.VaR, results_frame.ret, c=results_frame.VaR, cmap='RdYlBu')
plt.xlabel('Value at Risk')
plt.ylabel('Returns')
plt.colorbar()
#plot red star to highlight position of minimum VaR portfolio
plt.scatter(min_VaR_port[2], min_VaR_port[0], marker=(5, 1, 0), color='r', s=500)
plt.show()
min_VaR_port.to_frame().T
#locate positon of portfolio with minimum VaR
min_VaR_port = results_frame.iloc[results_frame['VaR'].idxmin()]
#create scatter plot coloured by VaR
plt.subplots(figsize=(15,10))
plt.scatter(
    results_frame.stdev, 
    results_frame.ret, 
    c=results_frame.VaR, 
    cmap='RdYlBu'
)
plt.xlabel('Standard Deviation')
plt.ylabel('Returns')
plt.colorbar()
#plot red star to highlight position of minimum VaR portfolio
plt.scatter(min_VaR_port[1], min_VaR_port[0], marker=(5, 1, 0), color='r', s=500)
plt.show()
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})

def calc_portfolio_VaR(weights, mean_returns, cov, alpha, days):
    portfolio_return = np.sum(mean_returns * weights) * days
    portfolio_std = np.sqrt(
        np.dot(weights.T, np.dot(cov, weights))
    ) * np.sqrt(days)
    portfolio_var = abs(portfolio_return - (portfolio_std * stats.norm.ppf(1 - alpha)))
    return portfolio_var


def min_VaR(mean_returns, cov, alpha, days):
    num_assets = len(mean_returns)
    args = (mean_returns, cov, alpha, days)
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bound = (0.0,1.0)
    bounds = tuple(bound for asset in range(num_assets))
    result = sco.minimize(calc_portfolio_VaR, num_assets * [1./num_assets,], args=args,
                        method='SLSQP', bounds=bounds, constraints=constraints)
    return result

min_port_VaR = min_VaR(mean_returns, cov, alpha, days)
pd.DataFrame([round(x, 2) for x in min_port_VaR['x']], index=ticker_names).T<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12357763367184632, 'fraction_numerical': 0.014193074758350667, 'mean_word_length': 3.3758029978586723, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '79213', 'license': 'MIT', 'n_tokens_mistral': 3039, 'n_tokens_neox': 2876, 'n_words': 617, 'path': 'notebooks/3.1 Portfolio optimization.ipynb', 'repo_name': 'gilberto-BE/aifi-pytorch', 'size': '8173'}