Home > Blockchain >  Is it possible to flip a formula in R?
Is it possible to flip a formula in R?

Time:04-17

I was working with a project and I used the VaR() function from the PerformanceAnalytics package to calculate Value-at-risk. I wanted to find out the probability of a stock generating making a loss of 1% or more. I found a solution to the problem by plugging numbers in to the probability variable, and controlling to see if it was approaching -1%. However, I was curious if it was possible to flip the formula so that I can just plug in the output and then the function will produce what would have been the input.

Produced the loss at 97.5% probability:

VaR(DNOlog, p = 0.975)

Produced a loss of -1% by changing the probability until it fit:

VaR(DNOlog, p = 0.6512184)

CodePudding user response:

What you want is the inverse function. If it is not too expensive to compute a lot of values of your function, then you can get a good approximation of this by computing many x-y pairs and then getting y as a function of x. Since you don't really say what your function is, I will use a simple function y = x sin(x) as an example.

x = seq(0,6, 0.01)
y = x   sin(x)
InverseFunction = approxfun(y,x)

## Test with an example
InverseFunction(4)      ## gives 4.967601

x1 = 4.967601
x1   sin(x1)            ## 3.999991

If you want more accuracy, use a smaller spacing between the x's.

CodePudding user response:

Let's get a reproducible example to demonstrate how you would go about this:

library(PerformanceAnalytics)

set.seed(2)
returns <- rnorm(1000, sd = 0.01)

This gives us a sensible result from VaR

VaR(returns, p = 0.975)
#>            [,1]
#> VaR -0.01893631

To reverse this, we can use uniroot. This is a function which uses an iterative approach to finding the input value that makes a function return 0:

inverse_VaR <- function(x, target) {
  f <- function(p) VaR(x, p)[1, 1] - target
  uniroot(f, c(0.6, 0.99999))$root
}

In our example, if we want to find the p value that makes VaR give an output of -0.01 with our vector returns, we can do:

inverse_VaR(returns, -0.01)
#> [1] 0.8483029

And to show this works, we can do:

VaR(returns, 0.8483029)
#>             [,1]
#> VaR -0.009999994

Created on 2022-04-16 by the reprex package (v2.0.1)

  • Related