# Chris Daigle
## Convex Optimization w/ Python
## Exam


```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sympy import *
from cvxpy import *
```


```python
df = pd.read_csv(
    '/Users/daiglechris/Git/ConvexOptimizationWithPython/Data/Stocks2-closeP.csv', 
    sep = ",")
```


```python
df.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>timestamp</th>
      <th>F_close</th>
      <th>BA_close</th>
      <th>RTN_close</th>
      <th>VLO_close</th>
      <th>AAL_close</th>
      <th>CI_close</th>
      <th>IBM_close</th>
      <th>PG_close</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2018-12-03</td>
      <td>9.60</td>
      <td>359.96</td>
      <td>172.87</td>
      <td>81.30</td>
      <td>39.65</td>
      <td>224.84</td>
      <td>125.31</td>
      <td>93.32</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2018-11-30</td>
      <td>9.41</td>
      <td>346.76</td>
      <td>175.34</td>
      <td>79.90</td>
      <td>40.16</td>
      <td>223.38</td>
      <td>124.27</td>
      <td>94.51</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2018-11-29</td>
      <td>9.37</td>
      <td>342.56</td>
      <td>173.58</td>
      <td>79.47</td>
      <td>38.42</td>
      <td>222.52</td>
      <td>121.48</td>
      <td>92.82</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2018-11-28</td>
      <td>9.41</td>
      <td>333.50</td>
      <td>173.61</td>
      <td>79.42</td>
      <td>38.94</td>
      <td>221.72</td>
      <td>123.00</td>
      <td>93.01</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2018-11-27</td>
      <td>9.28</td>
      <td>318.03</td>
      <td>171.67</td>
      <td>77.43</td>
      <td>38.29</td>
      <td>216.80</td>
      <td>120.03</td>
      <td>92.72</td>
    </tr>
  </tbody>
</table>
</div>



### Question 1:
(a) Compute the one day returns $\left (\dfrac{p_{t+1}-p_{t}}{p_{t}} \right )$ of each stock and find the mean and the variance of each stock's returns.


```python
oneDayReturns = df.iloc[:,1:].apply(lambda x: ((x - (x.shift(1))) / (x.shift(1))))
names = list(oneDayReturns.columns)
meansOfReturns = pd.DataFrame(oneDayReturns.describe().iloc[1].abs(),
                              index = names)
meansOfReturns1 = abs(oneDayReturns.describe().iloc[1].values)
varianceOfReturns = oneDayReturns.var()
table = pd.concat([meansOfReturns, varianceOfReturns],
                  axis = 1)
table.columns = ['Mean of the Returns', 'Variance of the Returns']
table
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Mean of the Returns</th>
      <th>Variance of the Returns</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>F_close</th>
      <td>0.001533</td>
      <td>0.000352</td>
    </tr>
    <tr>
      <th>BA_close</th>
      <td>0.000098</td>
      <td>0.000331</td>
    </tr>
    <tr>
      <th>RTN_close</th>
      <td>0.001566</td>
      <td>0.000214</td>
    </tr>
    <tr>
      <th>VLO_close</th>
      <td>0.003054</td>
      <td>0.000501</td>
    </tr>
    <tr>
      <th>AAL_close</th>
      <td>0.000345</td>
      <td>0.000649</td>
    </tr>
    <tr>
      <th>CI_close</th>
      <td>0.002542</td>
      <td>0.000194</td>
    </tr>
    <tr>
      <th>IBM_close</th>
      <td>0.001668</td>
      <td>0.000267</td>
    </tr>
    <tr>
      <th>PG_close</th>
      <td>0.001568</td>
      <td>0.000145</td>
    </tr>
  </tbody>
</table>
</div>



|**Name of Stock**| **Mean of the Returns** | **Variance of the Returns**    |
|------------|:--------------------------------------------:|--------------:|
| Ford       | 0.001533| 0.000352  |
| Boeing     | 0.000098| 0.000331 |
| Raytheon       | 0.001566| 0.000214 |
| Valero Energy     | 0.003054 | 0.000501 |
| American Airlines       | 0.000345 | 0.000649  |
| Cigna     |0.002542| 0.000194|
| IBM       | 0.001668| 0.000267 |
| Procter & Gamble     | 0.001568|0.000145|

(b) Plot the returns of the stocks with the two highest variance and the stocks with the two highest mean. Save a pdf copy of you graphs with “plt.savefig(ʼsample.pdfʼ). Send the pdf file to olivier.morand@uconn.edu with “graph-your name” in the title of your email.



```python
highestVar = table.sort_values(by = 'Variance of the Returns',
                               axis = 0,
                               ascending=False).head(2)
highestMean = table.sort_values(by = 'Mean of the Returns',
                                axis = 0,
                                ascending=False).head(2)
dfHighest = pd.concat([highestMean, highestVar])
dfReturnHighest = oneDayReturns[dfHighest.T.columns]
```


```python
dfReturnHighest.plot(grid = True, 
                     figsize = (12,8)).axhline(y = 0, 
                                               color = "black", 
                                               lw = 2)
plt.title('Returns of the stocks with the two highest variance and the stocks with the two highest mean')
plt.savefig('graph-Daigle.pdf')
plt.show()
```

