Подтвердить что ты не робот

R: оптимизация на основе исторических данных

У меня есть матрица ежемесячных возвратов и вектор прогнозов. Я хочу минимизировать риск для данного уровня доходности (исходя из прогноза). Прогнозы - это всего лишь ожидаемое изменение стоимости актива. Риск основан на пятом процентиле вектора, который является результатом передачи данного портфеля через ежемесячные доходы:

library(nloptr)
library(ggplot2)

#load csv files
balances<-as.matrix(t(c(-3300000, 2000000, -7700000, 5500000, -4000000, 1000000)))
forecast<-as.matrix(t(c(-0.000768006, 0.000635124, 0.001526249, -0.008919934, 0.000152549, 0.001271481)))
mReturns<-read.csv(file="C:/Users/Desktop/mReturns.csv", header=TRUE, sep=",", row.names=1)

mReturns<-round(mReturns, digits=8)
forecast<-round(forecast, digits=8)

colnames(balances)<-letters[1:ncol(balances)]
colnames(forecast)<-letters[1:ncol(forecast)]
colnames(mReturns)<-letters[1:ncol(forecast)]

#Minimize Variance:
fn <- function(H) {
    X<-balances * (1 - H)
    Y<-t(t(mReturns) * as.vector(X))
    return(quantile(rowSums(Y), .05, na.rm=TRUE))
}

fn2 <- function(H) {
    return(-fn(H))
}

#For a given forecast:
target<-0
eqn <- function(H) {
    X <- balances * (H)
    return(sum(X * forecast) - target)
}

loops<-6
n<-length(balances)

# Initialize a matrix to contain allocation and statistics
eff<-matrix(nrow=2+loops, ncol=n+3)
colnames(eff) <- c(colnames(balances), "Target", "Variance", "Forecast")

#Find the forecast for the 100% strategy
pars <-rep(1, n)
eff[1,1:n]<-pars
eff[1,n+2]<-fn(pars)
eff[1,n+3]<-eqn(pars)

#Find the strategy that maximizes forecast
pars2<-rep(0,n)
pars2[which(balances*forecast>=0)]<-1
eff[2,1:n]<-pars2
eff[2,n+2]<-fn(pars2)
eff[2,n+3]<-eqn(pars2)

#Constrain the values in H
lH<-rep(0, ncol(balances))
uH<-rep(1,ncol(balances))

pars2<-rep(1, n)  #initial guess is all 1's

increment = (eff[2,n+3]-eff[1,n+3])/(loops+1)
for (i in 1:loops) {
    target<-c(eff[2,n+3]-(i)*increment)  #target forecast
    sol <- auglag(pars, fn=fn2, gr=NULL, heq=eqn, lower=lH, upper=uH, nl.info = FALSE, control = list(xtol_rel = 1e-8, maxeval = 20000))
    targetHolder<-target
    target<-0
    eff[i+2,]<-c(sol$par, targetHolder, fn(sol$par), eqn(sol$par))
}

#Random Portfolios
set.seed(10)
randoms<-matrix(runif(10000*ncol(balances)), ncol=ncol(balances))
dots<-cbind(apply(randoms, 1, fn), apply(randoms, 1, eqn))

#graph
x11()
eff<-as.data.frame(eff)
dots<-as.data.frame(dots)

ggplot() +
    geom_point(data=dots, aes(V1, V2),size=3, color=rgb(115,150,0,max=255)) +
    geom_line(data=eff, aes(Variance, Forecast), size=1, color=rgb(187,8,38, max=255)) +
    geom_hline(yintercept = 0) + geom_vline(xintercept = 0) +
    ggtitle("Frontier") +
    labs(x="Variance", y="Forecast") +
    theme_bw() +
    scale_x_continuous(labels = comma) +
    scale_y_continuous(labels = comma) +
    geom_point(data=eff, aes(Variance, Forecast),size=3, color=rgb(187,8,38,max=255))

