# Portfolio optimization

**URL:** <https://discuss.ampl.com/t/portfolio-optimization/862>\
**Category:** Support\
**Created:** [December 17, 2023, 6:35am UTC](https://discuss.ampl.com/t/portfolio-optimization/862 "2023-12-17T06:35:10Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 17, 2023, 6:35am UTC](https://discuss.ampl.com/t/portfolio-optimization/862/1 "2023-12-17T06:35:10Z")

</div>

Hi,I am trying to insert min max values of variance and return into the objective function but I could not. No,I reviewed but I want to insert min-max normalization values into the risk adjusted return objective function.I want to define normalization for return and variance into one equation.I wrote  
stocks\_in\_sample = data[stocks][t - tau : t]

# n = 19

```
mu = expected_returns.mean_historical_return(stocks_in_sample,frequency=1)
Sigma = risk_models.sample_cov(stocks_in_sample, frequency=1)
risk_aversion=lr_predictions
weight=generate_random_weights(19, seed=None)
min_return=np.min(np.sum((weight*mu)))
max_return=np.max(np.sum((weight*mu)))
min_variance=np.min(np.sum((weight*mu*np.transpose(weight))))
max_variance=np.max(np.sum((weight*mu*np.transpose(weight)))) 
m = AMPL()
m.eval(
 r"""
        

 set A ordered;
 param risk_aversion;
 param Sigma{A, A};
 param mu{A};
 param lb default 0;
 param ub default 1;
 var w{A} >= lb <= ub;
 param min_return{A};
 param max_return{A};
 param min_variance{A};
 param max_variance{A};
     
 maximize risk_adjusted_return:
     risk_aversion*((sum {i in A} mu[i] * w[i]-min_return)/(max_return-min_return)+(1-risk_aversion)*((sum {i in A, j in A} w[i] * Sigma[i, j] * w[j]-min_variance)/(max_variance-min_variance));
        
 s.t. portfolio_weights:
 sum {i in A} w[i] = 1;
 
"""

```

)  
m.set[“A”] = stocks\_in\_sample

m.param[“mu”] = mu  
m.param[“risk\_aversion”] = risk\_aversion  
m.param[“Sigma”] = Sigma  
m.param[“min\_return”]=min\_return  
m.param[“max\_return”]=max\_return  
m.param[“min\_variance”]=min\_variance  
m.param[“max\_variance”]=max\_variance

m.option[“solver”] = “gurobi”  
m.solve()  
m.solve(verbose=False)

I got Error: line 17 offset 380 syntax error context: risk\_aversion\*((sum {i in A} mu[i] \* \>\>\> w[i]-min\_return) \<\<\< /(max\_return-min\_return)+(1-risk\_aversion)\*((sum {i in A, j in A} w[i] \* Sigma[i, j] \* w[j]-min\_variance)/(max\_variance-min\_variance));

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 18, 2023, 11:21am UTC](https://discuss.ampl.com/t/portfolio-optimization/862/3 "2023-12-18T11:21:54Z")

</div>

Hi @Firdevs_Uykun,

In the objective definition you have some parameters that are not scaler without specifying the index and there were also some missing parenthesis.

You can write that objective as follows:

```auto
maximize risk_adjusted_return:
    risk_aversion * (
        (sum {i in A} (mu[i] * w[i] - min_return[i]))
            /
        (sum {i in A} (max_return[i] - min_return[i]))
    ) + (1-risk_aversion) * (
        (sum {i in A, j in A} (w[i] * Sigma[i, j] * w[j] - min_variance[i]))
            /
        (sum {i in A} (max_variance[i] - min_variance[i]))
    );

```

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 18, 2023, 7:27pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/4 "2023-12-18T19:27:25Z")

</div>

Hi,I am trying to solve multiperiod markowitz model,  
min\_var = AMPL()  
min\_var.eval(  
r"“”

```
 set A ordered;
 
 
 param risk_aversion;
 param risk_free;
 param Sigma{A, A};
 param mu{A};
 param R_min;
 param R_max;
 param Var_min;
 param Var_max;
 var w{A} >=0;
        
 maximize risk_adjusted_return:
     risk_aversion*((sum {i in A} mu[i] * w[i]- R_min)/(R_max-R_min))+
     (1-risk_aversion)*((sum {i in A, j in A} w[i] * Sigma[i, j] * w[j]- Var_min)/(Var_max - Var_min));
    
 
 s.t. sum_of_weights: sum{i in A} w[i] == 1;
 s.t.portfolio_return:
 sum {i in A} mu[i] * w[i]=(sum {i in A} mu[i] * w[i])+(sum {i in A} mu[i] * w[i] - sum {i in A} w[i])*risk_free;

"""

```

)

