Kevin Chen Kevin Chen - 3 years ago 142
R Question

Backtesting open position counter for trading in R

Getting started on backtesting some trading data, in particular a very basic mean reversion idea and can't get my head around how to approach this concept.

How would I go about having a running 'posy' increase by 1 once DifFromFv (the deviation from fair value) reaches -10 and subsequently 'posy' increases by 1 as DifFromFv extends by multiples of -3 (-13,-16,-19, etc.) whilst having 'posy' decrease by 1 every time DifFromFv reverts back +5 from last changed 'posy'? Simply put, I am buying once the DifFromFv reaches 10 points and averaging every 3 points, whilst taking each individual average out for 5 points profit.

E.g:

DifFromFv posy
0.00 0
-10.00 1 #initial clip (target profit -5.00)
-11.50 1
-13.00 2 #avg #1 (target profit -8.00)
-16.60 3 #avg #2 (target profit -11.00)
-12.30 3
-11.00 2 #taking profit on avg #2
-14.10 2
-8.00 1 #taking profit on avg #1
-7.00 1
-5.00 0 #taking profit on initial clip


It should be noted that the take profit for every clip is consistently set at -5,-8,-11,etc. increments regardless of where the averages are filled as seen by the target profit for avg #2 being at -11.00 rather than -11.60. This is both to reduce margin of error in real-life fills vs data fills and also I'm pretty sure should make the approach to this concept a lot easier to think about.

Thanks in advance!

Answer Source

Next time please provide some code, even though your explanation is quite clear. However, you didn't mention how you want to deal with large jumps in DifFromFv (for instance, if it goes from -3 to -18), so I leave it up to you.

Here is the code with comments:

library(plyr)

firstPosy = FALSE

DiffFair <- c(0, -10, -11.5, -13, -16.6, -12.3, -11, -14.1, -8, -7, -5) # Your data here
posy <- c(0)

buyPrices <- c(0) # Stores the prices at which you by your asset
targetProfit <- c(0) # Stores the target profit alongside with the vector above

steps <- c(0) # Stores your multiples of -3 after -10 (-10, -13, -16...)
PNL = 0

for (i in 2:length(DiffFair)) {

  # Case where posy increments for the first time by one

  if (DiffFair[i] <= -10 & firstPosy == FALSE) {
    firstPosy = TRUE
    posy <- c(posy, 1)
    steps <- c(steps, round_any(DiffFair[i], 10, f = ceiling))
    lastChangePosy = DiffFair[i]
    buyPrices <- c(buyPrices, DiffFair[i])
    targetProfit <- c(targetProfit, -5)
  } 

  # Posy increase

  else if (tail(steps, n=1) > round_any(DiffFair[i] + 10, 3, f = ceiling) - 10 & DiffFair[i] <= -10) {
    posy <- c(posy, posy[i-1] + 1)
    steps <- c(steps, round_any(DiffFair[i] + 10, 3, f = ceiling) -10)
    lastChangePosy = DiffFair[i]

    buyPrices <- c(buyPrices, DiffFair[i])
    targetProfit <- c(targetProfit, tail(targetProfit, n=1) - 3)
  }

  # Posy decrease

 else if (DiffFair[i] >= tail(targetProfit, n=1) & tail(posy, n=1) > 0) {
    posy <- c(posy, posy[i-1] - 1)
    lastChangePosy = DiffFair[i]

    # Compute PNL and delete the target profit and buy price from the vectors
    PNL = PNL + (DiffFair[i] - tail(buyPrices, n=1))
    buyPrices <- buyPrices[-length(buyPrices)]
    targetProfit <- targetProfit[-length(targetProfit)]
    steps <- steps[-length(steps)]

    if (DiffFair[i] > -10) {
      firstPosy = FALSE
    }

  }

  # Posy doesn't change

  else {
    posy <- c(posy, posy[i-1])
  }

}

print(PNL)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download