ежемесячный доход (это лучший набор, который я могу получить для иллюстрации проблемы):

                    AAA           BBB           CCC           DDD           EEE           FFF
10/1/2006 -0.0273758311 -0.0173219254 -0.0092231793 -0.0138312574 -0.0124329157 -0.0124668848
11/1/2006  0.0386007238  0.0195502377  0.0097401588  0.0115189105 -0.0125419543  0.0065488401
12/1/2006  0.0180668473  0.0380363598  0.0137722146 -0.0103839765 -0.0110926718  0.0454652348
1/1/2007   0.0006337939 -0.0111542926 -0.0301578502  0.0142295446 -0.0180118359 -0.0101971958
2/1/2007  -0.0193818090  0.0038791343 -0.0147327469  0.0171395937 -0.0106915572 -0.0135595788
3/1/2007   0.0136933213 -0.0042708969  0.0272062488 -0.0086841626  0.0051172709  0.0125940716
4/1/2007   0.0304574997  0.0047998366 -0.0017821783  0.0288433537  0.0160311962  0.0127407857
5/1/2007   0.0233737324  0.0157028153 -0.0170184226  0.0122388783  0.0387973703  0.0187209825
6/1/2007   0.0067673716 -0.0081553009 -0.0182637526  0.0680350676  0.0472285071 -0.0113937077
7/1/2007   0.0195654783  0.0132667474 -0.0086871710 -0.0124935191 -0.0042241618  0.0068406573
8/1/2007   0.0076524606  0.0118484592  0.0353900671  0.0249734320  0.0087112958  0.0093050735
9/1/2007  -0.0435798575 -0.0075768758  0.0275545857 -0.0407258270  0.0004736651 -0.0027072510
10/1/2007  0.0924749572  0.0130880968  0.0002592090  0.0845218362  0.0644348088  0.0440939105
11/1/2007  0.0201274740  0.0179104478  0.0093311906  0.0350746684  0.0427970555  0.0136322114
12/1/2007 -0.0305820454 -0.0114417576  0.0308341887 -0.0249386286 -0.0477620911  0.0144194107
1/1/2008  -0.0093848937 -0.0339930944 -0.0036721437  0.0069662916  0.0061454765 -0.0028018861
2/1/2008   0.0321881064 -0.0107229158  0.0484552051  0.0198235360 -0.0027127500  0.0143914474
3/1/2008   0.0294150171  0.0122131189  0.0265085560  0.0323534622  0.0075926301  0.0254695311
4/1/2008  -0.0254592330 -0.0066361671  0.0185567006 -0.0307842234 -0.0328013313  0.0286580144
5/1/2008   0.0291005291 -0.0005567083 -0.0247055516  0.0492000484  0.0012745099 -0.0089663123
6/1/2008   0.0239931448  0.0037978529 -0.0103297983  0.0218807620  0.0267767258  0.0051699625
7/1/2008  -0.0010460251  0.0063562528 -0.0057476747  0.0181476849 -0.0281745247  0.0153658223
8/1/2008  -0.0270157068 -0.0099754374 -0.0146689710  0.0243589740 -0.0048676019 -0.0145000950
9/1/2008  -0.0848041326 -0.0878987342 -0.0039763301 -0.0543735223 -0.0370300926 -0.0608455410
10/1/2008 -0.0740827846 -0.0175974242  0.0228906428 -0.1397058821  0.0037639971 -0.0415954026
11/1/2008 -0.1518923038 -0.0915974459  0.0736264752 -0.1118110238 -0.1235463915 -0.0915839817
12/1/2008 -0.0413297394 -0.0741477980  0.0566584579 -0.0762846012 -0.0286790030 -0.0090366179
1/1/2009   0.1018431740 -0.0138403655  0.0268870859  0.0098509388  0.0231128587  0.1137102530
2/1/2009  -0.0962574426 -0.0094018259  0.0092303638 -0.0036590625 -0.0077260893 -0.0877180491
3/1/2009   0.0023529412 -0.0152682256 -0.0784996236 -0.0266487893 -0.0365901429 -0.0112385858
4/1/2009   0.0943661972  0.0104763235 -0.0096417819  0.0496085860  0.0129365079  0.0457810403
5/1/2009   0.0447590448  0.0313104783 -0.0059523944  0.0459061643  0.0631117103  0.0018114575
6/1/2009   0.1088146729  0.1020038871  0.0261932537  0.1138436318  0.0838591685  0.0667520530
7/1/2009  -0.0019750648  0.0021285653 -0.0007242318  0.0099870620 -0.0487995829 -0.0012006498
8/1/2009   0.0338899196  0.0142614395  0.0209125845  0.0361374737  0.0668151452  0.0081318060
9/1/2009  -0.0118435220 -0.0330880153  0.0189410175 -0.0253958301 -0.0240898396 -0.0023146525
10/1/2009  0.0529055690 -0.0126856436  0.0369378363  0.0711407143  0.0187286653  0.0225674916
11/1/2009  0.0344946533  0.0312127860 -0.0053280313  0.0144219837 -0.0008296452  0.0119628738
12/1/2009  0.0281204846  0.0096031119  0.0393401412  0.0235369340  0.0368954311  0.0245940621
1/1/2010  -0.0291891892 -0.0276924929 -0.0683577530 -0.0136428779 -0.0062689978 -0.0501956104
2/1/2010  -0.0073496659 -0.0119497245  0.0268182226 -0.0560575728 -0.0073543270 -0.0274364703
3/1/2010   0.0106573929 -0.0605965660  0.0166050081  0.0279786409  0.0184367195 -0.0266312540
4/1/2010   0.0224220224  0.0200787139 -0.0499893623  0.0188144624  0.0325203247  0.0021386431
5/1/2010   0.0034741070 -0.0011770861 -0.0003196447  0.0144877542 -0.0091364566 -0.0217087350
6/1/2010  -0.1007248729 -0.0407882676  0.0318856314 -0.0586643576 -0.0355315523 -0.0801113284
7/1/2010   0.0146775746  0.0359019862  0.0382420201  0.0316565244 -0.0039637605  0.0243683048
8/1/2010   0.0720891629  0.0337352573  0.0130681681  0.0206279554  0.0290375846  0.0419094755
9/1/2010   0.0082946251 -0.0149149085  0.0240407343  0.0050973650 -0.0191465044 -0.0186178363
10/1/2010  0.0665789185  0.0238757684  0.0146598812  0.0333195239  0.0295184853  0.0766648450
11/1/2010  0.0151172357  0.0133973711  0.0336604101 -0.0078097478  0.0044326247  0.0073961279
12/1/2010 -0.0190456894 -0.0257545523 -0.0437106512 -0.0011144347 -0.0017699119 -0.0542719355
1/1/2011   0.0568005783 -0.0007040901  0.0378451737  0.0262445077  0.0190380763  0.0186467768
2/1/2011  -0.0119222124  0.0339482449 -0.0028272754 -0.0018625333  0.0074702196  0.0332486551
3/1/2011   0.0022747503  0.0077437740 -0.0062301897  0.0003004991  0.0162084538 -0.0037602140
4/1/2011   0.0249654628 -0.0095899674 -0.0261717073  0.0354075923  0.0120431890  0.0333889816
5/1/2011   0.0562241263  0.0369933586  0.0353491621  0.0200583972  0.0191514125  0.0400365245
6/1/2011  -0.0325403336 -0.0223259711  0.0029648152 -0.0117927481 -0.0328489560 -0.0323495644
7/1/2011   0.0146975692 -0.0159177176  0.0014845420  0.0245501284  0.0195096504  0.0138190955
8/1/2011   0.0186629526  0.0138111236  0.0468851189 -0.0064491408  0.0015673977 -0.0190004131
9/1/2011  -0.0226961991 -0.0071796760  0.0036396795 -0.0330925481 -0.0203705594  0.0006315789
10/1/2011 -0.0988621526 -0.0367760677 -0.0016869980 -0.1381365404 -0.0698847952 -0.0611543587
11/1/2011  0.0690333264  0.0234214579 -0.0167155471  0.0770244711  0.0293022346  0.0236049899
12/1/2011 -0.0082292574 -0.0162392626  0.0086228941 -0.0306649633  0.0064108885 -0.0176603663
1/1/2012  -0.0034166341 -0.0093690249  0.0102717068 -0.0357295909 -0.0072456670 -0.0371443429
2/1/2012   0.0485845822  0.0187222544  0.0093176468  0.0763997010  0.0227318248  0.0154309081
3/1/2012   0.0097150864  0.0077680940 -0.0606509309  0.0117255850  0.0132927441  0.0113973102
4/1/2012  -0.0428346748  0.0031960895 -0.0211174021 -0.0616378357 -0.0132171821  0.0024040267
5/1/2012  -0.0011598685  0.0133058471  0.0347109283 -0.0427081690  0.0134970570 -0.0079442404
6/1/2012  -0.0612541126 -0.0528943962  0.0265316552 -0.0646046778 -0.0534101827 -0.0606632923
7/1/2012   0.0553551180  0.0223914600 -0.0221831931  0.0152781926  0.0240015740  0.0187389416
8/1/2012   0.0217815980 -0.0108868657  0.0172106230 -0.0170718584  0.0109387431 -0.0348938186
9/1/2012  -0.0132874486  0.0212409887  0.0006377956  0.0066476282  0.0195680830  0.0289570552
10/1/2012  0.0037783375  0.0166393546  0.0051289010  0.0019735538  0.0040720757  0.0245647508
11/1/2012  0.0038606312  0.0000000000 -0.0265851526 -0.0022644484 -0.0142498744  0.0042675357
12/1/2012  0.0025959042 -0.0072535648 -0.0286130154 -0.0489700375  0.0021118266  0.0033222591
1/1/2013  -0.0031645570  0.0147380254 -0.0486735937  0.0411386231  0.0010066431  0.0167873094
2/1/2013   0.0011544012 -0.0342174903 -0.0654305847  0.0319919529 -0.0031108877  0.0330202969
3/1/2013  -0.0196021908 -0.0417383547 -0.0087616625  0.0041925528 -0.0295091542 -0.0453079179
4/1/2013   0.0215622856  0.0127011571  0.0038614299 -0.0203384796  0.0098347756 -0.0132852096
5/1/2013  -0.0138156001  0.0214065270 -0.0427148166  0.0097436671  0.0084300305  0.0257607596
6/1/2013  -0.0688782956 -0.0229508197 -0.0304629093 -0.0652935412 -0.0281445781 -0.0137329287
7/1/2013  -0.0347926027  0.0012501645  0.0079269110 -0.0394347242 -0.0116223686  0.0050003846
8/1/2013  -0.0338817926 -0.0063744496  0.0012055870 -0.0326360551  0.0145950131  0.0109461115
9/1/2013  -0.0026890756  0.0253968254  0.0139553083 -0.0340809061 -0.0181266017  0.0011357613
10/1/2013  0.0558364229  0.0445691434  0.0017347621  0.0762463339  0.0208292961  0.0229919831
11/1/2013  0.0042562247 -0.0166100648 -0.0067903218 -0.0165498253 -0.0094049904 -0.0028833358
12/1/2013 -0.0349650350  0.0277533593 -0.0368020343 -0.0351883563 -0.0182777460  0.0077111292
1/1/2014  -0.0243741765  0.0120967742 -0.0266983220 -0.0110494902 -0.0028184893  0.0126554337
2/1/2014  -0.0146297547 -0.0076663045  0.0314581713 -0.0210129322 -0.0434938896 -0.0201264259
3/1/2014   0.0191868433  0.0186142709  0.0023576343  0.0292198115  0.0057845269  0.0234317070
4/1/2014   0.0361945316 -0.0068677217 -0.0178485935  0.0364295499  0.0036284465 -0.0006520794
5/1/2014   0.0029198659  0.0158147925  0.0128994503  0.0132598662  0.0062066454  0.0055825419
6/1/2014   0.0038818201 -0.0081690641  0.0055025913 -0.0041043938  0.0101419878 -0.0169430425
7/1/2014   0.0200859291  0.0235750522  0.0023639137  0.0179844668  0.0201279157  0.0032269894
8/1/2014  -0.0194798357 -0.0191836735 -0.0105253101 -0.0247154181 -0.0260168559 -0.0184223993
9/1/2014   0.0021477663 -0.0126627430 -0.0166746378  0.0052540178  0.0041394531 -0.0222685633
10/1/2014 -0.0636519503 -0.0254094412 -0.0416934585 -0.0947966609 -0.0261578426 -0.0384673979
11/1/2014  0.0068665599 -0.0118003213 -0.0305377641  0.0013318247 -0.0091425528 -0.0077636061
12/1/2014 -0.0348942942 -0.0165676774 -0.0513513556 -0.0323739586 -0.0055609505 -0.0043912176
1/1/2015  -0.0362737016 -0.0091544819 -0.0111909311 -0.0364614693 -0.0242873130 -0.0293504411
2/1/2015  -0.0514481242 -0.0337482356  0.0191506171 -0.0094300950 -0.0880458693 -0.0671678784
3/1/2015   0.0059263077  0.0250996016 -0.0178885567 -0.0557158943  0.0173391939 -0.0084137809
4/1/2015  -0.0266393443 -0.0398367664 -0.0010855227 -0.1022781142 -0.0083987014 -0.0386745266
5/1/2015   0.0330263158  0.0219253862 -0.0032458554  0.0498921894  0.0379965466  0.0405091517
6/1/2015  -0.0312062158  0.0034988117 -0.0370281860 -0.0485734132 -0.0289889795 -0.0242878828
7/1/2015   0.0051275309  0.0273666206  0.0129901792  0.0060967874 -0.0054011118  0.0115310698
8/1/2015  -0.0440810988  0.0003201639 -0.0058116534 -0.0795580758 -0.0382705683 -0.0062426491
9/1/2015  -0.0395457033 -0.0203559083  0.0378654941 -0.0749722897 -0.0126706388  0.0301347414
10/1/2015  0.0015671748 -0.0113042342 -0.0046693964 -0.0775158974 -0.0006783238 -0.0106053911
11/1/2015  0.0153627312  0.0196285771 -0.0057204213  0.0398620240  0.0143730891 -0.0168825368
12/1/2015  0.0259176240 -0.0224267565 -0.0183120461  0.0007267065 -0.0208114991 -0.0338906051
1/1/2016  -0.0027311211 -0.0222782124  0.0192451285 -0.0272167213 -0.0358715265  0.0209724443
2/1/2016  -0.0258797754 -0.0212260952 -0.0036366319 -0.0007064285 -0.0066676232  0.0029476787
3/1/2016   0.0085746416 -0.0333264048  0.0612226330  0.0074985366  0.0401193145 -0.0018368846
4/1/2016   0.0699651568  0.0197104358  0.0207718249  0.1070122134  0.0306663595  0.0481229297
5/1/2016  -0.0096391820  0.0270612216  0.0487323576  0.0343442572  0.0362376556  0.0052673163
6/1/2016  -0.0455083520 -0.0134136326 -0.0277524101 -0.0460086088 -0.0399143600 -0.0229674264
7/1/2016   0.0332093151 -0.0797031077  0.0684744419  0.1128105301  0.0128562573 -0.0046478370
8/1/2016   0.0050680181 -0.0066329992  0.0012697102 -0.0089113465 -0.0161536118  0.0024245690
9/1/2016   0.0019904459  0.0067531679 -0.0081372403  0.0025174229  0.0016026871  0.003045776