```
min_var.set["A"] = stocks_in_sample
min_var.param["mu"] = mu
min_var.param["risk_aversion"] = risk_aversion
min_var.param["Sigma"] = Sigma
min_var.param["R_min"]=R_min
min_var.param["R_max"]=R_max
min_var.param["Var_min"]=Var_min
min_var.param["Var_max"]=Var_max
min_var.param["risk_free"]=risk_free
min_var.option["solver"] = "gurobi"
min_var.solve()

```

but I got error:  
Warning: presolve, constraint sum\_of\_weights: all variables eliminated, but lower bound = 1 \> 0 Please report any bugs at: [GitHub - ampl/amplpy: Python API for AMPL](https://github.com/ampl/amplpy) For support/feedback go to [https://discuss.ampl.com](https://discuss.ampl.com/) or e-mail [support@ampl.com](mailto:support@ampl.com) Infeasible constraints determined by presolve.

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 19, 2023, 8:07pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/5 "2023-12-19T20:07:51Z")

</div>

Hi @Firdevs_Uykun,

The constraint portfolio return fixes all variables `w` to 0 if `rist_free` is non-zero:

```auto
 s.t. portfolio_return:
     sum {i in A} mu[i] * w[i] =
        (sum {i in A} mu[i] * w[i])+
        (sum {i in A} mu[i] * w[i] - sum {i in A} w[i]) * risk_free;

```

It is equivalent to:

```auto
 s.t. portfolio_return:
     0 = (sum {i in A} mu[i] * w[i] - sum {i in A} w[i]) * risk_free;

```

To make it quicker to debug these errors in the future, you can add `min_var.snapshot("snapshot.run")` right before `min_var.solve()` to produce a file that you can send to us and that allows us to reproduce the error right away.

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 19, 2023, 8:26pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/6 "2023-12-19T20:26:30Z")

</div>

I am trying to write as a constraint: xt+1 = e0 \*t xt + Pt′\*ut but when I try to define time as set I got error,my data in the for loop so can I ignore Time in the AMPL syntax expression,I saw MAD portfolio optimization in python-AMPL book,Do I need to write exactly what mathematics expression?

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 19, 2023, 8:41pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/7 "2023-12-19T20:41:29Z")

</div>

![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/dbbb06fc9e27f5135cda40cb25c6f30417c8b677.png)  
I am trying to write with summation equivalent.

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 19, 2023, 10:58pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/8 "2023-12-19T22:58:06Z")

</div>

You can add a new index to variable `w` for the time period. Then `sum {i in A} mu[i] * w[i,t]` will be the total expected return for time `t`. You can also have another index for `mu` so that you can use different expected returns for each time period.

However, are you looking for something like the following?

```auto
 s.t. inital_total_weights: sum{i in A} w[i, 0] == 1;
 s.t. portfolio_return_carried_over{t in T: t > 1}:
     sum {i in A} mu[i, t] * w[i, t-1] = sum {i in A} w[i, t];

```

If `mu[i,t]` is the expected relative return for asset `i` in period `t`, this carries over the returns from period t-1 to t. Note that for all time periods other than 1 the sum of weights will be different from 1 and you may need to be careful if you do anything that only works under that assumption.

If you could provide a reference with the full model you are trying to implement in mathematical notation, it would likely help figuring out the best way to model it.

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 11:02am UTC](https://discuss.ampl.com/t/portfolio-optimization/862/9 "2023-12-20T11:02:37Z")

</div>

Okay,thanks for your answers,first of all, I want to write multiperiod variance equation, variance depends on time. In MAD portfolio optimization you wrote var w{ASSETS}; means weights do not change over time,but their optimized value change over time.I define for variance :  
for t in range(tau, len(data)):  
stocks\_in\_sample = data[stocks][t - tau : t]  
#for time indexing  
stocks\_in\_sample[“Date”] = stocks\_in\_sample.index.format()  
stocks\_in\_sample.set\_index(“Date”, inplace=True)  
mu = calculate\_returns(stocks\_in\_sample)  
Sigma = risk\_models.sample\_cov(stocks\_in\_sample, frequency=1)  
TIME=stocks\_in\_sample.index.values  
m = AMPL()  
m.eval(  
r"“”

```
 set A ordered;
 set TIME ordered;

 param Sigma{t in TIME,A,A};
 param mu{t in TIME,A};
 param lb default 0;
 param ub default 1;
 var w{t in TIME,A} >= lb <= ub;
        
 minimize portfolio_variance:
    sum {t in TIME,i in A, j in A} w[t,i] * Sigma[t,i, j] * w[t,j];
        
 s.t. portfolio_weights:
 sum {t in TIME,i in A} w[t,i] = 1;

"""

```

)  
m.set[“A”] = stocks\_in\_sample  
m.param[“mu”] = mu  
m.param[“Sigma”] = Sigma  
m.set[“TIME”] = TIME  
m.option[“solver”] = “gurobi”  
m.solve()  
Var\_min=m.get\_value(“sum {t in TIME,i in A, j in A} w[t,i] \* Sigma[t,i, j] \* w[t,j]”)  
R\_min = m.get\_value(“sum {i in A,t in TIME} mu[t,i] \* w[t,i]”)

Then I got error:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/5f560fe49312da195b4e1ae9efcb5284307986e4.png)  
Time is :  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/7b7f61e044442f121eee5bdf28a1818bbd97d244.png)

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 20, 2023, 6:23pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/10 "2023-12-20T18:23:31Z")

