Vi allego il foglio excel ove è riportato il listato originale, merito di Paolo 1956 e la traduzione per "R" fatta da Cren.
Una volta scaricato e digerito, possiamo iniziare la discussione per trovare eventuali falle e tentare di sviluppare la vocazione del modello:
un portafoglio flessibile azionario - obbligazionario che possa esprimere rendimenti positivi superiori alla componente obbligazionaria minimizzando, in virtu della correlazione negativa o nulla, i draw downs.
Io in 7 mesi di test e ricerche, non ho trovato bugs eclatanti; credo che il modello abbia potenzialità non comuni (se applicato alla componente "reddito fisso" che è la più pesante) ed una facilità di impiego imbarazzante, poichè appare egualmente valido su indici (faccio sempre l'esempio del DJES600), costituenti degli stessi, futures, ETF e, appunto, obbligazioni (scadenza più lontana che segue la scadenza leader con maggiore volatilità e rendimenti, un esempio da testare)-
E' un trend follower, con i difetti ed i pregi di un trend follower ma, con una differenza fondamentale.
Si difende molto, molto bene, se la componente più rischiosa non mostra trend definiti (non su o giù, ma su e giù ampi e possibilmente volatili), va short con pochissimi soldi (leva implicita dei rendimenti negativi solitamente più ampi dei positivi), riversa la maggiorparte del capitale in assets si crede meno rischiosi (obbligazioni) , assets che fungono da copertura margini in caso di impiego con futures (esempio).
library(PerformanceAnalytics) library(quantmod) library(TTR) #alpha:=0.81; Questo valore sembra un'ottimizzazione ma non lo è...e risulta ottimo su tutti i sottostanti che ho testato. #Ann:=12; #mv:=Input("Max Volat Richiesta:",0,500,3.5); #Leva:=Input("Leva:",0,10,1); #rf:=Input("Risk Free Disponibile:",0,100,3); #ss:=1.2; Questa è una blanda ottimizzazione..è uno shift verticale alla media che vedrai usata come soglia. #alpha1:="Frequenza Ribilanciamento Size:" = 0.97; alpha <- .81 Ann <- 12 mv <- 3.5 Leva <- 1 rf <- 3 ss <- 1.2 alpha1 <- .97 #sec:=S&P500 MENSILE getSymbols('^GSPC', from = '1900-01-01') sec <- to.monthly(GSPC) #r:=100*Log(SEC/Ref(SEC,-1)); r <- diff(log(Cl(sec))) * 100 #k:=PREV*alpha+r*(1-alpha)+ss/ann; k <- EMA(r, ratio = 1 - alpha) + ss / Ann #dt:=If(r<k,1,0); dt <- ifelse(r < k, 1, 0) #lpm:=(PREV*alpha +(r*dt-k)*(1-alpha)); lpm <- EMA(r * dt - k, ratio = 1 - alpha) #dt:=If(r>k,1,0); dt <- ifelse(r > k, 1, 0) #hpm:= (PREV*alpha +Abs(k-r*dt)*(1-alpha)); hpm <- EMA(abs(k - r * dt), ratio = 1 - alpha) #TAR:=(hpm+lpm)+k; TAR <- hpm + lpm + k #dtx:=If(Ref(tar,-1)>0,1,0); dtx <- ifelse(lag(TAR) > 0, 1, 0) #dtx1:=If(Ref(tar,-1)<0,-1,0); dtx1 <- ifelse(lag(TAR) < 0, -1, 0) #mr:=PREV*alpha+r*(1-alpha); mr <- EMA(r, ratio = 1 - alpha) #volat:=Sqr(Power(PREV,2)*(alpha)+(1-alpha)*Power(r-mr,2)); volat <- sqrt(EMA((r - mr) ^ 2, ratio = 1 - alpha)) #volat:=mv/(volat*Sqr(ann)); volat <- mv / volat * sqrt(Ann) #osa:=If(TAR*volat<0,0,tar*volat); osa <- ifelse(TAR * volat < 0, 0, TAR * volat) #osa:=PREV*alpha1+(If(osa>leva,leva,osa))*(1-alpha1); osa <- EMA(ifelse(osa > Leva, Leva, osa), ratio = 1 - alpha1) #r:=100*Log(C/Ref(C,-1)) -----> C=DAX MENSILE getSymbols('^GDAXI', from = '1990-01-01') C <- Cl(to.monthly(GDAXI)) r <- diff(log(C)) * 100 osa <- na.omit(merge(r, osa))[,2] r <- na.omit(merge(r, osa))[,1] #equity:=Cum(r*Ref(osa,-1)*dtx+r*Ref(osa,-1)*dtx1+(rf/ann)*(1-Ref(osa,-1))); returns <- na.omit(r * lag(osa) * dtx + r * lag(osa) * dtx1 + rf / Ann * (1- lag(osa))) equity <- cumsum(returns) # ********************************* # Performance analysis # ********************************* charts.PerformanceSummary(R = cbind(returns / 100, r / 100), ylog = TRUE, Rf = rf / 100, methods = 'HistoricalES', gap = 12) Omega(R = returns / 100, L = rf / 100) table.DownsideRisk(R = returns / 100, MAR = rf / (100 * 12)) table.Returns(R = returns / 100)