Как вы можете видеть, красная линия - это не самый эффективный набор решений: введите описание изображения здесь

4b9b3361

Ответ 1

Я бы пошел с квантильной сплайновой регрессией (пакет fields). Здесь я сделал модель, чтобы она соответствовала 10% точек (просто чтобы запустить ее быстрее для примера).

library(fields)
dots <- dots[base::sample(NROW(dots), 1000), ]
fit90 = qsreg(x=dots$V1, y=dots$V2, alpha=0.95, lam=1E7)
plot(x=dots$V1, y=dots$V2, main=("alpha=95%"))
points(x=dots$V1, y=fitted(fit90), col="red")

Затем вы можете tweek параметры, чтобы выбрать порог, который вам подходит (90%, 95%, 99% от предела ваших очков), а затем играть с аргументом лямбда, чтобы получить сглаживание, которое вы хотите (оно идет 0 до бесконечности.)

введите описание изображения здесь

Ответ 2

Одна вещь, которая поможет с визуализацией, - показать непрозрачность. Добавив альфу к вашей эстетике, вы увидите данные на глубине лучше.

Например:

ggplot() +
    geom_point(data=dots, aes(V1, V2),size=3, color=rgb(115,150,0,max=255), alpha=0.05) +
    geom_line(data=eff, aes(Variance, Forecast), size=1, color=rgb(187,8,38, max=255)) +
    geom_hline(yintercept = 0) + geom_vline(xintercept = 0) +
    ggtitle("Frontier") +
    labs(x="Variance", y="Forecast") +
    theme_bw() +
    scale_x_continuous(labels = comma) +
    scale_y_continuous(labels = comma) +
    geom_point(data=eff, aes(Variance, Forecast),size=3, color=rgb(187,8,38,max=255))

