Using a custom Spread to execute onto the 2 underlying instruments - Quantstrat Help
Hi Joshua, I thought that applyStrategy would not execute orders against the synthetic because i was explicitly stating which symbols I wanted orders put against. However orders were executing against it anyway. I wouldn't mind if applyStrategy went through the symbols data but never placed an order on it. Thank you for the suggestions I will give them a try. I appreciate your answers. Derek
On Mon, Dec 22, 2014 at 5:55 AM, Joshua Ulrich <josh.m.ulrich at gmail.com> wrote:
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