R: Quantstrat example Guy Yollin

908 views Asked by At

I'm working through Guy Yollin slides for quanstrat blotter etc. Here's the code I'm trying to execute:

#According to quantstrat lectures 1-3 von Guy Yollin

library(blotter)
library(FinancialInstrument)
source("chart_Posn.R")

currency("USD")
stock("SPY",currency="USD",multiplier=1)
getSymbols('SPY', from='1998-01-01', to='2011-07-31', adjust=T)
SPY=to.monthly(SPY, indexAt='endof')
SPY$SMA10m <- SMA(Cl(SPY), 10)

####################################
# Initialize portfolio and account #
####################################
#Initialize portfolio and account
b.strategy <- "bFaber" #Is only the name for the portfolio strategy
initPortf(b.strategy,'SPY', initDate='1997-12-31')
initAcct(b.strategy,portfolios=b.strategy, initDate='1997-12-31', initEq=1e6)

#######################
# Formating the chart #
#######################
theme<-chart_theme()
theme$col$up.col<-'lightgreen'
theme$col$up.border<-'lightgreen'
theme$col$dn.col<-'pink'
theme$col$dn.border<-'pink'
chart_Series(SPY,theme=theme,name="SPY")
plot(add_SMA(n=10,col=4,lwd=2))

#################
# Trading logic # (buy when monthly price > 10-month SMA, sell when monthly price < 10-month SMA)
#################
for( i in 1:nrow(SPY) ) {
  CurrentDate <- time(SPY)[i]
  ClosePrice <- as.numeric(Cl(SPY[i,]))
  Posn <- getPosQty(b.strategy, Symbol='SPY', Date=CurrentDate)
  if( !is.na(as.numeric(SPY[i,'SMA10m'])) ) {
    if( Posn == 0 ) { # No position, test to go Long
      if( ClosePrice > as.numeric(SPY[i,'SMA10m']) ) {
        # enter long position
        addTxn(b.strategy, Symbol='SPY', TxnDate=CurrentDate,
               TxnPrice=ClosePrice, TxnQty = 1000 , TxnFees=0) }
    } else { # Have a position, so check exit
      if( ClosePrice < as.numeric(SPY[i,'SMA10m']) ) {
        # exit position
        addTxn(b.strategy, Symbol='SPY', TxnDate=CurrentDate,
               TxnPrice=ClosePrice, TxnQty = -Posn , TxnFees=0) }
    }
  }
  # Calculate P&L and resulting equity with blotter
  updatePortf(b.strategy, Dates = CurrentDate)
  updateAcct(b.strategy, Dates = CurrentDate)
  updateEndEq(b.strategy, Dates = CurrentDate)
} # End dates loop

chart.Posn(b.strategy, Symbol='SPY', Dates='1998::')
plot(add_SMA(n=10,col=4,on=1,lwd=2))

However I cannot get it working..there is always this error after the for Loop:

Error in periodicity(table) : 
  can not calculate periodicity of 1 Observation

And these two lines generate following error:

chart.Posn(b.strategy, Symbol='SPY', Dates='1998::')
plot(add_SMA(n=10,col=4,on=1,lwd=2)
> chart.Posn(b.strategy, Symbol='SPY', Dates='1998::')
Error in as.POSIXct.numeric(first(index(Position))) : 
  'origin' must be supplied
> plot(add_SMA(n=10,col=4,on=1,lwd=2))
Warning message:
In mapply(function(name, value) { :
  longer argument not a multiple of length of shorter

What am I overlooking?

1

There are 1 answers

0
Khma On

First, to directly answer the two points:

indicators are not necessary to a strategy, the only hard and fast requirement is that you need at least one rule that will create orders, or at least one rule in the order slot that will create transactions.

the strategy object contains only the specification of the strategy, nothing more, see below.

Next, to explain what's going on:

quantstrat makes extensive use of delayed execution to allow for code reuse. The strategy object is a storage place for the specification of the strategy. It may be applied to one or more portfolios (as created by initPortf()) by using the portfolios= argument.

The strategy specification is only a storehouse of how you want to apply the strategy later. Until you call applyStrategy(...), nothing is evaluated. This allows for useful properties like using the same strategy object to test multiple different parameter sets, or applying against different portfolio constructions and constituents, without changing the strategy specification.

The strategy object itself is not changed by applyStrategy. Inside applyStrategy, a special internal object called mktdata is created which will be modified by the execution of the indicators, signals, and rules contained in the strategy specification.

The mktdata object is constructed, by default, from retrieving the object containing your historical data from the .GlobalEnv, or some other environment specified by the user. There will be one of these objects created for each symbol in the portfolio, and maintained inside the function scope of applyStrategy.

When the indicators and signals are applied, the most common pattern is for these functions is to return a vector of the same length as the mktdata time series, or a time series object with the same index as the mktdata time series. If this pattern is followed, these columns will be added to the mktdata object and available for later indicator, signal, and rule functions to make use of. indicators and signals are presumed to always be not path dependent, and rules, by default, are path dependent.

The example signal functions, such as sigCrossover and sigThreshold, make use of this pattern to access and compare columns that exist in mktdata. ruleSignal, an example rule, looks for points where signals have some particular value, and then acts on that information to create orders.

External references:

Using quantstrat (R/Finance 2013)

Introduction to quantstrat (FOSS trading blog)

from R: Quantstrat examples of Guy Yollin. Indicators necessary? And what is stored in these financial instruments?