Это обеспечивает: введите описание изображения здесь

Теперь ваша оптимизация выглядит намного лучше.

Ответ 3

У меня нет достаточного количества баллов для комментариев, но похоже, что вам нужна функция оптимизации среднего отклонения. (Тем не менее, есть трудности в этом подходе: см. документ, который я написал для получения более подробной информации.)

В любом случае, вы можете попробовать функцию portfolio.optim из пакета tseries. Вот пример кода:

portfolio.optim(x, pm = mean(x), riskless = FALSE, shorts = FALSE,
rf = 0.0, reslow = NULL, reshigh = NULL, covmat = cov(x), ...)

Чтобы дать вам больше информации, вы можете найти эти слайды полезными.

Я надеюсь, что это поможет вам.


ИЗМЕНИТЬ (теперь у меня было немного времени, чтобы рассмотреть детали.)

Из того, что мне кажется, ваши инвестиции немного противоречат друг другу. В конце концов, некоторые инвестиции с более высоким риском имеют наименьшую ожидаемую прибыль и наоборот. Здесь подробно:

library(ggplot2)
library(tseries)
library(scales)
library(dplyr)

# Load csv files (with a modified reference in my code)
forecast<-as.matrix(t(c(-0.000768006, 0.000635124, 0.001526249, -0.008919934, 0.000152549, 0.001271481)))
mReturns<-read.csv(file="mReturns.csv", header=TRUE, sep=",", row.names=1)