</div>

You need to load the indexing set of `mu` before being able to load values into it. Otherwise you get the error about missing data for set `TIME` since it is not available when you try to load the values for `mu`. You can do that as follows:

```auto
m.set["TIME"] = TIME
m.param["mu"] = mu

```

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 7:16pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/11 "2023-12-20T19:16:46Z")

</div>

Thanks,that s true,  
m = AMPL()  
m.eval(  
r"“”

```
 set A;
 set Time;
 

 param Sigma{t in Time,A, A};
 param mu{Time,A};
 param lb default 0;
 param ub default 1;
 var w{Time,A} >= lb <= ub;
        
 minimize portfolio_variance {t in Time}:
    sum {i in A, j in A} w[t,i] * Sigma[t,i, j] * w[t,j];
        
 s.t. portfolio_weights {t in Time}:
 sum {i in A} w[t,i] = 1;

"""

```

)  
m.set[“A”] = list(stocks\_in\_sample.columns)  
m.set[“Time”] = stocks\_in\_sample.index.values  
m.param[“mu”] = mu  
m.param[“Sigma”] = Sigma  
m.option[“solver”] = “gurobi”  
m.solve()  
Then I got :

 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/7c5c52aedc0f350ec67baac1d1686905edbda00a.png)  
and mu has the form:  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/86730805671daf51eaa68b5cf5954a5fe403f13e.png)

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 7:25pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/12 "2023-12-20T19:25:42Z")

</div>

I solved the expected return just depend assets, then I got following message:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/111349751109f42885f376d96ea1ed744d6577c8.png)  
My sigma for 26 day period: 19\*19 matrix:  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/4c64e85a9dfe51895e87f8d759bb606c6fa9c35f.png)

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 20, 2023, 8:05pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/13 "2023-12-20T20:05:45Z")

</div>

You have `Sigma` defined as `Sigma{t in Time,A, A};` so you need to have a DataFrame with three indices.

What is the output of `display(Sigma.stack())`? In order to be able to load it, there must be 3 indices and 1 data column.

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 8:10pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/14 "2023-12-20T20:10:49Z")

</div>

![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/134ba079adcb0308a792f3e0abed4504daa5e0ad.png)

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 8:13pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/15 "2023-12-20T20:13:10Z")

</div>

I want to sure one thing,I am using for loop for data iteration set,I divide data periods as 26 day,still in the AMLP syntax I have to write Time,right?

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 20, 2023, 8:21pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/16 "2023-12-20T20:21:12Z")

</div>

To load the data in that dataframe you need to have `Sigma` defined as `param Sigma{A, A};`. However, if you want to use Sigma values for multiple time windows you need to build a dataframe with all Sigmas indexed over Time and pairs of assets (i.e., 3 indices).

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 8:31pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/17 "2023-12-20T20:31:53Z")

</div>

I am trying to formulate mean variance optimization with rebalancing, first I need minimum variance,your sigma calculates for 26 week time period,also I got optimization solution for variance:  
minimize portfolio\_variance {t in Time}:  
sum {i in A, j in A} w[t,i] \* Sigma[i,j] \* w[t,j];  
In the notation Sigma does not have t,is that true? Sigma recalculated as Sigma = risk\_models.sample\_cov(stocks\_in\_sample, frequency=1) and stocks\_in\_sample = data[stocks][t - tau : t], How can I store the optimized values?

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 20, 2023, 9:37pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/18 "2023-12-20T21:37:32Z")

</div>

You suggest  
s.t. portfolio\_return\_carried\_over {t in Time}:  
sum {i in A} mu[i] \* w[i,t+1]=(sum {i in A} mu[i] \* w[i,t])+(sum {i in A} mu[i] \* w[i,t] - sum {i in A} w[i,t])\*risk\_free;  
I tried then get:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/e98246cbe67b59df679218c135ef1bcbb3d5a226.png)  
How can I solve,I mentioned the equation above as a picture

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 21, 2023, 2:32pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/19 "2023-12-21T14:32:37Z")

</div>

For the sigma for 26 weeks you can do the following:

