title: Python errors out on portfolio management exercise
body: <p>When I try to run the chunk of code below I get some weird errors.  </p>
  
  <p>Here is the traceback:</p>
  
  <pre><code>Traceback (most recent call last):
    File "&lt;input&gt;", line 1, in &lt;module&gt;
    File "&lt;input&gt;", line 91, in display_simulated_ef_with_random
    File "&lt;input&gt;", line 71, in random_portfolios
    File "&lt;input&gt;", line 59, in portfolio_annualised_performance
    File "C:\Users\rms\PycharmProjects\untitled2\venv\lib\site-packages\pandas\core\ops.py", line 1583, in wrapper
      result = safe_na_op(lvalues, rvalues)
    File "C:\Users\rms\PycharmProjects\untitled2\venv\lib\site-packages\pandas\core\ops.py", line 1529, in safe_na_op
      return na_op(lvalues, rvalues)
    File "C:\Users\rms\PycharmProjects\untitled2\venv\lib\site-packages\pandas\core\ops.py", line 1505, in na_op
      result = expressions.evaluate(op, str_rep, x, y, **eval_kwargs)
    File "C:\Users\rms\PycharmProjects\untitled2\venv\lib\site-packages\pandas\core\computation\expressions.py", line 208, in evaluate
      return _evaluate(op, op_str, a, b, **eval_kwargs)
    File "C:\Users\rms\PycharmProjects\untitled2\venv\lib\site-packages\pandas\core\computation\expressions.py", line 68, in _evaluate_standard
      return op(a, b)
  ValueError: operands could not be broadcast together with shapes (22,) (4,) 
  </code></pre>
  
  <p>I think I am missing something somewhat simple, but I'm not sure what the issue really is.  Any thoughts?</p>
  
  <pre><code>import pandas as pd
  import numpy as np
  from pandas_datareader import data, wb
  import datetime
  import scipy.optimize as sco
  from scipy import stats
  from datetime import datetime, date, time
  import matplotlib.pyplot as plt
  
  pd.set_option('display.max_columns', None)
  
  tickers = ['AAPL',
  'BA',
  'CAT',
  'CSCO',
  'CVX',
  'XOM',
  'GS',
  'HD',
  'IBM',
  'INTC',
  'JNJ',
  'KO',
  'JPM',
  'MCD',
  'MMM',
  'MRK',
  'MSFT',
  'NKE',
  'PFE',
  'PG',
  'VZ',
  'DIS']
  start = date(2019, 1, 1)
  end = date(2019, 7, 16)
  
  df = pd.DataFrame([data.DataReader(ticker, 'yahoo', start, end)['Adj Close'] for ticker in tickers]).T
  df.columns = tickers
  
  print(df)
  
  
  
  plt.figure(figsize=(10, 5))
  for c in df.columns.values:
      plt.plot(df.index, df[c], lw=3, alpha=0.8,label=c)
  plt.legend(loc='upper left', fontsize=12)
  plt.ylabel('price in $')
  
  returns = df.pct_change()
  plt.figure(figsize=(10, 5))
  for c in returns.columns.values:
      plt.plot(returns.index, returns[c], lw=3, alpha=0.8,label=c)
  plt.legend(loc='upper right', fontsize=12)
  plt.ylabel('daily returns')
  
  
  def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
      returns = np.sum(mean_returns * weights) * 252
      std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
      return std, returns
  
  
  def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate):
      results = np.zeros((3, num_portfolios))
      weights_record = []
      for i in range(num_portfolios):
          weights = np.random.random(4)
          weights /= np.sum(weights)
          weights_record.append(weights)
          portfolio_std_dev, portfolio_return = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
          results[0, i] = portfolio_std_dev
          results[1, i] = portfolio_return
          results[2, i] = (portfolio_return - risk_free_rate) / portfolio_std_dev
      return results, weights_record
  
  
  # calculate sharpe ratio
  returns = df.pct_change()
  mean_returns = returns.mean()
  cov_matrix = returns.cov()
  num_portfolios = 250
  risk_free_rate = 0.015
  
  
  # generate random portfolio and gets the results (portfolio returns, portfolio volatility, portfolio Sharpe ratio)
  # and weights for the corresponding result. Then by locating the one with the highest Sharpe ratio portfolio,
  # it displays maximum Sharpe ratio portfolio as red star sign. And does similar steps for minimum volatility portfolio,
  # and displays it as a green star on the plot.
  def display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate):
      results, weights = random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate)
  
      max_sharpe_idx = np.argmax(results[2])
      sdp, rp = results[0, max_sharpe_idx], results[1, max_sharpe_idx]
      max_sharpe_allocation = pd.DataFrame(weights[max_sharpe_idx], index=df.columns, columns=['allocation'])
      max_sharpe_allocation.allocation = [round(i * 100, 2) for i in max_sharpe_allocation.allocation]
      max_sharpe_allocation = max_sharpe_allocation.T
  
  
      min_vol_idx = np.argmin(results[0])
      sdp_min, rp_min = results[0, min_vol_idx], results[1, min_vol_idx]
      min_vol_allocation = pd.DataFrame(weights[min_vol_idx], index=df.columns, columns=['allocation'])
      min_vol_allocation.allocation = [round(i * 100, 2) for i in min_vol_allocation.allocation]
      min_vol_allocation = min_vol_allocation.T
  
      print("-" * 80)
      print("Maximum Sharpe Ratio Portfolio Allocation\n")
      print("Annualised Return:", round(rp, 2))
      print("Annualised Volatility:", round(sdp, 2))
      print("\n")
      print(max_sharpe_allocation)
      print("-" * 80)
      print("Minimum Volatility Portfolio Allocation\n")
      print("Annualised Return:", round(rp_min, 2))
      print("Annualised Volatility:", round(sdp_min, 2))
      print("\n")
      print(min_vol_allocation)
  
      plt.figure(figsize=(10, 7))
      plt.scatter(results[0, :], results[1, :], c=results[2, :], cmap='YlGnBu', marker='o', s=10, alpha=0.3)
      plt.colorbar()
      plt.scatter(sdp, rp, marker='*', color='r', s=500, label='Maximum Sharpe ratio')
      plt.scatter(sdp_min, rp_min, marker='*', color='g', s=500, label='Minimum volatility')
      plt.title('Simulated Portfolio Optimization based on Efficient Frontier')
      plt.xlabel('annualised volatility')
      plt.ylabel('annualised returns')
      plt.legend(labelspacing=0.8)
  
  
  display_simulated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate)
  </code></pre>