# Consider inputs to mean-variance optimiser
mRet <- matrix(unlist(mReturns), nrow = 120, ncol = 6, byrow = FALSE)
colnames(mRet) <- c("AAA", "BBB", "CCC", "DDD", "EEE", "FFF")
vc <- cov(mRet)
cor <- cor(mRet)
print(round(cor, 2))

Этот код дает эту корреляционную матрицу ежемесячных возвратов:

     AAA   BBB   CCC  DDD  EEE  FFF
AAA 1.00  0.58  0.05 0.77 0.73 0.74
BBB 0.58  1.00 -0.10 0.45 0.57 0.61
CCC 0.05 -0.10  1.00 0.02 0.01 0.05
DDD 0.77  0.45  0.02 1.00 0.64 0.53
EEE 0.73  0.57  0.01 0.64 1.00 0.57
FFF 0.74  0.61  0.05 0.53 0.57 1.00

И теперь для других входов оптимизатору:

returnStats <- data_frame(name = c("AAA", "BBB", "CCC", "DDD", "EEE", "FFF"), 
                          ret = as.numeric(forecast), 
                          vol = sqrt(apply(mRet, 2, var)))
inputs <- returnStats
inputs[, 2:3] <- round(100*inputs[, 2:3], 2)
print(inputs)

