Test in R: “Faber Portfolio” – Parte 1

Dopo le dovute introduzioni, entriamo nel vivo dell’utilizzo dell’ambiente, e lo faremo in un articolo diviso in più parti.

Partendo da un test relativamente semplice, ne approfitteremo per spiegare i primi elementi di R e dei package per il Trading Algoritmico che utilizzeremo.

Il test utilizzerà un listato preso dal blog “FOSS Trading”, e si basa sulla strategia descritta nell’ articolo: Faber, Mebane T., – “A Quantitative Approach to Tactical Asset Allocation.” – Journal of Risk Management (Spring 2007).

In questo articolo gli autori descrivono una strategia da applicare allo SPY:

  • comprare quando il prezzo di chiusura del titolo supera la SMA a 10 mesi,
  • chiudere e incassare quando la SMA a 10 mesi supera il prezzo di chiusura del titolo.

Le candele sono mensili. In questa strategia si entra solo in long, mai in short.

Tengo a precisare che questa è una strategia che riporto qui solo per spiegare come funziona R, non è consigliabile utilizzarla in reale (almeno senza le opportune verifiche).

Riporto prima il listato e dopo spiegherò le singole parti.

# This code implements the strategy found in:
# Faber, Mebane T., “A Quantitative Approach to Tactical Asset Allocation.”
# Journal of Risk Management (Spring 2007).
# The article implements a simpler version of the 200-day SMA, opting for a
# 10-month SMA because monthly data are more easily available in earlier
# periods and lower granularity should translate to lower transaction costs.
# The rules of the system are relatively simple:
# – Buy when monthly price > 10-month SMA
# – Sell and move to cash when monthly price < 10-month SMA
# 1. All entry and exit prices are on the day of the signal at the close.
# 2. All data series are total return series including dividends, updated monthly.
# NOTE: For the purposes of this demo, we only use price returns.
# 3. Cash returns are estimated with 90-day commercial paper. Margin rates for
# leveraged models are estimated with the broker call rate.
# NOTE: For the purposes of this demo, we ignore interest and leverage.
# 4. Taxes, commissions, and slippage are excluded.
# Data:
# This demo uses monthly data downloaded from Yahoo Finance for two ETFs: SPY and
# IEF. These were chosen to illustrate the classic stock/bond asset portfolio.
# Though longer serires would be preferred, data for IEF begin in mid-2002.
# Load required libraries
library(quantmod)
library(TTR)
library(blotter) # r-forge revision 193
library(PerformanceAnalytics)
# Set initial values
initDate=’2006-07-31′
endDate=’2012-01-31′
initEq=100000
# Set currency and instruments
currency(“USD”)
stock(“IEF”,currency=”USD”,multiplier=1)
stock(“SPY”,currency=”USD”,multiplier=1)
# Load data with quantmod
print(“Loading data”)
symbols = c(“IEF”, “SPY”)
getSymbols(symbols, from=initDate, to=endDate, index.class=c(“POSIXt”,”POSIXct”))
# Adjust prices for splits/dividends (thanks pg)
#IEF = adjustOHLC(IEF)
#SPY = adjustOHLC(SPY)
# Convert data to monthly frequency (to.weekly() needs drop.time=FALSE)
IEF = to.monthly(IEF, indexAt=’endof’)
SPY = to.monthly(SPY, indexAt=’endof’)
# Set up indicators with TTR
print(“Setting up indicators”)
IEF$SMA = SMA(Cl(IEF), 10)
SPY$SMA = SMA(Cl(SPY), 10)
# Set up a portfolio object and an account object in blotter
initPortf(name=’default’, symbols=symbols, initDate=initDate)
initAcct(name=’default’, portfolios=’default’, initDate=initDate, initEq=initEq)
verbose = TRUE
# Create trades
for( i in 10:NROW(SPY) ) {
  CurrentDate=time(SPY)[i]
  equity = getEndEq(Account=’default’, CurrentDate)
  for( symbol in symbols ) {
    sym = get(symbol)
    ClosePrice = as.numeric(Cl(sym[i,]))
    Posn = getPosQty(Portfolio=’default’, Symbol=symbol, Date=CurrentDate)
    UnitSize = as.numeric(trunc((equity/NROW(symbols))/ClosePrice))
    # Position Entry (assume fill at close)
    if( Posn == 0 ) {
    # No position, so test to initiate Long position
      if( Cl(sym[i,]) > sym[i,’SMA’] ) {
        # Store trade with blotter
        addTxn(‘default’, Symbol=symbol, TxnDate=CurrentDate,
          TxnPrice=ClosePrice, TxnQty=UnitSize, TxnFees=0, verbose=verbose)
      }
    } else {
      # Have a position, so check exit
      if( Cl(sym[i,]) < sym[i,’SMA’] ) {
        # Store trade with blotter
        addTxn(Portfolio=’default’, Symbol=symbol, TxnDate=CurrentDate,
          TxnPrice=ClosePrice, TxnQty=-Posn, TxnFees=0, verbose=verbose)
      }
    }
  } # End symbols loop
  # Calculate P&L and resulting equity with blotter
  updatePortf(Portfolio=’default’, Dates=CurrentDate)
  updateAcct(name=’default’, Dates=CurrentDate)
  updateEndEq(Account=’default’, Dates=CurrentDate)
} # End dates loop
# Buy and Hold cumulative equity
buyhold = exp(cumsum( ( 0.5*ROC(Cl(IEF)) + 0.5*ROC(Cl(SPY)) )[-1] ))
# Final values
cat(‘Tactical Asset Allocation Return: ‘,(getEndEq(Account=’default’, Date=CurrentDate)-initEq)/initEq,’\n’)
cat(‘Buy and Hold Return: ‘,tail(buyhold,1)-1,’\n’)
# Plot Strategy Summary
png(filename=”20091118_blotter_strategy.png”, 720, 720)
#charts.PerformanceSummary(ROC(getAccount(‘default’)$TOTAL$End.Eq)[-1],main=”Tactical Asset Allocation”)
charts.PerformanceSummary(ROC(getAccount(‘default’)$summary$End.Eq)[-1],main=”Tactical Asset Allocation”)
dev.off()
# Plot Buy and Hold Summary
png(filename=”20091118_blotter_buyhold.png”, 720, 720)
charts.PerformanceSummary(ROC(buyhold)[-1],main=”Buy & Hold”)
dev.off()

Cominciamo a spiegare passo passo, in modo da mostrare, anche a chi desidera conoscere R un pò più in dettaglio, un assaggio di cosa si può fare con questo ambiente di calcolo sfruttando la potenza dei package di Trading Algoritmico.

Il carattere “#” serve per i commenti. In R esiste solo il commento per la singola riga.

La sezione:

# Load required libraries
library(quantmod)
library(TTR)
library(blotter) # r-forge revision 193
library(PerformanceAnalytics)

carica i packages specializzati per il Trading Algoritmico che utilizzeremo. I packages devono essere installati nell’ambiente. L’installazione avviene in maniera molto semplice utilizzando la function install.packages(), che riesce a installare i packages anche direttamente da internet. Per l’uso basta fare riferimento alla documentazione di R.
La sezione:

# Set initial values
initDate=’2006-07-31′
endDate=’2012-01-31′
initEq=100000

setta i valori che ci servono. I primi due valori sono le date, l’altro è il capitale iniziale. Da notare che le date sono delle stringhe, il formato da utilizzare per l’indicizzazione delle strutture dati “xts”.

La sezione:

# Set currency and instruments
currency(“USD”)
stock(“IEF”,currency=”USD”,multiplier=1)
stock(“SPY”,currency=”USD”,multiplier=1)

setta la moneta da utilizzare e i titoli che saranno utilizzati per il test.

Nella sezione seguente si nota qualcosa di molto interessante:

# Load data with quantmod
print(“Loading data”)
symbols = c(“IEF”, “SPY”)
getSymbols(symbols, from=initDate, to=endDate, index.class=c(“POSIXt”,”POSIXct”))

La variabile “symbols” è un vettore di stringhe costruito con la function “c()”. Per i neofiti, questa function è una delle più utilizzate in R, e genera un vettore a partire dai parametri passati in ingresso. Per maggiori dettagli fare riferimento alla documentazione di R.

La function “getSymbols()” è davvero molto potente. Scarica da una sorgente su internet i dati storici dei simboli che gli vengono passati. La sorgente di default è Yahoo. In uscita restituisce tanti oggetti “xts” quanti sono i simboli nel vettore “symbols”. Gli oggetti xts sono una potentissima struttura dati. Si può accedere agli elementi sia con gli indici (in maniera analoga agli array) sia con le date. Le date devono essere passate come stringhe. I dati storici quindi sono memorizzati in questi due oggetti.

Per adesso ci fermiamo qui. Proseguiremo la spiegazione nella prossima parte.

A presto.

2 thoughts on “Test in R: “Faber Portfolio” – Parte 1

Lascia un commento