Question about the Ulcer Index calculation in PerformanceAnalytics

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about the Ulcer Index calculation in PerformanceAnalytics

Ilya Kipnis
I'm working on porting over an interesting risk metric that I found out about through a twitter exchange with the usual suspects (Adam Butler of ReSolve, Wayne Himelsein) called the Serenity Ratio, found here:

https://www.keyquant.com/Download/GetFile?Filename=%5CPublications%5CKeyQuant_WhitePaper_APT_Part1.pdf

Now, I've run into an issue, namely with the calculation of the Ulcer Index:

Now, as I understand it, the Ulcer Index is the root-mean-square (read: volatility, I.E. standard deviation) of drawdowns. However, when I check the UlcerIndex function in R, it uses the DrawdownPeak function, which has a different calculation than PerformanceAnalytics:::Drawdowns .  

Furthermore, taking the standard deviation of *either* PerformanceAnalytics:::Drawdowns *or* DrawdownPeak of returns yields a different calculation than using the formal UlcerIndex function.  

Here is my script. Can someone explain the choices made with the UlcerIndex implementation in the package?  

Sample script:

getSymbols('SPY', from = '1990-01-01')
spyRets <- na.omit(Return.calculate(Ad(SPY)))
compare <- cbind(PerformanceAnalytics:::Drawdowns(spyRets), 
                 xts(DrawdownPeak(spyRets), order.by = index(spyRets)))
colnames(compare) <- c("PerfA:::Drawdowns", "DrawdownPeak")
plot(compare, legend.loc = 'bottomleft')
differentUIs <- c(StdDev(PerformanceAnalytics:::Drawdowns(spyRets)),
                  StdDev(DrawdownPeak(spyRets)),
                  UlcerIndex(spyRets))
names(differentUIs) <- c("StdDevDrawdowns", "StdDevDDPeak", "UlcerInex")

Outputs:

image.png
image.png

In the interest of replication (I.E. Python has none of these functions in any library I know of), and for the correct calculation of other functions dependent on the Ulcer Index (UPI, Serenity Ratio), can someone help me resolve/understand the discrepancies here?

Thanks so much.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Question about the Ulcer Index calculation in PerformanceAnalytics

Eric Berger
Hi Ilya,
You  write that UI is a std dev of something, but that is not how it is defined. 
To be a standard deviation, there would have to be a subtraction of a mean somewhere, and that is not present. (Technically, UI is the square root of a semivariance.)

I hope that helps,
Eric


On Sun, Mar 7, 2021 at 3:22 PM Ilya Kipnis <[hidden email]> wrote:
I'm working on porting over an interesting risk metric that I found out about through a twitter exchange with the usual suspects (Adam Butler of ReSolve, Wayne Himelsein) called the Serenity Ratio, found here:

https://www.keyquant.com/Download/GetFile?Filename=%5CPublications%5CKeyQuant_WhitePaper_APT_Part1.pdf

Now, I've run into an issue, namely with the calculation of the Ulcer Index:

Now, as I understand it, the Ulcer Index is the root-mean-square (read: volatility, I.E. standard deviation) of drawdowns. However, when I check the UlcerIndex function in R, it uses the DrawdownPeak function, which has a different calculation than PerformanceAnalytics:::Drawdowns .  

Furthermore, taking the standard deviation of *either* PerformanceAnalytics:::Drawdowns *or* DrawdownPeak of returns yields a different calculation than using the formal UlcerIndex function.  

Here is my script. Can someone explain the choices made with the UlcerIndex implementation in the package?  

Sample script:

getSymbols('SPY', from = '1990-01-01')
spyRets <- na.omit(Return.calculate(Ad(SPY)))
compare <- cbind(PerformanceAnalytics:::Drawdowns(spyRets), 
                 xts(DrawdownPeak(spyRets), order.by = index(spyRets)))
colnames(compare) <- c("PerfA:::Drawdowns", "DrawdownPeak")
plot(compare, legend.loc = 'bottomleft')
differentUIs <- c(StdDev(PerformanceAnalytics:::Drawdowns(spyRets)),
                  StdDev(DrawdownPeak(spyRets)),
                  UlcerIndex(spyRets))
names(differentUIs) <- c("StdDevDrawdowns", "StdDevDDPeak", "UlcerInex")

Outputs:

image.png
image.png

In the interest of replication (I.E. Python has none of these functions in any library I know of), and for the correct calculation of other functions dependent on the Ulcer Index (UPI, Serenity Ratio), can someone help me resolve/understand the discrepancies here?

Thanks so much.
_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Question about the Ulcer Index calculation in PerformanceAnalytics

Ilya Kipnis
Eric,

Thanks for the clarification on that part. The one *other* part that has me scratching my head, though, is the use of the DrawdownPeak function, which doesn't have quite the exact same calculations as the usual drawdown curve I'm accustomed to. Is there a reason for using this less common drawdown trajectory calculation, as opposed to the original drawdown curve?

-Ilya

On Sun, Mar 7, 2021 at 8:27 PM Eric Berger <[hidden email]> wrote:
Hi Ilya,
You  write that UI is a std dev of something, but that is not how it is defined. 
To be a standard deviation, there would have to be a subtraction of a mean somewhere, and that is not present. (Technically, UI is the square root of a semivariance.)

I hope that helps,
Eric


On Sun, Mar 7, 2021 at 3:22 PM Ilya Kipnis <[hidden email]> wrote:
I'm working on porting over an interesting risk metric that I found out about through a twitter exchange with the usual suspects (Adam Butler of ReSolve, Wayne Himelsein) called the Serenity Ratio, found here:

https://www.keyquant.com/Download/GetFile?Filename=%5CPublications%5CKeyQuant_WhitePaper_APT_Part1.pdf

Now, I've run into an issue, namely with the calculation of the Ulcer Index:

Now, as I understand it, the Ulcer Index is the root-mean-square (read: volatility, I.E. standard deviation) of drawdowns. However, when I check the UlcerIndex function in R, it uses the DrawdownPeak function, which has a different calculation than PerformanceAnalytics:::Drawdowns .  

Furthermore, taking the standard deviation of *either* PerformanceAnalytics:::Drawdowns *or* DrawdownPeak of returns yields a different calculation than using the formal UlcerIndex function.  

Here is my script. Can someone explain the choices made with the UlcerIndex implementation in the package?  

Sample script:

getSymbols('SPY', from = '1990-01-01')
spyRets <- na.omit(Return.calculate(Ad(SPY)))
compare <- cbind(PerformanceAnalytics:::Drawdowns(spyRets), 
                 xts(DrawdownPeak(spyRets), order.by = index(spyRets)))
colnames(compare) <- c("PerfA:::Drawdowns", "DrawdownPeak")
plot(compare, legend.loc = 'bottomleft')
differentUIs <- c(StdDev(PerformanceAnalytics:::Drawdowns(spyRets)),
                  StdDev(DrawdownPeak(spyRets)),
                  UlcerIndex(spyRets))
names(differentUIs) <- c("StdDevDrawdowns", "StdDevDDPeak", "UlcerInex")

Outputs:

image.png
image.png

In the interest of replication (I.E. Python has none of these functions in any library I know of), and for the correct calculation of other functions dependent on the Ulcer Index (UPI, Serenity Ratio), can someone help me resolve/understand the discrepancies here?

Thanks so much.
_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Question about the Ulcer Index calculation in PerformanceAnalytics

Farid Moussaoui-2
In reply to this post by Ilya Kipnis
Hi Ilya,

There is a reference in the code about how is implemented the Ulcer Index.

It is here also: http://www.tangotools.com/ui/ui.htm

Farid.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.