[R-SIG-Finance] Optimization of Custom Indicator Based Threshold Multiplier
John Kumar
rjkft at yahoo.com
Wed Feb 22 12:22:34 CET 2017
Hi good people of the mailing list,
I am having trouble implementing a threshold multiplier (ATR based) that is
set via a custom indicator (i.e. apply.paramset will not run). I've had a
similar problem previously when the indicator label in the paramset and the
indicator did not match, but here I have been careful to match them. It will
run properly with a single value using apply.strategy, so I'm assuming the
syntax is OK. The function, two rules and distribution are presented below
along with the complete code. Any help to get this to run would be
appreciated. Cheers
John
atrStopThresh <- function(HLC, n=14, atr_mult=2){
ATR <- ATR(HLC = HLC, n)
pctATR <- (atr_mult*ATR$atr)/Cl(HLC)
return(pctATR)
}
add.indicator(strategy = strat,name =
"atrStopThresh",arguments=list(HLC=quote(OHLC(mktdata)),
atr_mult =
atrMult),
label = "atr_mult_stop"
)
# c) Stoploss rules
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='long', sigval=TRUE, orderside=NULL,
ordertype='stoplimit',
prefer='High', orderqty="all", replace=FALSE,
orderset ="ocolong",
tmult=TRUE, threshold="atr.atrStopThresh"
),
type='chain', parent = "EnterLONG",
label='StopLONG',enabled = TRUE
)
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='short', sigval=TRUE, orderside=NULL,
ordertype='stoplimit',
prefer='Low', orderqty="all", replace=FALSE,
orderset ="ocoshort",
tmult=TRUE, threshold="atr.atrStopThresh"
),
type='chain', parent = "EnterSHORT",
label='StopSHORT',enabled = TRUE
)
add.distribution(portfolio.st,
paramset.label = "DMA_OPT",
component.type = "indicator",
component.label = "atr_mult_stop",
variable = list(atr_mult = atrMult),
label = "atr_mult_stop"
)
Full Code:
# This strategy uses a simple moving average crossover (MAfast and MASlow),
to either a) go long if the fast
# moving avergae is above the slow moving average or b) short if the fast
moving avergae is below the slow
# moving average. It is essentially a modified version of the luxor demo,
with the ordersets removed. This
# prevents the one closes other behaviour and allows us to be always in the
market. Has a rebalancing rule
# that enables us to compare being 100% invested in this strategy to buy and
hold. No leverage. Here the
# simple percentage multiple stop loss is replace with an ATR based stop
loss, which is implemented
# via a custom indicatoe. Working.
# Library and time zone setup
library(quantstrat) # Required package for strategy back testing
library(doParallel) # For parrallel optimization
library(rgl) # Library to load 3D trade graphs
library(reshape2) # Library to load 3D trade graphs
ttz<-Sys.getenv('TZ') # Time zone to UTC, saving original time zone
Sys.setenv(TZ='UTC')
# Quantstrat general variables
strat <- "DMA1EQ" # Give the stratgey a name variable
portfolio.st <- "DMA1EQ" # Portfolio name
account.st <- "DMA1EQ" # Account name
initEq <- 10000 # this parameter is required to get pct
equity rebalancing to work
# Strategy specific variables
MAfast <- 10 #fast moving average period
MAslow <- 100 #slow moving average period
atrMult <- seq(1, 5, by = 1) #atr multiplier
# Strategy Functions
# Custom indicator to generate the threshold multiplier to set an ATR based
stop, if a simple % multiplier
# is desired just set it to return a fixed numeric. e.g. return(0.04)
atrStopThresh <- function(HLC, n=14, atr_mult=2){
ATR <- ATR(HLC = HLC, n)
pctATR <- (atr_mult*ATR$atr)/Cl(HLC)
return(pctATR)
}
# Symbols etc
currency('USD') # set USD as a base currency
symbol <- "GSPC" # Universe selection At this stage is only one
symbol
# set the instument as a future and get the data from yahoo
stock(symbol, currency = "USD", multiplier = 1)
getSymbols("^GSPC", from = '1995-01-01')
# if run previously, run this code from here down
delete.paramset(portfolio.st,"DMA_OPT")
rm.strat(portfolio.st)
# initialize the portfolio, account and orders. Starting equity and assuming
data post 1995.
initPortf(portfolio.st, symbols = symbol, initDate = "1995-01-01")
initAcct(account.st, portfolios = portfolio.st, initEq = initEq, initDate =
"1995-01-01")
initOrders(portfolio = portfolio.st, initDate = "1995-01-01")
# define the strategy with a position limit to prevent multiple trades in a
direction
strategy(strat, store = TRUE)
addPosLimit(strat, symbol, timestamp="1995-01-01", maxpos=100,
longlevels = 1, minpos=-100, shortlevels = 1)
# Add the indicators - One bband for the breakout another for the stop
add.indicator(strategy = strat,name =
"SMA",arguments=list(x=quote(Cl(mktdata)[,1]),
n = MAfast),
label = "nFast"
)
add.indicator(strategy = strat,name =
"SMA",arguments=list(x=quote(Cl(mktdata)[,1]),
n = MAslow),
label = "nSlow"
)
add.indicator(strategy = strat,name =
"atrStopThresh",arguments=list(HLC=quote(OHLC(mktdata)),
atr_mult =
atrMult),
label = "atr_mult_stop"
)
# Add the signals - Go long on a cross of the close greater than the
breakout band and close on a cross
# less than the close band. Signals reversed for a short.
add.signal(strategy=strat,name='sigCrossover', arguments =
list(columns=c("nFast", "nSlow"),relationship="gt"
),
label='long'
)
add.signal(strategy=strat,name='sigCrossover',arguments =
list(columns=c("nFast", "nSlow"),relationship="lte"
),
label='short'
)
# Add the rules
# a) Entry rules - enter on moving average cross, osMaxPos is the order
function
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='long', sigval=TRUE, orderside='long',
ordertype='market',
orderqty=+100, osFUN='osMaxPos', replace=FALSE
),
type='enter',
label='EnterLONG'
)
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='short', sigval=TRUE, orderside='short',
ordertype='market',
orderqty=-100, osFUN='osMaxPos', replace=FALSE
),
type='enter',
label='EnterSHORT'
)
# b) Exit rules - Close on cross the other way
add.rule(strategy = strat, name='ruleSignal',
arguments=list(sigcol='long' , sigval=TRUE, orderside=NULL,
ordertype='market',
orderqty="all", replace=TRUE, orderset = "ocolong"
),
type='exit',
label='ExitLONG'
)
add.rule(strategy = strat, name='ruleSignal',
arguments=list(sigcol='short', sigval=TRUE, orderside=NULL ,
ordertype='market',
orderqty="all", replace=TRUE, orderset = "ocoshort"
),
type='exit',
label='ExitSHORT'
)
# c) Stoploss rules
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='long', sigval=TRUE, orderside=NULL,
ordertype='stoplimit',
orderqty="all", replace=FALSE, orderset ="ocolong",
tmult=TRUE, threshold="atr.atrStopThresh"
),
type='chain', parent = "EnterLONG",
label='StopLONG',enabled = TRUE
)
add.rule(strategy=strat,
name='ruleSignal',
arguments=list(sigcol='short', sigval=TRUE, orderside=NULL,
ordertype='stoplimit',
orderqty="all", replace=FALSE, orderset ="ocoshort",
tmult=TRUE, threshold="atr.atrStopThresh"
),
type='chain', parent = "EnterSHORT",
label='StopSHORT',enabled = TRUE
)
# Add distributions and constraints
add.distribution(portfolio.st,
paramset.label = "DMA_OPT",
component.type = "indicator",
component.label = "atr_mult_stop",
variable = list(atr_mult = atrMult),
label = "atr_mult_stop"
)
# Now apply the parameter sets for optimization
out <- apply.paramset(strat, paramset.label = "DMA_OPT",
portfolio=portfolio.st, account = account.st,
nsamples=0, verbose = TRUE,audit = globalenv())
stats <- out$tradeStats
Sys.setenv(TZ=ttz) # Return to
original time zone
[[alternative HTML version deleted]]
More information about the R-SIG-Finance
mailing list