И это дает ожидаемый (прогнозируемый) доход и волатильность каждой инвестиции:

   name   ret   vol
  <chr> <dbl> <dbl>
1   AAA -0.08  4.17
2   BBB  0.06  2.74
3   CCC  0.15  2.84
4   DDD -0.89  4.60
5   EEE  0.02  2.94
6   FFF  0.13  3.12

Итак, как я упоминал выше, это странные входы (поскольку они были введены выше):

  • Инвестиции со второй по величине волатильностью имеют наивысший ожидаемый доход (CCC)
  • Инвестиции с наивысшей волатильностью имеют самый низкий ожидаемый доход (DDD)

Все это упрощает ответ prima facie: распределите партии в CCC. Несомненно, влияние диверсификации второго порядка может означать, что вы не распределяете все на CCC, не выбираете также некоторые FFF, учитывая его профиль риска и низкий коэффициент корреляции между этими двумя инвестициями.

И все это подтверждается конечными точками эффективной границы. (Я сохранил границу в обратном пространстве, так как это проще интерпретировать. Кстати, вы также можете использовать пакет PortfolioAnalytics, если хотите.)

# Build efficient frontier
effFrontier = function (averet, rcov, nports = 8, shorts=FALSE, wmax=1)
{
  mxret = max(abs(averet))
  mnret = -mxret
  n.assets = ncol(averet)
  reshigh = rep(wmax,n.assets)
  if( shorts )
  {
    reslow = rep(-wmax,n.assets)
  } else {
    reslow = rep(0,n.assets)
  }
  min.rets = seq(mnret, mxret, len = nports)
  vol = rep(NA, nports)
  ret = rep(NA, nports)
  for (k in 1:nports)
  {
    port.sol = NULL
    try(port.sol <- portfolio.optim(x=averet, pm=min.rets[k], covmat=rcov,
                                    reshigh=reshigh, reslow=reslow,shorts=shorts),silent=T)
    if ( !is.null(port.sol) )
    {
      vol[k] = sqrt(as.vector(port.sol$pw %*% rcov %*% port.sol$pw))
      ret[k] = averet %*% port.sol$pw
    }
  }
  return(list(vol = vol, ret = ret))
}

# Run efficient frontier
eF <- effFrontier(averet=forecast, rcov=vc, shorts = FALSE, nports = 100)
eff <- as_data_frame(eF)

Все, что остается, это построить эту границу:

ggplot() +
  geom_line(data=eff, aes(vol, ret), size=1, color=rgb(187,8,38, max=255)) +
  geom_hline(yintercept = 0) + geom_vline(xintercept = 0) +
  ggtitle("Frontier") +
  labs(x="Volatility", y="Forecast") +
  theme_bw() +
  scale_x_continuous(labels = percent) +
  scale_y_continuous(labels = percent) +
  geom_point(data=eff, aes(vol, ret), size=3, color=rgb(187,8,38,max=255))

И этот код создает эту диаграмму:

Оптимизация портфеля

Разрыв в 2% волатильности и инверсия этой границы говорят о характере ваших инвестиций.

Извините, что расширенный ответ занял некоторое время, но я надеюсь, что это поможет вам немного больше.