[R-SIG-Finance] Using a custom Spread to execute onto the 2 underlying instruments - Quantstrat Help

Joshua Ulrich josh.m.ulrich at gmail.com
Sun Dec 21 22:55:00 CET 2014


On Thu, Dec 11, 2014 at 1:31 AM, Derek Wong <treydog999 at gmail.com> wrote:
> Hello
>
> I am having problems with using a spread to generate signals and rules
> but then execute individually on the underlying. In my example case, I
> am taking the SP500 E-mini future (ES) and the Dow E-mini future (YM)
> calculating a custom spread function then using that for signal
> generation using rolling std dev and mean for thresholds. There is not
> very much documentation or demos on spreads and other synthetics that
> are available in the Financial Instrument Package. Example code below.
>
> I run into problems in the backtest runs and it runs the trade rules
> for every symbol in the portfolio, symb1 (ES), symb2(YM), and the
> custom spread symb1.symb2. I was expecting it to just run on
> symb1.symb2 and by using the RuleSignal symbol field and specify
> "symb1" and "symb2" for execution it would then execute on the
> underlying themselves. Instead quantstrat applystrategy goes through
> symb1, symb2, and symb1.symb2 and places trades on everything.
>
?applyStrategy says that it will apply the strategy to every symbol in
the portfolio, so I'm not sure why you expected it to only run on one
symbol in the portfolio.

> Is it possible to use a custom spread to execute on the underlying, if
> so how? Am I mis-specifying or misusing  the RuleSignal symbol
> identifier field? because I am specifically stating I want to execute
> symb1 long and symb2 short for a given signal or vice versa. I am not
> specifying the symb1.symb2 at all for any of the RuleSignal executions
> but they do trade.
>
One thing you could try:
Remove the synthetic spread from your portfolio object, and just use
the synthetic spread data to manually create signals for each of the
underlyings.  Then call applyRules for each underlying and pass your
signals via the signals argument to applyRules.

Or, perhaps better still, you could keep only the synthetic spread in
your portfolio, since your rules create orders on the underlyings.
Then you might be able to leave the rest of your data unchanged.

Note that both suggestions are just off the top of my head, since I
don't have a Quandl token.  Let me know if either of those suggestions
help.