### Question 2:
Two clients, John and Jane, have asked you for help to build a portfolio in which to invest their income. You seek a combination of the 8 stocks that will maximize each clientʼs utility. A portfolio is a vector $X = (x_{1}, ..., x_{8})$ with $\forall i = 1, ... 8$, $0 \le x_{i} \le 1$ and $\sum_{i=1}^{8} x_{i} = 1$ where $x_{i}$ is the fraction of income to be spend on asset $i$. Both clients have utility: 
$$X.\overline{R}^{T} - \frac{1}{2}AX\Sigma X^{T}$$
where $\overline{R}$ is the $1 \times 8$ vector of means calculated in 1, and $\Sigma$ is the $8 \times 8$ covariance matrix of returns. John is risk averse and his risk coefficient is $A = 2$ while Jane's coefficient is $A = 10$.

(a) Explain below why the problem is convex.

The problem is convex because the Hessian Matrix of $X\Sigma X^{T}$ is positive semidefinite (PSD), $\frac{1}{2} A$ only scales the value of $X\Sigma X^{T}$, and the first portion $X.\overline{R}^{T}$ is just a vector of scalars, singleton or otherwise. So, we only need to evaluate the Hessian of $X\Sigma X^{T}$.


```python
x1, x2, x3, x4, x5, x6, x7, x8 = symbols('ford, Boeing, Raytheon, Valero, AmericanAir, Cigna, IBM, PG')
X = np.array([x1, x2, x3, x4, x5, x6, x7, x8])
R = meansOfReturns
Sigma = oneDayReturns.cov()
Z = np.array(X*Sigma*X.T)
```


```python
def hessian(x):
    """
    Calculate the hessian matrix with finite differences
    Parameters:
       - x : ndarray
    Returns:
       an array of shape (x.dim, x.ndim) + x.shape
       where the array[i, j, ...] corresponds to the second derivative x_ij
    """
    x_grad = np.gradient(x) 
    hessian = np.empty((x.ndim, x.ndim) + x.shape, dtype=x.dtype) 
    for k, grad_k in enumerate(x_grad):
        # iterate over dimensions
        # apply gradient again to every component of the first derivative.
        tmp_grad = np.gradient(grad_k) 
        for l, grad_kl in enumerate(tmp_grad):
            hessian[k, l, :, :] = grad_kl
    return hessian
```


```python
H = hessian(np.array(Sigma))
np.linalg.det(H)
```




    array([[ 2.20799925e-63, -6.76560985e-48],
           [-7.95272270e-48, -3.57667386e-65]])



This works out to a series of zeros in the matrix. I'm not sure why there are 4 values, but regardless, zero times any real value is zero and thus, the matrix is PSD and the problem is thus convex.

(b) Solve for Jane's and Johns' optimal portfolio. Write your answer below


```python
mu = meansOfReturns1

w = Variable(8) # Decision variable

gamma = 2 # Risk Parameter in the utility function
ret = mu*w
risk = quad_form(w, Sigma)

obj = Maximize(ret - gamma*risk)
constraints = [sum(w) == 1 , w >=0]

# Form the problem
prob = Problem(obj, constraints)
```


```python
port_data = []
ret_data = []
risk_data = []
prob_data = []

gamma_vals = [2,10]
for i in range(2):
    gamma = gamma_vals[i]
    prob.solve() # Solve the problem for a specific value of gamma
    risk_data.append(sqrt(risk).value) # optimal value of the risk (standard deviation)
    ret_data.append(ret.value) # optimal value of the return
    prob_data.append(prob.value) # maximum utility
    port_data.append(w.value)  
```


```python
print(np.sum(port_data[0]))
print(np.sum(port_data[1]))
```

    1.0000000000000788
    1.0000000000000788


Checking that the proportions add to 1. Because of floating point arithmetic, the value is not exactly 1, but the results "check out"


```python
results = pd.DataFrame(
    {"John's Optimal Portfolio":port_data[0],
     "Jane's Optimal Portfolio":port_data[1]},
    index= ['Ford', 'Boeing', 'Raytheon', 
                  'Valero', 'American Airlines', 
                  'Cigna', 'IBM', ' PG'])
results
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>John's Optimal Portfolio</th>
      <th>Jane's Optimal Portfolio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>Ford</th>
      <td>7.262696e-08</td>
      <td>7.262696e-08</td>
    </tr>
    <tr>
      <th>Boeing</th>
      <td>2.046956e-08</td>
      <td>2.046956e-08</td>
    </tr>
    <tr>
      <th>Raytheon</th>
      <td>6.250528e-08</td>
      <td>6.250528e-08</td>
    </tr>
    <tr>
      <th>Valero</th>
      <td>4.409146e-01</td>
      <td>4.409146e-01</td>
    </tr>
    <tr>
      <th>American Airlines</th>
      <td>2.174878e-08</td>
      <td>2.174878e-08</td>
    </tr>
    <tr>
      <th>Cigna</th>
      <td>5.590849e-01</td>
      <td>5.590849e-01</td>
    </tr>
    <tr>
      <th>IBM</th>
      <td>7.084433e-08</td>
      <td>7.084433e-08</td>
    </tr>
    <tr>
      <th>PG</th>
      <td>2.445910e-07</td>
      <td>2.445910e-07</td>
    </tr>
  </tbody>
</table>
</div>




```python

```


```python

```

2b5887ab24f171d5f1390e5c6adc9f796a9abb96
ipynb
Jupyter Notebook
Exam/DaigleExam.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Exam/DaigleExam.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Exam/DaigleExam.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Qwen/Qwen-72B
1. YES
2. YES