I believe this is a formatting issue with my indicator. Can someone tell me what im doing wrong here?
#....omitted the portfolio initialization above
#returns change from past day, or NA if one of the values is invalid
changeDaily<-function(x,y){if(is.na(x+y)==T){return(NA)};ifelse(x-y>0,"UP","DOWN")}
#creates column called lagPredict which uses the function changeDaily
add.indicator(strat, name = "changeDaily",arguments = list(HLC = quote(mktdata),Cl(mktdata),Lag(Cl(mktdata))), label='lagPredict')
error:
Error in has.Cl(x) : object 'mktdata' not found
Traceback:
traceback()
3: has.Cl(x)
2: Cl(mktdata)
1: add.indicator(strat, name = "changeDaily", arguments = list(HLC = quote(mktdata),
Cl(mktdata), Lag(Cl(mktdata))), label = "lagPredict")
Complete code:
source("forex.functions.R")
startDate <- '2010-01-01' # start of data
endDate <- '2015-05-01' # end of data
symbols<-c("USD/EUR")
portfolio<-acct<-strat<-"simpleLookAhead"
initSetup(symbols,portfolio,acct,strat)
dump<-lapply(symbols,function(x)forex.weeklyOHLC(x))
symbols<-gsub("/","",symbols)
#############################################################
#returns change from past day, or NA if one of the values is invalid
changeDaily<-function(x,y){if(is.na(x+y)==T){return(NA)};ifelse(x-y>0,"UP","DOWN")}
#creates column called lagPredict which uses the function changeDaily to return UP or DOWN in reference to yesterdays price
add.indicator(strat, name = "changeDaily",arguments = list(HLC = quote(mktdata),Cl(mktdata),Lag(Cl(mktdata))), label='lagPredict')
forex.functions.R
library(PerformanceAnalytics)
library(quantmod)
library(lattice)
library(IKTrading)
library(quantstrat)
Sys.setenv(TZ="EST") # set time zone
if (!exists('.blotter')) .blotter <- new.env()
if (!exists('.strategy')) .strategy <- new.env()
forex.weeklyOHLC<-function(ss){
ss<-getSymbols(ss,src="oanda",from=startDate,to=endDate)
x<-get(ss)
#x<-adjustOHLC(x,symbol.name=symbol) #calls get Splits which calls getSymbols which fails bc src != oanda
x<-to.weekly(x,indexAt='lastof',drop.time=TRUE)
indexFormat(x)<-'%Y-%m-%d'
colnames(x)<-gsub("x",ss,colnames(x))
assign(ss,x)
}
initSetup<-function(symbols,portfolio, acct, strat){
initDate <- '2009-12-31'
initEq <- 1e6
currency("USD")
stock(symbols, currency="USD", multiplier=1)
rm.strat(strat) # remove portfolio, account, orderbook if re-run
initPortf(name=portfolio, symbols, initDate=Sys.Date())
initAcct(name=acct, portfolios=portfolio,initDate=Sys.Date(), initEq=initEq)
initOrders(portfolio=portfolio, initDate=Sys.Date())
strategy(strat, store=TRUE)
}
You need to quote all the objects in the arguments list in the call to add.indicator to prevent them from being evaluated. You also need to specify the correct arguments to pass to your changeDaily function. You pass HLC, but changeDaily does not have a HLC argument.
Your add.indicator call should look something like this:
add.indicator(strat, name = "changeDaily",
arguments = list(x = quote(Cl(mktdata)), y = quote(Lag(Cl(mktdata)))),
label = 'lagPredict')
Related
I am trying to use the applySignals function on my stock data and additional filter rule that I created since the TTR package does not provide a simple filter rule.
When I use the applyIndicators function I can see that an additional column appears with the filter (daily return) so I think this works. However when I add my long and short signal based on this filter and I use the applySignals function I get the following error:
test <- applySignals(strategy = strategy.st, mktdata = test_init)
Error in dimnames<-.xts(*tmp*, value = dn) :
length of 'dimnames' [2] not equal to array extent
In addition: Warning message:
In match.names(column, colnames(data)) :
all columns not located in filter for OTRK.Open OTRK.High OTRK.Low OTRK.Close FILTER.filter longfilter
I used the same example and code from a professional who provided the code but it doesn't seem to work for me. (chapter 9.3 Simple filter rule: https://bookdown.org/kochiuyu/technical-analysis-with-r-second-edition/simple-filter-rule.html)
I am new to R so I don't really understand the error message.
Thanks in advance!
This is my code as far as the error:
install.packages("quantstrat")
install.packages("TTR")
## Library
library("quantstrat")
library("TTR")
## Quantsrat not directly available: solution
install.packages("devtools")
require(devtools)
install_github("braverock/blotter") # dependency
install_github("braverock/quantstrat")
###############################################################################################################################
###############################################################################################################################
initdate <- "2003-12-15"
from <- "2018-12-15"
to <- "2021-04-07"
Sys.setenv(TZ = "UTC")
currency("USD")
getSymbols("OTRK", from = from, to = to, src= "yahoo", adjust = TRUE)
stock("OTRK", currency = "USD", multiplier=1)
tradesize <- 1000
initeq <- 1000
#txnfees <- -10
#orderqty <- 100
#nsamples <- 5
#Parameters indicators#
filterthreshold <- 0.05
#Initialise#
strategy.st <- portfolio.st <- account.st <- "FilterRule"
rm.strat(strategy.st)
initPortf(portfolio.st, symbols = "OTRK", initDate = initdate, currency = "USD")
initAcct(account.st, portfolios = portfolio.st, initDate = initdate, currency = "USD", initEq = initeq)
initOrders(portfolio.st, symbols = "OTRK", initDate = initdate)
strategy(strategy.st, store = TRUE)
#Adding indicators#
FILTER <- function(price) {
lagprice <- lag(price,1)
temp<- price/lagprice - 1
colnames(temp) <- "FILTER"
return(temp)
}
add.indicator(
strategy=strategy.st,
name = "FILTER",
arguments = list(price = quote(Cl(mktdata))),
label= "filter")
#Check test indicators work#
test_init <- applyIndicators(strategy = strategy.st, mktdata = OHLC(OTRK))
head(test_init, n=7)
tail(test_init, n=7)
#Adding signals#
add.signal(strategy.st,
name="sigThreshold",
arguments = list(threshold= filterthreshold,
column="filter",
relationship="gt",
cross=TRUE),
label="longfilter")
add.signal(strategy.st,
name="sigThreshold",
arguments = list(threshold= - filterthreshold,
column="filter",
relationship="lt",
cross=TRUE),
label="shortfilter")
#Test signals on data
test <- applySignals(strategy = strategy.st, mktdata = test_init)
I am currently trying to write a simple strategy using Bollinger Bands in R. The goal is to enter a long position when the closing price touches the lower band and exit when it touches the upper one. To do that I firstly wrote two simple function to use as indicators:
BBandsDown <- function(HLC,n=20,maType,sd=2){
bbdown <- BBands(HLC,n,maType,sd)$dn
colnames(bbdown)<-"bbdown"
return(bbdown)
}
BBandsUp <- function(HLC,n=20,maType,sd=2){
bbup <- BBands(HLC,n,maType,sd)$up
colnames(bbup)<-"bbup"
return(bbup)
}
Then I added the indicators
add.indicator(strategy = strategy.st,
name = 'Cl',
arguments = list(x=quote(mktdata)),
label = 'close')
add.indicator(strategy = strategy.st,
name = 'BBandsDown',
arguments = list(HLC = quote(Cl(mktdata)), n=10,maType="SMA",sd=1.5),
label = 'bbandsdown1.5')
add.indicator(strategy = strategy.st,
name = 'BBandsUp',
arguments = list(HLC = quote(Cl(mktdata)), n=10,maType="SMA",sd=1.5),
label = 'bbandsup1.5')
Then I define Signals and Rules. My problem is that I cannot use the applyStrategy command because it reply.
Error in BBands(HLC, n, maType, sd) (from strategy_bbands.r!15334IYx#2) :
Price series must be either High-Low-Close, or Close/univariate.
I tried with both HLC = quote(Cl(mktdata)) and HLC = quote(HLC(mktdata)) but the error is the same. What am I doing wrong?
You haven't provided a reproducible example.
The error is pretty clear that you're passing in the wrong data.
I suspect that you have mangled the data prior to calling applyStrategy , but there isn't enough here to validate that.
See the bbands.R demo in the demos directory for a working example.
I'm having trouble writing a custom indicator function for use with quanstrat::add.indicator
Error:
Error in inherits(x, "xts") : object 'price' not found
My code:
library(quantstrat)
symbols<-getSymbols("USD/EUR",src="oanda")
strat<-acct<-portfolio<-"tempTest"
initEq<-1000
initDate <- '2009-12-31'
currency("USD")
exchange_rate(symbols, currency="USD")
rm.strat(strat) # remove portfolio, account, orderbook if re-run
initPortf(name=portfolio, symbols, initDate=Sys.Date())
initAcct(name=acct, portfolios=portfolio,initDate=Sys.Date(), initEq=initEq)
initOrders(portfolio=portfolio, initDate=Sys.Date())
strategy(strat, store=TRUE)
colnames(USDEUR)<-"Close"
#################################################################################################
RSI.lagged<-function(lag=1,n=2,...){
RSI <- RSI(price)
RSI <- lag(RSI, lag)
out <- RSI$rsi
colnames(out) <- "rsi"
return(out)
}
########RSI indicator
####THIS IS LAGGED TO PREVENT FOREKNOWLEDGE
add.indicator(strat, name="RSI.lagged", arguments=list(price = quote(Cl(mktdata)), n=2), label="rsiIndLagged")
test <- applyIndicators(strat, mktdata=USDEUR)
After adding the parameter price to the RSI.lagged function eg RSI.lagged<-function(lag=1,n=2,price,...) I get the error:
Error in `colnames<-`(`*tmp*`, value = "rsi") : attempt to set 'colnames' on an object with less than two dimensions
You were trying to access the name of a column that does not exist. Try this instead to get your indicator to work:
RSI.lagged<-function(price, lag=1,n=2,...){
# Stick in a browser to see your problem more clearly:
# browser()
rsi <- RSI(price)
rsi <- lag(rsi, lag)
# This column name does not exist: "rsi". The name of the column gets the default "EMA"
# tail(rsi)
# EMA
# 2017-11-04 63.48806
# 2017-11-05 66.43532
# 2017-11-06 64.41188
# 2017-11-07 66.02659
# 2017-11-08 67.96394
# 2017-11-09 66.08134
colnames(rsi) <- "rsi"
return(out)
}
(Aside, also strongly suggest you do not try using Oanda data to backtest with,as the prices aren't "real"; they are a weighted average price for each day. See: Exact time stamp on quantmod currency (FX) data)
What is the correct method to have signals reference other signals? Is it not intended functionality? I cant seem to find a way to do it in my code.
library(PerformanceAnalytics)
library(quantmod)
library(lattice)
startDate <- '2010-01-01' # start of data
endDate <- '2015-05-01' # end of data
.blotter<-new.env()
.strategy<-new.env()
Sys.setenv(TZ="EST") # set time zone
symbols<-c("GOOG")
data<-getSymbols(symbols, from=startDate, to=endDate, index.class="POSIXct",env=NULL)
library(quantstrat)
initDate <- '2009-12-31'
initEq <- 1e6
currency("USD")
stock(symbols, currency="USD", multiplier=1)
rm.strat("multiAsset.bb1") # remove portfolio, account, orderbook if re-run
initPortf(name="multiAsset.bb1", symbols, initDate=initDate)
initAcct(name="multiAsset.bb1", portfolios="multiAsset.bb1",initDate=initDate, initEq=initEq)
initOrders(portfolio="multiAsset.bb1", initDate=initDate)
strategy("bbands", store=TRUE)
#Indicators are applied before signals and rules, and the output of indicators may be used as inputs to construct signals or fire rules
#mktdata is the time series object that holds the current symbols data during evaluation (pg 55)
add.indicator("bbands", name = "BBands",arguments = list(HLC = quote(HLC(mktdata)), maType='SMA'), label='bbInd')
test <- applyIndicators("bbands", mktdata=data)
head(test, 10)
add.signal("bbands", name="sigThreshold", arguments=list(columns=c("pctB.bbInd",".77"),relationship="gt"),label="H.gt.UpperBand")
add.signal("bbands", name="sigThreshold", arguments=list(columns=c("H.gt.UpperBand","0"),relationship="gt"),label="true.upper.band")
test <- applySignals("bbands", mktdata=test)
head(test, 10)
Error
Error in match.names(column, colnames(data)) :
argument "column" is missing, with no default
Note that this is a generalized example. It would be trivial to make the first signal an indicator and avoid this problem in this specific case.
You've passed the wrong arguments to sigThreshold. This corrected code works as expected, with the second signal using the H.gt.UpperBand column (singular) from the first signal. The missing arguments in your code for the sigThreshold function are column (singular) and threshold.
library(quantstrat)
startDate <- '2010-01-01' # start of data
endDate <- '2015-05-01' # end of data
Sys.setenv(TZ="EST") # set time zone
symbols<-c("GOOG")
data<-getSymbols.yahoo(symbols, from=startDate, to=endDate, index.class="POSIXct",auto.assign=FALSE)
initDate <- '2009-12-31'
initEq <- 1e6
currency("USD")
stock(symbols, currency="USD", multiplier=1)
rm.strat("multiAsset.bb1") # remove portfolio, account, orderbook if re-run
initPortf(name="multiAsset.bb1", symbols, initDate=initDate)
initAcct(name="multiAsset.bb1", portfolios="multiAsset.bb1",initDate=initDate, initEq=initEq)
initOrders(portfolio="multiAsset.bb1", initDate=initDate)
strategy("bbands", store=TRUE)
#Indicators are applied before signals and rules, and the output of indicators may be used as inputs to construct signals or fire rules
#mktdata is the time series object that holds the current symbols data during evaluation (pg 55)
add.indicator("bbands"
, name = "BBands"
, arguments = list(HLC = quote(HLC(mktdata))
, maType='SMA')
, label='bbInd')
test <- applyIndicators("bbands", mktdata=data)
head(test, 10)
add.signal("bbands"
, name="sigThreshold"
, arguments=list(column="pctB.bbInd"
, threshold=.77
, relationship="gt")
, label="H.gt.UpperBand")
add.signal("bbands"
, name="sigThreshold"
, arguments=list(column="H.gt.UpperBand"
, threshold=0
, relationship="gt")
,label="true.upper.band")
test <- applySignals("bbands", mktdata=test)
head(test, 10)
I am trying to tell whether a specific column value is greater than .77, but this code returns 1 if the value is greater then 0. Is there any way to use a known function (not a custom one) to do a simple greater then check?
library(PerformanceAnalytics)
library(quantmod)
library(lattice)
startDate <- '2010-01-01' # start of data
endDate <- '2015-05-01' # end of data
.blotter<-new.env()
.strategy<-new.env()
Sys.setenv(TZ="EST") # set time zone
symbols<-c("GOOG")
data<-getSymbols(symbols, from=startDate, to=endDate, index.class="POSIXct",env=NULL)
library(quantstrat)
initDate <- '2009-12-31'
initEq <- 1e6
currency("USD")
stock(symbols, currency="USD", multiplier=1)
rm.strat("multiAsset.bb1") # remove portfolio, account, orderbook if re-run
initPortf(name="multiAsset.bb1", symbols, initDate=initDate)
initAcct(name="multiAsset.bb1", portfolios="multiAsset.bb1",initDate=initDate, initEq=initEq)
initOrders(portfolio="multiAsset.bb1", initDate=initDate)
strategy("bbands", store=TRUE)
#Indicators are applied before signals and rules, and the output of indicators may be used as inputs to construct signals or fire rules
#mktdata is the time series object that holds the current symbols data during evaluation (pg 55)
add.indicator("bbands", name = "BBands",arguments = list(HLC = quote(HLC(mktdata)), maType='SMA'), label='bbInd')
test <- applyIndicators("bbands", mktdata=data)
head(test, 10)
add.signal("bbands", name="sigThreshold", arguments=list(columns=c("pctB.bbInd",".77"),relationship="gt"),label="H.gt.UpperBand")
test <- applySignals("bbands", mktdata=test) #DOESNT WORK
head(test, 10)
Error:
Error in match.names(column, colnames(data)) :
argument "column" is missing, with no default
My solution was to change:
add.signal("bbands", name="sigThreshold", arguments=list(columns=c("pctB.bbInd",".77"),relationship="gt"),label="H.gt.UpperBand")
to:
add.signal("bbands", name="sigThreshold", arguments=list(threshold=.77,column="pctB.bbInd",relationship="gt"),label="H.gt.UpperBand")