top of page

Implementing Mean Variance portfolio optimization method with C++


In the last post, I constructed the matrix computation class, which is the main tool that I gonna use in portfolio optimization.

First, what is mean variance method? In plain language, under Markowitz's assumption, the assets have two attributes--risk and return and the are receptively measured by variance-covariance and rate of return. The return of the portfolio is simply the summition of assets' returns while the risk of the portfolio will be the sum of all assets' variance and the covariance between each other. Our aim is to find the combination of assets that could yield the given expected return while having minimum total variance.

For a deeper understanding of mean-variance method, one may refer to

Lyuu Y.D. 's Financial Engineering and Computation-Principles, Mathematics, and Algorithms Chapter 31.

After understanding the theoretical knowledge it become much easier to apply it into practice. For clear mathematical expression of this method, one can refer to:

Bernt Arne Odegaard's Financial Numerical Recipes in C++

As suggested in the book, the problem becomes a series of matrix computation:

Note "1" denotes simple column vector with elements=1;

"V" is the variance-covariance matrix

"e" is a single column vector contains the return of each asset.

This is the same thing as the black-board picture at the beginning of the article( which actually costs me 1.5 hours to figure out.... :(

Ok, let roll~

For the program:

Before the comment "//START", I was loading data from a .txt file. In the txt file, each asset's data occupies a line. Before loading data, the user has to tell the compiler how many assets there are in the portfolio and this number has to be the exact number as it is in the data file.

You might find it hard to understand this part :

for (int i = 0; i < indatas.size(); i++) { temp0.push_back(indatas[i]); if ((((i + 1) % (indatas.size() / num)) == 0) && i != 0) { pricevec.push_back(temp0); temp0.clear(); } } for (int i = 0; i < pricevec.size(); i++) { vector<double>temp; for (int j = 0; j < pricevec[0].size() - 1; j++) { temp.push_back((pricevec[i][j + 1] - pricevec[i][j]) / pricevec[i][j]); } ratevec.push_back(temp); }

actually what I did is only to put appropriately the data into a matrix in the form that each row contains the data of an asset. It must be easier to rewrite this from your own usage than reading others.

When the data is safely lying in our matrix, the task has been finished by 90%. what we do next is to operate the matrix using the tool we developed before. Simply following the mathematical expression and carefully perform the matrix operation, you will get the right answer.

**

I upload all the data file and relative code files in the category "C++"

*******************************************************************************************************

#include"CarlsMatrixCalculator.h" #include<fstream>

int main() { cout << " Minimum Variance Frontier Project" << endl; vector<vector<double>> variance; vector<vector<double>> e;

//input datas ifstream infile; infile.open("pdata.txt"); double x; bool mark = 1; vector<double> indatas; vector<double>::iterator inda; int num; cout << "Please input the numbers of assets in the portfolio " << endl; cin >> num;

while (mark) { infile >> x; if (infile) { indatas.push_back(x); } else { mark = 0; if (infile.eof()) { cout << endl; cout << '\t' << '\t' << '\t' << "---***End of The File***---" << endl<<endl; } else cout << "Wrong file!" << endl; } }

vector<vector<double>>pricevec; vector<vector<double>>ratevec; vector<double>temp0; for (int i = 0; i < indatas.size(); i++) { temp0.push_back(indatas[i]); if ((((i + 1) % (indatas.size() / num)) == 0) && i != 0) { pricevec.push_back(temp0); temp0.clear(); } } for (int i = 0; i < pricevec.size(); i++) { vector<double>temp; for (int j = 0; j < pricevec[0].size() - 1; j++) { temp.push_back((pricevec[i][j + 1] - pricevec[i][j]) / pricevec[i][j]); } ratevec.push_back(temp); }

// START! //Crucial paras; double a; double b; double c; double D; double rate = 0.1;

Matrix carl; variance = carl.covariance(ratevec); //carl.show_matrix(variance); e = carl.average; //carl.show_matrix(e); //carl.show_matrix(ratevec);

cout << "Covariance Matrix: " << endl; carl.show_matrix(variance); cout << "Expected return of stocks: " << endl; carl.show_matrix(e); cout << "Expected return of the portfolio: " << rate << endl; vector<vector<double>> v_inverse = carl.inverse(variance); cout << "Inverse of Variance Matrix" << endl; carl.show_matrix(v_inverse); cout << endl; //calculate A vector<vector<double>>one_tran = carl.generator(num, "r"); vector<vector<double>>temp = carl.multiplication(one_tran, v_inverse); temp = carl.multiplication(temp,e); a = temp[0][0]; cout << "a : " << a << endl;

//carlculate B temp = carl.trans(e); temp = carl.multiplication(temp, v_inverse); temp = carl.multiplication(temp, e); b = temp[0][0]; cout << "b: " << b << endl;

// calculate C temp = carl.multiplication(one_tran, v_inverse); temp = carl.multiplication(temp, carl.trans(one_tran)); c = temp[0][0]; cout << "c: " << c << endl;

// calculate D D = b*c - a*a; cout << "D :" << D << endl;

//calculating g; vector<vector<double>>temp2; cout << endl; temp = carl.scale(b, one_tran); temp2 = carl.scale(a, carl.trans(e)); temp = carl.subtraction(temp, temp2); temp = carl.multiplication(temp, v_inverse); temp = carl.scale(1.0 / D, temp); vector<vector<double>>g = temp; cout << "Matrix g: "; carl.show_matrix(temp); //calculating h; temp = carl.scale(c, carl.trans(e)); temp2 = carl.scale(a, one_tran); temp = carl.subtraction(temp, temp2); temp = carl.multiplication(temp, v_inverse); temp = carl.scale(1.0 / D, temp); vector<vector<double>>h = temp; cout << "Matrix h: "; carl.show_matrix(temp); //calculating w cout << endl; vector<vector<double>>wp; temp = carl.scale(rate, h); temp = carl.addition(g, temp); wp = temp; cout << "The Resulted weight of portfolio wp "; carl.show_matrix(wp);

vector<vector<double>>test; vector<double>firstrow; vector<double>firstrow2; firstrow.push_back(0.0365994); firstrow.push_back(-7.277); test.push_back(firstrow); firstrow2.push_back(-7.277); firstrow2.push_back(0.00443548); test.push_back(firstrow2);

test = carl.inverse(test); carl.show_matrix(test);

return 0; }


Who Am I?

Hello, My name is Tongda (Carl). I am currently a Math Finance graudate student at BU. I am fan of innovation and funny ideas! You can reach my by  LinkedIn below :)

Follow Me
  • LinkedIn Social Icon
bottom of page