R quantstrat futures example - "Transactions must be added in order"

288 views Asked by At

Edit: the fix was easier than thought, I just initialized the portfolio, account and orders too late, given my data starts earlier. The following makes to code run. I won't delete my question, since I found hardly any examples for individual futures.

## set up quantstrat environment ----
initDate <- '2010-01-01'
startDate <- '2010-01-01'
startEquity <- 10E6
endDate <- '2012-12-31'

I have been looking for a quantstrat example that is running on individual futures forever, unfortunately, I didn't find anything, although I went through all the examples, demos etc. in the package, Guy Yollin's site etc. Hence, I decided to try it myself. I use VX futures, load them and try to run a simple RSI-strategy on them. Many parts of the code are copied from different sites, but it works until applyStrategy.

library(FinancialInstrument)
library(quantstrat)
library(qmao)
library(quantmod)

##  download sample data ----
dl_data <- T # change to T for downloading the data
if(dl_data){
  getSymbols("VX", src='cfe', Months = 1:12, Years = 2011:2012)
  to_store <- c(ls()[grepl('VX', ls())])
  saveSymbols.days(Symbols = to_store,
                   base_dir = 'data/VX')
}

## new blotter and strategy environments
.blotter <- new.env()
.strategy <- new.env()

## load VX futures ----
vx_names <- gsub(pattern = '.RData', replacement = '', list.files(path = 'data/VX/'))

currency('USD')

for(i in vx_names){
  future(primary_id = i, currency = 'USD', multiplier = 1000, tick_size = 0.05, underlying_id = NULL)
}

getSymbols.FI(Symbols = vx_names,
              dir = 'data/VX',
              extension = "rda",
              from = '2010-12-01',
              to = '2013-12-31')

## set up quantstrat environment ----
initDate <- '2010-12-01'
startDate <- '2011-01-01'
startEquity <- 10E6
endDate <- '2012-12-31'

portName <- stratName <- acctName <- 'futures_example'

rm.strat(stratName)

# initialize portfolio, account and orders
initPortf(portName, symbols = vx_names, initDate = startDate)
initAcct(acctName, portfolios = portName, initDate = startDate, initEq = startEquity)
initOrders(portfolio = portName, startDate = startDate)

# Initialize and store the strategy
strategy(stratName, store = TRUE)

# Define RSI Indicator
add.indicator(
  strategy = stratName,
  name = "RSI",
  arguments = list(price = quote(Cl(mktdata)), maType = "EMA"),
  label = "RSI"
)

# The applyIndicators function allow to observe the indicators for a specific symbol while making progress in building the strategy
test <- applyIndicators(stratName, mktdata = OHLC(VX_G11))
tail(test, 10)

# add signals
add.signal(
  strategy = stratName,
  name = "sigThreshold",
  arguments = list(
    threshold = 30,
    column = "RSI",
    relationship = "lt",
    cross = TRUE
  ),
  label = "LongEntry"
)

add.signal(
  strategy = stratName,
  name = "sigThreshold",
  arguments = list(
    threshold = 70,
    column = "RSI",
    relationship = "gt",
    cross = TRUE
  ),
  label = "LongExit"
)

# With applySignal(), it is possible to observe the signal columns as well as the remaining information of the mktdata object.
sig <- applySignals(stratName, mktdata)

# Add Strategy Rules
add.rule(
  strategy = stratName,
  name = 'ruleSignal',
  arguments = list(
    sigcol = "LongEntry",
    sigval = TRUE,
    orderqty = 100,
    ordertype = "market",
    orderside = "long",
    replace = FALSE
  ),
  label = "longEnter",
  enabled = TRUE,
  type = "enter"
)


add.rule(
  strategy = stratName,
  name = 'ruleSignal',
  arguments = list(
    sigcol = "LongExit",
    sigval = TRUE,
    orderqty = "all",
    ordertype = "market",
    orderside = "long",
    replace = FALSE
  ),
  label = "longExit",
  enabled = TRUE,
  type = "exit"
)

## Apply the Strategy to the Portfolio ----
# Apply strategy to the portfolio
t1 <- Sys.time()
results <- applyStrategy(stratName, portfolios = portName, symbols = vx_names)
t2 <- Sys.time()
print(t2 - t1)

When running it, I get the error