```python
n_slices = 26
slices = np.array_split(prices, n_slices)
dfs = []
for i, slice_df in enumerate(slices):
    df = risk_models.risk_matrix(slice_df, method="exp_cov").stack().to_frame()
    df.reset_index(inplace=True) # Turn the index into regular data columns
    df.columns = ["Stock1", "Stock2", "S"] # Adjust column names
    df["Time"] = i # Add new column with the index of the slice
    dfs.append(df)

df = pd.concat(dfs) # Concatenate all dataframes
df.set_index(["Time", "Stock1", "Stock2"], inplace=True) # Set the index to be (Time, Stock1, Stock2)
display(df)

```

This will produce a dataframe in the right format to be loaded into `param Sigma{Time, A, A};`:

 ![Screenshot 2023-12-21 at 14.25.52](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/5d124ef2a579e92d7a36aefd6e4dde6a07dfb14c.png)

Regarding the error with `portfolio_return_carried_over`, you got that error because you used strings for time instead of the week number. So t+1 is invalid. However, you can define `Time` as an ordered set with `set Time ordered;` and then instead of `t+1` you can use `next(t)`. You can learn more about sets and ordered sets in Chapter 5 of the AMPL Book: [AMPL Book - Guide for modelers at all levels of experience](https://ampl.com/learn/ampl-book/)

---

<div class="post-metadata">

**Author:** ![Firdevs\_Uykun](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/firdevs_uykun/32/528_2.png) [@Firdevs\_Uykun](https://discuss.ampl.com/u/Firdevs_Uykun)\
**Post date:** [December 22, 2023, 7:50pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/20 "2023-12-22T19:50:57Z")

</div>

hi,thanks for help,  
My code as follows:  
tau=26  
for t in range(tau, len(data)):  
stocks = [  
‘HD’, ‘MCD’, ‘NKE’, ‘KO’, ‘PG’, ‘SYY’, ‘WMT’, # Consumer Staples  
‘CVX’, ‘XOM’, # Energy  
‘AXP’, ‘JPM’, # Financials  
‘JNJ’, ‘MRK’, ‘PFE’, ‘WBA’, # Health Care  
‘BA’, ‘CAT’, ‘MMM’, # Industrials  
‘IRX’,# Information Technology#t-bill  
]  
stocks\_in\_sample = data[stocks][t - tau : t]  
mu = expected\_returns.mean\_historical\_return(stocks\_in\_sample,frequency=1)  
dfs =   
for i, slice\_df in enumerate(stocks\_in\_sample.values):  
df = risk\_models.risk\_matrix(slice\_df, method=“sample\_cov”).stack().to\_frame()  
df.reset\_index(inplace=True) # Turn the index into regular data columns  
df.columns = [ ‘HD’, ‘MCD’, ‘NKE’, ‘KO’, ‘PG’, ‘SYY’, ‘WMT’, # Consumer Staples  
‘CVX’, ‘XOM’, # Energy  
‘AXP’, ‘JPM’, # Financials  
‘JNJ’, ‘MRK’, ‘PFE’, ‘WBA’, # Health Care  
‘BA’, ‘CAT’, ‘MMM’, # Industrials  
‘IRX’,“S”] # Adjust column names  
df[“Time”] = i # Add new column with the index of the slice  
dfs.append(df)

```
df = pd.concat(dfs) # Concatenate all dataframes
df.set_index(["Time", 'HD', 'MCD', 'NKE', 'KO', 'PG', 'SYY', 'WMT', # Consumer Staples
    'CVX', 'XOM', # Energy
    'AXP', 'JPM', # Financials
    'JNJ', 'MRK', 'PFE', 'WBA', # Health Care
    'BA', 'CAT', 'MMM', # Industrials
    'IRX' ], inplace=True) # Set the index to be (Time, Stock1, Stock2)
display(df)

```

Then I got following error;

 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/9e4e5ecf4481be0eed890e722b673f2af918de31.png)  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/ampl/original/1X/b7db6210f0e350b576c5c91b7b325115ce95669b.png)  
I downloaded weekly data from Yahoo Finance and ,my stocks\_in\_sample.shape is (26,19).

---

<div class="post-metadata">

**Author:** ![fdabrandao](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.ampl.com/fdabrandao/32/63_2.png) [@fdabrandao](https://discuss.ampl.com/u/fdabrandao)\
**Post date:** [December 22, 2023, 9:33pm UTC](https://discuss.ampl.com/t/portfolio-optimization/862/21 "2023-12-22T21:33:45Z")

</div>

`df.columns = ["Stock1", "Stock2", "S"]` sets the names for the three columns. You are trying to assign a list with more than 3 elements and that is why you are getting that error. Right before this line you can use `display(df)` to see how the dataframe looks like at that point. The line above stacks the dataframe so there are no ticker names across both axis anymore.

[Next page](https://discuss.ampl.com/t/portfolio-optimization/862.md?page=2)
