-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathportfolio_optimisation.cpp
More file actions
157 lines (127 loc) · 5.17 KB
/
Copy pathportfolio_optimisation.cpp
File metadata and controls
157 lines (127 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <bits/stdc++.h>
struct Asset {
std::string name;
double expectedReturn;
double risk;
};
struct PortfolioMetrics {
double portfolioReturn;
double portfolioRisk;
double sharpeRatio;
double sortinoRatio;
double maxDrawdown;
};
std::vector<double> optimizePortfolio(const std::vector<Asset>& assets, double targetReturn) {
int numAssets = assets.size();
std::vector<double> portfolioWeights(numAssets, 1.0 / numAssets);
double portfolioReturn = 0.0;
double portfolioRisk = 0.0;
for (int i = 0; i < numAssets; i++) {
portfolioReturn += portfolioWeights[i] * assets[i].expectedReturn;
portfolioRisk += std::pow(portfolioWeights[i] * assets[i].risk, 2);
}
portfolioRisk = std::sqrt(portfolioRisk);
if (portfolioReturn < targetReturn) {
for (int i = 0; i < numAssets; i++) {
double adjustedWeight = (assets[i].expectedReturn - portfolioReturn) / (targetReturn - portfolioReturn);
portfolioWeights[i] = std::max(0.0, adjustedWeight);
}
double totalWeight = 0.0;
for (int i = 0; i < numAssets; i++) {
totalWeight += portfolioWeights[i];
}
for (int i = 0; i < numAssets; i++) {
portfolioWeights[i] /= totalWeight;
}
}
return portfolioWeights;
}
double calculatePortfolioValue(const std::vector<double>& portfolioWeights, const std::vector<Asset>& assets, double investment) {
double portfolioValue = 0.0;
for (int i = 0; i < assets.size(); i++) {
double assetValue = portfolioWeights[i] * investment;
portfolioValue += assetValue;
std::cout << assets[i].name << " Value: " << assetValue << std::endl;
}
std::cout << "Portfolio Value: " << portfolioValue << std::endl;
return portfolioValue;
}
double calculateSharpeRatio(double portfolioReturn, double portfolioRisk, double riskFreeRate) {
return (portfolioReturn - riskFreeRate) / portfolioRisk;
}
double calculateSortinoRatio(double portfolioReturn, double portfolioRisk, double riskFreeRate, const std::vector<Asset>& assets) {
double downsideRisk = 0.0;
for (const Asset& asset : assets) {
double assetReturn = asset.expectedReturn;
double assetRisk = asset.risk;
if (assetReturn < riskFreeRate) {
downsideRisk += std::pow(assetRisk, 2);
}
}
downsideRisk = std::sqrt(downsideRisk);
if (downsideRisk == 0.0) {
return 0.0;
}
return (portfolioReturn - riskFreeRate) / downsideRisk;
}
double calculateMaxDrawdown(const std::vector<double>& portfolioValues) {
double maxDrawdown = 0.0;
double peakValue = 0.0;
for (double value : portfolioValues) {
if (value > peakValue) {
peakValue = value;
} else {
double drawdown = (peakValue - value) / peakValue;
if (drawdown > maxDrawdown) {
maxDrawdown = drawdown;
}
}
}
return maxDrawdown;
}
PortfolioMetrics analyzePortfolio(const std::vector<Asset>& assets, const std::vector<double>& portfolioWeights,
double riskFreeRate, double investment) {
PortfolioMetrics metrics;
int numAssets = assets.size();
std::vector<double> portfolioValues(numAssets, 0.0);
double portfolioReturn = 0.0;
double portfolioRisk = 0.0;
for (int i = 0; i < numAssets; i++) {
portfolioValues[i] = portfolioWeights[i] * investment;
portfolioReturn += portfolioWeights[i] * assets[i].expectedReturn;
portfolioRisk += std::pow(portfolioWeights[i] * assets[i].risk, 2);
}
portfolioRisk = std::sqrt(portfolioRisk);
metrics.portfolioReturn = portfolioReturn;
metrics.portfolioRisk = portfolioRisk;
metrics.sharpeRatio = calculateSharpeRatio(portfolioReturn, portfolioRisk, riskFreeRate);
metrics.sortinoRatio = calculateSortinoRatio(portfolioReturn, portfolioRisk, riskFreeRate, assets);
metrics.maxDrawdown = calculateMaxDrawdown(portfolioValues);
return metrics;
}
int main() {
std::vector<Asset> assets = {
{"Asset 1", 0.05, 0.1},
{"Asset 2", 0.08, 0.15},
{"Asset 3", 0.12, 0.18},
{"Asset 4", 0.09, 0.12},
{"Asset 5", 0.07, 0.14}
};
double targetReturn = 0.10;
double investment = 10000.0;
double riskFreeRate = 0.03;
std::vector<double> portfolioWeights = optimizePortfolio(assets, targetReturn);
std::cout << "Portfolio Weights:\n";
for (int i = 0; i < assets.size(); i++) {
std::cout << assets[i].name << ": " << portfolioWeights[i] << std::endl;
}
double portfolioValue = calculatePortfolioValue(portfolioWeights, assets, investment);
PortfolioMetrics metrics = analyzePortfolio(assets, portfolioWeights, riskFreeRate, investment);
std::cout << "Portfolio Metrics:\n";
std::cout << "Portfolio Return: " << metrics.portfolioReturn << std::endl;
std::cout << "Portfolio Risk: " << metrics.portfolioRisk << std::endl;
std::cout << "Sharpe Ratio: " << metrics.sharpeRatio << std::endl;
std::cout << "Sortino Ratio: " << metrics.sortinoRatio << std::endl;
std::cout << "Max Drawdown: " << metrics.maxDrawdown << std::endl;
return 0;
}