Error in addTxn(Portfolio = portfolio, Symbol = symbol, TxnDate = txntime,  : 
  Transactions must be added in order. TxnDate (2010-12-30 01:00:00) is before last transaction in portfolio (2011-01-01) for VX_F11

When googling for that, I find an old bug, which should already be fixed in my version of blotter and I suspect that it has to do with the futures, which expire at some point or the setup. Any hints why this does not work? How do I tell quantstrat that the futures "live" only for a limited amount of time?

In general, the quantstrat package and its ecosystem of related packages looks super powerful to me, but getting started with it using real data and not another yahoo-finance example is harder than I thought and the lack of vignettes or stackoverflow questions doesn't help, so I thought I'd add one.

1

There are 1 answers

0
tester On

The initDate can't be bigger than the first date we have data for. The following change fixes the resulting error:

library(FinancialInstrument)
library(quantstrat)
library(qmao)
library(quantmod)

##  download sample data ----
dl_data <- T # change to T for downloading the data
if(dl_data){
  getSymbols("VX", src='cfe', Months = 1:12, Years = 2011:2012)
  to_store <- c(ls()[grepl('VX', ls())])
  saveSymbols.days(Symbols = to_store,
                   base_dir = 'data/VX')
}

## new blotter and strategy environments
.blotter <- new.env()
.strategy <- new.env()

## load VX futures ----
vx_names <- gsub(pattern = '.RData', replacement = '', list.files(path = 'data/VX/'))

currency('USD')

for(i in vx_names){
  future(primary_id = i, currency = 'USD', multiplier = 1000, tick_size = 0.05, underlying_id = NULL)
}

getSymbols.FI(Symbols = vx_names,
              dir = 'data/VX',
              extension = "rda",
              from = '2010-12-01',
              to = '2013-12-31')

## set up quantstrat environment ----
initDate <- '2010-01-01'
startDate <- '2010-01-01'
startEquity <- 10E6
endDate <- '2012-12-31'

portName <- stratName <- acctName <- 'futures_example'

rm.strat(stratName)

# initialize portfolio, account and orders
initPortf(portName, symbols = vx_names, initDate = startDate)
initAcct(acctName, portfolios = portName, initDate = startDate, initEq = startEquity)
initOrders(portfolio = portName, startDate = startDate)

# Initialize and store the strategy
strategy(stratName, store = TRUE)

# Define RSI Indicator
add.indicator(
  strategy = stratName,
  name = "RSI",
  arguments = list(price = quote(Cl(mktdata)), maType = "EMA"),
  label = "RSI"
)

# The applyIndicators function allow to observe the indicators for a specific symbol while making progress in building the strategy
test <- applyIndicators(stratName, mktdata = OHLC(VX_G11))
tail(test, 10)

# add signals
add.signal(
  strategy = stratName,
  name = "sigThreshold",
  arguments = list(
    threshold = 30,
    column = "RSI",
    relationship = "lt",
    cross = TRUE
  ),
  label = "LongEntry"
)

add.signal(
  strategy = stratName,
  name = "sigThreshold",
  arguments = list(
    threshold = 70,
    column = "RSI",
    relationship = "gt",
    cross = TRUE
  ),
  label = "LongExit"
)

# With applySignal(), it is possible to observe the signal columns as well as the remaining information of the mktdata object.
sig <- applySignals(stratName, mktdata)

# Add Strategy Rules
add.rule(
  strategy = stratName,
  name = 'ruleSignal',
  arguments = list(
    sigcol = "LongEntry",
    sigval = TRUE,
    orderqty = 100,
    ordertype = "market",
    orderside = "long",
    replace = FALSE
  ),
  label = "longEnter",
  enabled = TRUE,
  type = "enter"
)


add.rule(
  strategy = stratName,
  name = 'ruleSignal',
  arguments = list(
    sigcol = "LongExit",
    sigval = TRUE,
    orderqty = "all",
    ordertype = "market",
    orderside = "long",
    replace = FALSE
  ),
  label = "longExit",
  enabled = TRUE,
  type = "exit"
)

## Apply the Strategy to the Portfolio ----
# Apply strategy to the portfolio
t1 <- Sys.time()
results <- applyStrategy(stratName, portfolios = portName, symbols = vx_names)
t2 <- Sys.time()
print(t2 - t1)