Search code examples
rfinancial

dataframe math to calculate profit based on indicator


Simple explanation: My Goal is to figure out how to get the profit column shown below. I am trying to calculate the difference in val for every pair of changing values (-1 to 1 and 1 to -1).

  1. If the starting indicator is 1 or -1 store the value.
  2. Find the next indicator that is opposite (so -1 on row 3). Save this val. Subtract the first value from it (.85.-.84). Store that in the profit column.
  3. repeat

Specific to this case

  1. Go until find next opposite val (on row 4). Save this value. Subtract values, save in profit column. ()
  2. Go until find next opposite val (on row 8). Save this value. Subtract values, save in profit column. Financial explanation (if it is useful) I am trying to write a function to calculate profit given a column of values and a column of indicators (buy/sell/hold). I know this is implemented in a few of the big packages (quantmod, quantstrat), but I cant seem to find a simple way to do it.

    df<-
    

    data.frame(val=c(.84,.83,.85,.83,.83,.84,.85,.81),indicator=c(1,0,-1,1,0,1,1,-1))

    df
    val      indicator  profit
    1 0.84         1       NA
    2 0.83         0       NA
    3 0.85        -1       .01  based on: (.85-.84) from 1 one to -1
    4 0.83         1       .02  based on (.85-.83) from -1 to 1
    5 0.83         0       NA 
    6 0.84         1       NA 
    7 0.85         1       NA
    8 0.81        -1       -.02  based on (.81-.83) from last change (row 4) to now 
    

Notes

  • multiple indicators should be ignored (1111) means nothing beyond the first one which should be stored. (line 4 is stored, lines 5,6,7 are not)
  • ignore 0, holds do not change profit calculation

I am happy to provide more info if needed.


Solution

  • It was easier for me to work it out in my head after splitting the problem into two parts, which correspond to the two loops shown below. The first part involves flagging the rows where there was a change in the indicator value, while the second part involves subtracting the val's from the relevant rows (i.e., those selected in part 1). FYI, I assume you meant to put -.02 for row 4 in your example? If not, then please clarify which rows get subtracted from which when calculating profit.

    data.frame(val=c(.84,.83,.85,.83,.83,.84,.85,.81),
               indicator=c(1,0,-1,1,0,1,1,-1)) -> x
    
    x$num <- seq_along(x$val)
    x$rollingProf <- NA
    # start with indicator = 1
    
    indicator <- 1
    value <- .84
    
    for (i in 1:(nrow(x) - 1)) {        
        x[i + 1, "indicator"] -> next_
        if (indicator * -1 == next_) {
            1 -> x[i + 1, "rollingProf"]
            indicator <- next_
        } 
    }
    
    x[!is.na(x$rollingProf), c("val", "num")] -> q
    for (i in 2:nrow(q)) {
        q[i, "val"] - q[i - 1, "val"] -> q[i, "change"]
    }