rdplyrfinanceperformanceanalytics

profit drawdown of each column in data.frame


I want to calculate the profit/drawdown of each column A:C in the data.frame below. Header A thru C can be considered like a stock ticker symbol. Each row can be considered the hourly closing price. The pricedate and hour could be combined to form a timestamp for this time series of data.

I have tried using the fTrading and PerformanceAnalytics package to calculate the max drawdown, but keep getting errors. I don't care when the max drawdown occurs. I just need the amount of the max drawdown so I can use it to calculate the the profit/drawdown (profit divided by max drawdown) ratio.

Data:

hourlyclose <- data.frame(pricedate = as.Date('2019-12-18'), hour = c(1,2,3,4,5), A = c(3,5,6,2,4), B = c(1,9,7,11,4), C = c(0,2,5,4,9))

I am desiring an output of second data.frame with a column each for the stock symbol, the profit-drawdown ratio, and just the profit (which is the last row minus the first row in my example hourlyclose data.frame).

The resulting data.frame should look like:

Stock     pdd      profit
 A        0.25        1
 B        0.43        3
 C        9.0         9

I would prefer to use the tidyverse and either of those finance packages for operations as much as possible.

Drawdown definition: A drawdown is a measure of how much the price goes down before it reaches or exceeds the previously high price.

Max Drawdowns for each column:

For "A" the max drawdown is 4 because A was at a high of 6 and then went down to 2.

For "B" there are two drawdowns, but only one max drawdown. There is a reduction in stock price from 9 to 7, for a drawdown of 2. But the stock reaches a new high the next row to 11, but then reduces down to 4, for a drawdown of 7. So the max drawdown is 7 for "B".

For "C" the stock price has a reduction from 5 to 4 for a max drawdown of 1.


Solution

  • We can get the data in long format, group_by name and calculate the drawdown value using cummax and max. Profit is calculated by subtracting last by the first value and pdd is division of profit by drawdown.

    library(dplyr)
    
    hourlyclose %>%
      tidyr::pivot_longer(cols = A:C) %>%
      group_by(name) %>%
      summarise(drawdown = max(cummax(value) - value), 
                profit  = last(value) - first(value), 
                pdd = profit/drawdown)
    
    # A tibble: 3 x 4
    #  name  drawdown profit   pdd
    #  <chr>    <dbl>  <dbl> <dbl>
    #1 A            4      1 0.25 
    #2 B            7      3 0.429
    #3 C            1      9 9