>
> Thanks
>
> Derek
>
>
>
>
> # attempt to create a pairs trading strategy using a spread from
> Financial Instrument package.
> # Based on a Notional Spread and Standard Devations from the rolling mean
>
> require(quantstrat)
> require(Quandl)
> require(quantmod)
> #### Data Prep ####
>
> #get data from Quandl
> symb1 <- Quandl("CHRIS/CME_ES1", type = "xts",
> trim_start="2010-01-01", trim_end="2014-11-17")
> symb2 <- Quandl("CHRIS/CME_YM1", type = "xts",
> trim_start="2010-01-01", trim_end="2014-11-17")
>
> #Trim and Format  - Using settlement as Close value
> symb1 <- symb1[,c(1,2,3,6)]
> symb2 <- symb2[,c(1,2,3,6)]
>
> colnames(symb1) <- c("Open", "High", "Low", "Close")
> colnames(symb2) <- c("Open", "High", "Low", "Close")
>
> #Clean data so only dates where both trades exist
> merge <- cbind(symb1, symb2)
> dates <- index(merge[complete.cases(merge),])
> symb1<- symb1[dates]
> symb2<- symb2[dates]
>
> # -----------------------STRATEGY-------------------
> #clean variables for reruns
> suppressWarnings(rm("order_book.bbands",pos=.strategy))
> suppressWarnings(rm("account.bbands","portfolio.bbands",pos=.blotter))
> suppressWarnings(rm("account.st","portfolio.st","stock.str","stratBBands","initDate","initEq",'start_t','end_t'))
>
> #Initial values / parameters
> initDate= index(symb1)[1]-1
> initEq=100000
>
> SD = 2 # how many standard deviations
> N = 20 # length of moving average
>
> #Initialize FinancialInstrument Objects
>
> currency('USD')
>
> future( primary_id = "symb1",
>         currency = "USD",
>         tick_size = .25,
>         multiplier = 50)
>
> future( primary_id = "symb2",
>         currency = "USD",
>         tick_size = 1,
>         multiplier = 5)
>
> #Create Spread Series
> calcRatio <- function(x) {
>   #returns the ratio of notional close prices for 2 symbols
>   x1 <- get(x[1])
>   x2 <- get(x[2])
>   mult1 <- getInstrument(x[1])$multiplier
>   mult2 <- getInstrument(x[2])$multiplier
>   rat.Op <- ((mult1 * Op(x1))) / (mult2 * Op(x2))
>   rat.Hi <- ((mult1 * Hi(x1))) / (mult2 * Hi(x2))
>   rat.Lo <- ((mult1 * Lo(x1))) / (mult2 * Lo(x2))
>   rat.Cl <- ((mult1 * Cl(x1))) / (mult2 * Cl(x2))
>   ratio <- cbind(rat.Op, rat.Hi, rat.Lo, rat.Cl)
>   colnames(ratio) <- c("Open", "High", "Low", "Close")
>   return(ratio)
> }
>
> Ratio <- calcRatio(c("symb1", "symb2"))
>
> #Initialize Spread (using notional ratio as hedge ratio)
> spread(primary_id = "symb1.symb2",
>        currency = "USD",
>        members = c("symb1", "symb2"),
>        memberratio = list(1, as.numeric(-Cl(Ratio))) )
>
> #Notional Ratio is also spread for trading
> symb1.symb2 <- Ratio
>
> #name strings
> portfolio.st = 'bbands'
> account.st = 'bbands'
>
> #initialization of strategy objects ----
> initPortf(portfolio.st, #portfolio Initiatlization
>           symbols = c("symb1.symb2", "symb1", "symb2"),
>           initDate = initDate,
>           currency = "USD",
>           initPosQty = 0)
>
> initAcct(account.st, #account initialization
>          portfolios = portfolio.st,
>          initDate = initDate,
>          initEq = initEq)
>
> initOrders(portfolio = portfolio.st, #orders initialize
>            initDate = initDate)
>
> addPosLimit( portfolio = portfolio.st, # add position limit rules
>              symbol = 'symb1.symb2',
>              timestamp = initDate,
>              maxpos = 1,
>              longlevels = 1,
>              minpos = -1)
>
> addPosLimit( portfolio = portfolio.st, # add position limit rules
>              symbol = 'symb1',
>              timestamp = initDate,
>              maxpos = 2,
>              longlevels = 1,
>              minpos = -2)
>
> addPosLimit( portfolio = portfolio.st, # add position limit rules
>              symbol = 'symb2',
>              timestamp = initDate,
>              maxpos = 2,
>              longlevels = 1,
>              minpos = -2)
>
> stratBBands <- strategy("bbands") # strategy object init
>
> # Indicator
> stratBBands <- add.indicator(
>   strategy = stratBBands,
>   name = "BBands",
>   arguments = list(
>     HLC = quote(HLC(mktdata)),
>     n = N,
>     sd = SD,
>     maType = "SMA"),
>   label = "BBands")
>
> # #Indi Debug
> # summary(stratBBands)
> # start_t <- Sys.time()
> # applyIndicators( strategy = stratBBands, mktdata = Ratio)
> # end_t<-Sys.time()
> # print("strat execution time:")
> # print(end_t-start_t)
>
> # Add signals:
> stratBBands <- add.signal(
>   strategy = stratBBands,
>   name = "sigCrossover",
>   arguments = list(
>     columns = c("Close","up.BBands"),
>     relationship = "gt"),
>   label = "Cl.gt.UpperBand")
>
> stratBBands <- add.signal(
>   strategy = stratBBands,
>   name = "sigCrossover",
>   arguments = list(
>     columns = c("Close","dn.BBands"),
>     relationship = "lt"),
>   label = "Cl.lt.LowerBand")
>
> stratBBands <- add.signal(
>   strategy = stratBBands,
>   name = "sigCrossover",
>   arguments = list(
>     columns = c("High","Low", "mavg.BBands"),
>     relationship = "op"),
>   label = "Cross.Mid")
>
> # #Signal Debug
> # summary(stratBBands)
> # start_t <- Sys.time()
> # applySignals(strategy = stratBBands, mktdata =
> applyIndicators(strategy = stratBBands, mktdata = Ratio))
> # end_t<-Sys.time()
> # print("strat execution time:")
> # print(end_t-start_t)
>
> # Rules -----
>
> #Entry
>
> stratBBands <- add.rule (
>   strategy = stratBBands,
>   name = "ruleSignal",
>   arguments = list(
>     sigcol = "Cl.gt.UpperBand",
>     sigval = TRUE,
>     orderqty = -1,
>     ordertype = "market",
>     orderside = "short",
>     symbol = "symb1",
>     replace = TRUE,
>     osFUN = osMaxPos),
>   type = "enter",
>   label = "ShortSpread_symb1")
>
> stratBBands <- add.rule (
>   strategy = stratBBands,
>   name = "ruleSignal",
>   arguments = list(
>     sigcol = "Cl.gt.UpperBand",
>     sigval = TRUE,
>     orderqty = 1,
>     ordertype = "market",
>     orderside = "long",
>     symbol = "symb2",
>     replace = TRUE,
>     osFUN = osMaxPos),
>   type = "enter",
>   label = "ShortSpread_symb2")
>
> stratBBands <- add.rule (
>   strategy = stratBBands,
>   name = "ruleSignal",
>   arguments = list(
>     sigcol = "Cl.lt.LowerBand",
>     sigval = TRUE,
>     orderqty = 1,
>     ordertype = "market",
>     orderside = "long"
>     symbol = "symb1",
>     replace = TRUE,
>     osFUN = osMaxPos),
>   type = "enter",
>   label = "LongSpread_symb1")
>
> stratBBands <- add.rule (
>   strategy = stratBBands,
>   name = "ruleSignal",
>   arguments = list(
>     sigcol = "Cl.lt.LowerBand",
>     sigval = TRUE,
>     orderqty = -1,
>     ordertype = "market",
>     orderside = "short",
>     symbol = "symb2",
>     replace = TRUE,
>     osFUN = osMaxPos),
>   type = "enter",
>   label = "LongSpread_symb2")
>
> # Exit
> stratBBands <- add.rule(
>   strategy = stratBBands,
>   name = "ruleSignal",
>   arguments = list(
>     sigcol = "Cross.Mid",
>     sigval = TRUE,
>     orderqty = "all",
>     ordertype = "market",
>     TxnFees = 0,
>     replace = TRUE),
>   type = "exit",
>   label = "Exit")
>
>
> summary(stratBBands)
>
> # Strategy Execution ----
> start_t<-Sys.time()
> out<-try(applyStrategy(strategy=stratBBands ,
>                        portfolios="bbands"))
> end_t<-Sys.time()
> print("strat execution time:")
> print(end_t-start_t)
>
> # update portfolio
> start_t<-Sys.time()
> updatePortf(Portfolio='bbands',Dates=paste('::',as.Date(Sys.time()),sep=''))
> end_t<-Sys.time()
> print("updatePortf execution time:")
> print(end_t-start_t)
>
> #Chart
> chart.Posn(Portfolio='bbands',Symbol="symb1")
> plot(add_BBands(on=1,sd=SD,n=N))
> chart.Posn(Portfolio='bbands',Symbol="symb2")
> plot(add_BBands(on=1,sd=SD,n=N))
> chart.Posn(Portfolio='bbands',Symbol="symb1.symb2")
> plot(add_BBands(on=1,sd=SD,n=N))
>
> #Stats
> book <- getOrderBook("bbands")
> stats <- tradeStats("bbands")
> rets <- PortfReturns("bbands")
> port <- getPortfolio("bbands")
>
> _______________________________________________
> R-SIG-Finance at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.



-- 
Joshua Ulrich  |  about.me/joshuaulrich
FOSS Trading  |  www.fosstrading.com



More information about the R-SIG-Finance mailing list