Tuesday, September 20, 2016

R: optimization based on historical data

Leave a Comment

I have a matrix of monthly returns and a vector of forecasts. I want to minimize my risk for a given level of return (based on the forecast). The forecasts are just the anticipated % change in value of the asset. The risk is based on the 5th percentile of the vector that is the result of passing a given portfolio through the monthly returns:

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)) 

monthly returns (this is the best set I can get for illustrating the problem):

                    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 

As you can see, the red line is not the most efficient set of solutions: enter image description here

3 Answers

Answers 1

I would go with quantile spline regression (package fields). Here I did the model to fit 10% of the points (just to run it faster for the example).

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") 

Then you can tweek the parameters to choose the threshold that suits you (90%, 95%, 99% of the limit of your points) and then play with the lambda argument to get the smoothing you want (it goes fro 0 to infinite..)

enter image description here

Answers 2

One thing that will help with the visualization is to show opacity. By adding an alpha to your aesthetics you will see the data in depth better.

For example:

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)) 

This provides: enter image description here

Now your optimization looks a lot better.

Answers 3

I don't have a high enough score to comment, but it looks like you need a mean-variance optimisation function. (That said, there are difficulties in this approach: see a paper that I wrote for more details.)

Anyway, you could try the portfolio.optim function from the package tseries. Here's an example of the code:

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

To give you some more background, you may find these slides useful.

I hope that helps you.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment