fbpx
skip to Main Content
CryptoPortfolio Optimisation Sample
%Step 1. Defining the portfolio problem.
Asset = { ‘Ethereum’, ‘Bitcoin’, ‘XRP’, ‘Ford MC’ };
Price = [ 351.4915; 2957.54; 0.2690; 11.17 ];
Holding = [ 2; 1; 100; 10 ];
UnitCost = [ 0.001; 0.001; 0.001; 0.004 ];
Blotter = dataset({Price, ‘Price’}, {Holding, ‘InitHolding’},‘obsnames’,Asset);
Wealth = sum(Blotter.Price .* Blotter.InitHolding);
Blotter.InitPort = (1/Wealth)*(Blotter.Price .* Blotter.InitHolding);
Blotter.UnitCost = UnitCost;
disp(Blotter);
Price InitHolding InitPort UnitCost Ethereum 351.49 2 0.18504 0.001 Bitcoin 2957.5 1 0.77848 0.001 XRP 0.269 100 0.0070806 0.001 Ford MC 11.17 10 0.029402 0.004
%Step 2. Simulating asset prices.
AssetMean = [ 0.05; 0.1; 0.12; 0.18 ];
AssetCovar = [ 0.0064 0.00408 0.00192 0;
0.00408 0.0289 0.0204 0.0119;
0.00192 0.0204 0.0576 0.0336;
0 0.0119 0.0336 0.1225 ];
X = portsim(AssetMean’/12, AssetCovar/12, 60); % monthly total returns for 5 years (60 months)
[Y, T] = ret2tick(X, [], 1/12); % form total return prices
plot(T, log(Y));
title(‘\bfSimulated Asset Class Total Return Prices’);
xlabel(‘Year’);
ylabel(‘Log Total Return Price’);
legend(Asset,‘Location’,‘best’);
%Step 3. Setting up the Portfolio object.
p = Portfolio(‘Name’, ‘Asset Allocation Portfolio’,
‘AssetList’, Asset, ‘InitPort’, Blotter.InitPort);
p = setDefaultConstraints(p);
p = setGroups(p, [ 1, 1, 1, 0 ], [], 0.85);
p = addGroups(p, [ 0, 0, 0, 1 ], [], 0.35);
p = setAssetMoments(p, AssetMean/12, AssetCovar/12);
p = estimateAssetMoments(p, Y, ‘DataFormat’, ‘Prices’);
p.AssetMean = 12*p.AssetMean;
p.AssetCovar = 12*p.AssetCovar;
display(p);
p =
Portfolio with properties: BuyCost: [] SellCost: [] RiskFreeRate: [] AssetMean: [4×1 double] AssetCovar: [4×4 double] TrackingError: [] TrackingPort: [] Turnover: [] BuyTurnover: [] SellTurnover: [] Name: ‘Asset Allocation Portfolio’ NumAssets: 4 AssetList: {‘Ethereum’ ‘Bitcoin’ ‘XRP’ ‘Ford MC’} InitPort: [4×1 double] AInequality: [] bInequality: [] AEquality: [] bEquality: [] LowerBound: [4×1 double] UpperBound: [] LowerBudget: 1 UpperBudget: 1 GroupMatrix: [2×4 double] LowerGroup: [] UpperGroup: [2×1 double] GroupA: [] GroupB: [] LowerRatio: [] UpperRatio: []
%Step 4. Validate the portfolio problem.
[lb, ub] = estimateBounds(p);
display([lb, ub])
0.0000 0.8500 0.0000 0.8500 0.0000 0.8500 0.1500 0.3500
%Step 5. Plotting the efficient frontier.
plotFrontier(p, 40);
%Step 6. Evaluating gross vs. net portfolio returns.
q = setCosts(p, UnitCost, UnitCost);
display(q);
q =
Portfolio with properties: BuyCost: [4×1 double] SellCost: [4×1 double] RiskFreeRate: [] AssetMean: [4×1 double] AssetCovar: [4×4 double] TrackingError: [] TrackingPort: [] Turnover: [] BuyTurnover: [] SellTurnover: [] Name: ‘Asset Allocation Portfolio’ NumAssets: 4 AssetList: {‘Ethereum’ ‘Bitcoin’ ‘XRP’ ‘Ford MC’} InitPort: [4×1 double] AInequality: [] bInequality: [] AEquality: [] bEquality: [] LowerBound: [4×1 double] UpperBound: [] LowerBudget: 1 UpperBudget: 1 GroupMatrix: [2×4 double] LowerGroup: [] UpperGroup: [2×1 double] GroupA: [] GroupB: [] LowerRatio: [] UpperRatio: []
%Step 7. Analyzing descriptive properties of the Portfolio structures.
[prsk0, pret0] = estimatePortMoments(p, p.InitPort);
pret = estimatePortReturn(p, p.estimateFrontierLimits);
qret = estimatePortReturn(q, q.estimateFrontierLimits);
displayReturns(pret0, pret, qret);
Annualized Portfolio Returns … Gross Net Initial Portfolio Return 9.32 % 9.32 % Minimum Efficient Portfolio Return 6.98 % 6.79 % Maximum Efficient Portfolio Return 14.10 % 13.81 %
%Step 8. Obtaining a Portfolio at the specified return level on the efficient frontier.
Level = 0.3;
qret = estimatePortReturn(q, q.estimateFrontierLimits);
qwgt = estimateFrontierByReturn(q, interp1([0, 1], qret, Level));
[qrsk, qret] = estimatePortMoments(q, qwgt);
displayReturnLevel(Level, qret, qrsk);
Portfolio at 30% return level on efficient frontier … Return Risk 8.90 10.64
display(qwgt);
qwgt =
0.4887 0.2690 0.0756 0.1667
%Step 9. Obtaining a Portfolio at the specified risk levels on the efficient frontier.
TargetRisk = [ 0.10; 0.15; 0.20 ];
qwgt = estimateFrontierByRisk(q, TargetRisk);
display(qwgt);
qwgt =
0.5414 0.1871 0 0.2382 0.4438 0.2912 0.0704 0.1021 0.3588 0.1500 0.2670 0.3500
display(estimatePortRisk(q, qwgt));
0.1000 0.1500 0.2000
[qwgt, qbuy, qsell] = estimateFrontierByRisk(q, 0.15);
disp(sum(qbuy + qsell)/2)
0.3347
q = setTurnover(q, 0.15);
[qwgt, qbuy, qsell] = estimateFrontierByRisk(q, 0.15);
qbuy(abs(qbuy) < 1.0e-5) = 0;
qsell(abs(qsell) < 1.0e-5) = 0; % zero out near 0 trade weights
Blotter.Port = qwgt;
Blotter.Buy = qbuy;
Blotter.Sell = qsell;
display(Blotter);
Blotter =
Price InitHolding InitPort UnitCost Port Buy Sell Ethereum 351.49 2 0.18504 0.001 0.1037 0 0.081338 Bitcoin 2957.5 1 0.77848 0.001 0.70982 0 0.068662 XRP 0.269 100 0.0070806 0.001 0.0070806 0 0 Ford MC 11.17 10 0.029402 0.004 0.1794 0.15 0
TotalCost = Wealth * sum(Blotter.UnitCost .* (Blotter.Buy + Blotter.Sell))
TotalCost = 2.8493
Blotter.Holding = Wealth * (Blotter.Port ./ Blotter.Price);
Blotter.BuyShare = Wealth * (Blotter.Buy ./ Blotter.Price);
Blotter.SellShare = Wealth * (Blotter.Sell ./ Blotter.Price);
Blotter.Buy = [];
Blotter.Sell = [];
Blotter.UnitCost = [];
%Step 10. Displaying the final results.
display(Blotter);
Blotter =
Price InitHolding InitPort Port Holding BuyShare SellShare Ethereum 351.49 2 0.18504 0.1037 1.1209 0 0.87915 Bitcoin 2957.5 1 0.77848 0.70982 0.9118 0 0.0882 XRP 0.269 100 0.0070806 0.0070806 100 0 0 Ford MC 11.17 10 0.029402 0.1794 61.018 51.018 0
plotFrontier(q, 40);
hold on
scatter(estimatePortRisk(q, qwgt), estimatePortReturn(q, qwgt), ‘filled’, ‘r’);
h = legend(‘Initial Portfolio’, ‘Efficient Frontier’, ‘Final Portfolio’, ‘location’, ‘best’);
set(h, ‘Fontsize’, 8);
hold off
Back To Top
Search