Search code examples
rquantitative-financetradingback-testing

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!


Solution

  • 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 & DiffFair[i] > -13 & 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)
      } 
    
    else if (DiffFair[i] <= -13 & firstPosy == FALSE) {
        firstPosy = TRUE
        lastChangePosy = DiffFair[i]
        steps <- c(steps, round_any(DiffFair[i] + 10, 3, f = ceiling) - 10)
        buyPrices <- c(buyPrices, DiffFair[i])
        targetProfit <- c(targetProfit, -5)
        posy <- c(posy, tail(posy, n=1) + (-round_any(DiffFair[i] + 10, 3, f = ceiling) / 3) + 1)
      }
    
      # 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) {
        if (tail(targetProfit, n=1) == -5) {
          posy <- c(posy, 0)
        }
        else {
          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)