0
$\begingroup$

Hope this question isn't too naive. I've been trying to replicate the Monte Carlo method using sampling without replacement as described in the Jaekle & Tomasini book (Trading Systems: A New Approach to System Development and Portfolio Optimisation, 2nd Edition, Ch 4, pp 84-89). I took the P/L trade values from Luxor (GBP/USD) strategy results in the luxor-p066.RData dataset that accompanies the quantstrat R package. I wrote a little R script to store the trade P/L values in a vector, sample without replacement, and calculate the maximum drawdown for each simulation. My results, however, seem strange, as they cluster at the highest maximum drawdown, as shown in the section following the code below.

My R code is as follows:

data("luxor-p066")
pnl <- portfolio.luxor$symbols$GBPUSD$txn[, "Gross.Txn.Realized.PL"]
head(pnl)   # Check
indices <- which(pnl == 0)   # Remove trade entries (P/L = 0) 
pnl <- pnl[-indices]
pnl_df <- data.matrix(as.data.frame(pnl))   # Convert xts to vector

max_drawdown <- function(vec)
{
  peak <- vec[1]
  max_dd <- 0.0
  
  for (k in 1:length(vec))
  {
    if(vec[k] < peak)
      max_dd = max(peak - vec[k], max_dd)
   else if(peak < vec[k])
    peak = vec[k]
  }
  return(max_dd)
}

# Sanity check
max_drawdown(pnl_df)    # 14670

max_dd_vec <- vector("numeric")
for(k in 1:100)
{
  max_dd_vec <- c(max_dd_vec, max_drawdown(sample(pnl_df)))
}

(sort(max_dd_vec, decreasing = TRUE))

The output is as follows:

# Note the clustering at worst Max DD = 17137
# [1] 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137
# [15] 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137
# [29] 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137 17137
# [43] 16307 16307 16307 16307 16307 16307 16307 16307 16307 16307 16307 16307 16307 16307
# [57] 16307 16307 16307 16307 16307 16307 16307 16307 15067 15067 15067 15067 15067 14670
# [71] 14670 14670 14670 14670 14670 14670 14670 14670 14670 14670 14670 14520 14520 14520
# [85] 14520 14260 14260 14260 14260 13840 13840 13840 13730 13727 13727 13727 13727 13727
# [99] 13727 13380

In the Jaekle & Tomasini book, they seem to imply (albeit via a coin toss example) that the resulting distribution should be somewhat bell-shaped, from which one should be able to determine lower confidence bounds on worst possible maximum drawdown, but this is not what I'm seeing. Instead, it resembles more of a cumulative distribution, which I have not found discussed in the book.

Could someone perhaps explain this? Am I doing something wrong, or am I in fact generating an empirical CDF?

Thanks in advance.

$\endgroup$

1 Answer 1

1
$\begingroup$

I do not know the book or that dataset (which, I think, is from package quantstrat?). But it seems that your pnl is daily profit/loss. But drawdown is computed on the cumulative profit/loss.

Here is why you get 17137:

## sort(coredata(pnl))
##   [1] -7570 -6740 -5500 -4160 -4035 -3970 -3750 -3625 -3550
##  [10] -3250 -3240 -3220 -3152 -3053 -2640 -2520 -2480 -2440
## ## ....
## [253]  4050  4260  4420  4480  5810  6060  6160  6690  6950
## [262]  7100  9567

Whenever the two extremes end up next to each other, then you get 9567+7570 == 17137.

Try to use cumsum around pnl:

max_drawdown(cumsum(pnl_df))
## [1] 17370

NMOF::drawdown(cumsum(pnl_df), relative = FALSE)
## $maximum
## [1] 17370
## 
## $high
## [1] 35830
## 
## $high.position
## [1] 128
## 
## $low
## [1] 18460
## 
## $low.position
## [1] 163
$\endgroup$
3
  • $\begingroup$ OK, I've had a closer look at it, and I see the critical error, as you say, of using the individual trades rather than the cumulative equity line. It has been almost two years since I touched this stuff. I actually wrote a brute force equivalent (since I ultimately need to implement it in C++), and it matches your results. Thank you very much!!! $\endgroup$
    – djhanson
    Oct 21, 2023 at 5:39
  • $\begingroup$ PS: I tried to give you a checkmark, but I don't have the reputation on quant stack exchange yet (unlike stack overflow). In any case, I guess it gets recorded, so hopefully that helps. Thanks again! $\endgroup$
    – djhanson
    Oct 21, 2023 at 5:42
  • $\begingroup$ No worries; I am glad it helped. $\endgroup$ Oct 23, 2023 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.