Cumulative Return in Trading Strategy Test

2019-08-28 01:33发布

I have a Signal based on order imbalance that I want to test against historic stock data.

I also have the price for each of these Signals and then I calculate a Trend on the price to see if the returns are rising or falling in the last previous 4 prices. From the Signal I have taken

nSignal <- pnorm(Signal, mean = mean(Signal), sd = sd(Signal)) 

Now my idea is to buy/short each time nSignal rises above 0.70. If the trend is positive then I would place a buy and if it the trend is negative I would place a short order.

Sell   if( nSignal > = 0.70 && Trend < 0 ) 
Buy    if( nSignal > = 0.70 && Trend > 0 ) 
Ignore if( nSignal > = 0.70 && Trend = 0 )

I am then getting out of the position when the nSignal begins to decline again. I do not want to have more than one open position at any time. So if there is a Buy/Sell signal occuring while I have an open position I would ignore.

My questions are regarding the coding of the Sell and Buy vectors and calculation of the returns on these. I would ideally like to have 1 vector as output.

I can produce the Buy / Sell signal, but I am stuck on telling R to ignore further buy / sell until nSignal drops and the position is released. I have attached what I would like to calculate.

   dd <- textConnection("PriceTao,nSignal,Trend,Sell ,Buy,,Return
79.35,0.799276057198847,0.00632873284203539, ,Buy,79.35,
79.5,0.800495492911607,0.00631674578326402, ,,,
79.55,0.849748126078447,0.00378111963884864, ,,,
79.7,0.781025021425822,0.00440489652262133, ,release,79.7,0.00100623484156181
79.7,0.850907051807651,0.00251453735437934, ,Buy,79.7,
79.85,0.835339437922026,0.00376766425320585, ,release,79.85,0.000429459362427442
80,0.829431322197511,0.00376057994561618, ,,,
79.75,0.721861766918789,0.000635579945616138, ,,,
79.8,0.749198554641736,-0.000619518523171436,Sell, ,79.8,
79.9,0.655121878771812,-0.00124490792027077,release, ,79.9,-0.000285955381947645
79.85,0.638399458172212,0.00125430985194441, , ,,
79.75,0.677237812176031,-0.00062499754849088, , ,,
79.8,0.77229131417357,-0.00125117113292239,Sell, ,79.8,
79.9,0.78060399324371,0.00062774392694287, ,,,
80,0.785209846277682,0.00313165653529857, ,,,
80,0.71354933296563,0.00250469728764968,release,,80,-0.000571553096032407
80,0.723175396790292,0.00125156445556929, ,,,
80.05,0.645047940052525,0.000624999999999876, , ,,
79.95,0.654754824370203,-0.000624219237976287, , ,,
79.95,0.66648952405407,-0.000624219237976287, , ,,
80.05,0.66246174072327,1.56250061034147E-06, , ,,
80.1,0.64268970941157,0.00187539135757464, , ,,
80.05,0.626534449371471,0.00125117163223132, , ,,
80.05,0.659757399947805,3.89893644814343E-07, , ,,
80.15,0.605440623800618,0.000624999512632951, , ,,
80.15,0.555063339554548,0.00124921923797627, , ,,
80.1,0.623048801370024,0.000625388919822667, , ,,
79.95,0.671863289394849,-0.00249648949418346, , ,,
80.05,0.629889151643382,-0.00124570775559696, , ,,
80.15,0.692044829948308,0.000627341800532921, , ,,
80.25,0.781503635407542,0.00374766161286955, ,Buy,80.25,
80.35,0.767181308420401,0.00374298579328602, ,release,80.35,0.000283988254209611
80.2,0.712321509444304,0.000626933947966979, ,,,
")

Data <- read.table(dd, header = TRUE, sep = ",")
close(dd) 
Data                         

1条回答
【Aperson】
2楼-- · 2019-08-28 02:00

Here's an implementation of the basic moving average cross system. It should be trivial to adjust it to fit your needs.

library(quantmod)
library(tseries) # for maxdrawdown if you want it

x <- getSymbols("SPY", src="yahoo", from="2012-01-01", to="2012-12-31", auto.assign=FALSE)
n1 <- 20 # for short term moving average
n2 <- 50 # for long term moving average

x$ma1 <- SMA(Ad(x), n1) # add a short term MA
x$ma2 <- SMA(Ad(x), n2) # add a long term MA
x$spd <- x$ma1 - x$ma2 # difference between the two
x$spd[1:n2] <- 0 # flat until we have enough data to calculate both MAs
x$cross <- c(0, diff(x$spd > 0, na.pad=FALSE)) # short cross long
x$pos <- NA # Position
x$pos[x$cross == 1] <- 1 # long where it crosses from below
x$pos[x$cross == -1] <- -1 # short where it crosses from above
# fill forward your position until you get the next signal.  Also, you have to 
# lag your signal because today's return will be a result of yesterday's position
x$pos <- c(0, lag(na.locf(x$pos), na.pad=FALSE)) 
x$pos[is.na(x$pos)] <- 0
x$ret <- c(0, ROC(Ad(x), na.pad=FALSE))
x$cumret <- cumsum(x$pos * x$ret)
out <- data.frame(n1=n1, n2=n2, cumret=as.numeric(last(x$cumret)), 
                  mdd=maxdrawdown(x$cumret)$maxdrawdown, ntrades=sum(abs(x$cross)))
out
tail(x)

Edit

Ok then, using your data

library(quantmod) # for Lag.  Also loads zoo which is needed for na.locf, and 
                  # TTR which is needed for ROC
x <- Data[, 1:3]
x$pos <- NA
x$pos[with(x, nSignal >= 0.7 & Trend < 0)] <- -1
x$pos[with(x, nSignal >= 0.7 & Trend > 0)] <- 1
x$pos <- na.locf(x$pos)
x$pos[is.na(x$pos)] <- 0 # first few rows are NA; replace with 0 meaning "no position"
x$ret <- ROC(x$PriceTao) * Lag(x$pos) # yesterdays position * return from yesterday to today
x

Note that you are using a data.frame which is slower than a matrix. Also, you do not have any dates or times associated with your data. IMHO xts or zoo would be a better data structure if you actually have time series data.

查看更多
登录 后发表回答