-1

...and a suggestion to Use a.any() or a.all().

I am new to python and i am trying to implement a sabr model. I have defined a function with the following parameters:

def haganimpliedvol(a,f,k,B,v,t,p):
    if k != f:
        z = v/a*math.pow(f*k,(1-B)/2)*math.log(f/k)
        xz = math.log((math.sqrt(1-2*p*z+math.pow(z,2))+z-p)/(1-p))
        
        sigma = a/math.pow(f*k,(1-B)/2)*(1 + math.pow(1-B,2)/24* math.pow(math.log(f/k),2)+\
                                        math.pow(1-B,4)/1920* math.pow(math.log(f/k),4))*\
                                        xz*\
                                        (1+(math.pow(1-B,2)/24*math.pow(a,2)/math.pow(f/k,1-B)+1/4*(p*B*v*a)/math.pow(f/k,(1-B)/2)+\
                                           (2-3*math.pow(p,2))/24*math.pow(v,2)))*t
        
    else:
        sigma = a/math.pow(f,1-B)*\
        (1+(math.pow(1-B,2)/24*math.pow(a,2)/math.pow(f,(2-2*B))+\
            1/4*(p*B*a*v)/math.pow(f,1-B)+(2-3*math.pow(p,2))/24*math.pow(v,2)))*t
    
    return(sigma)

Now I define another function to and call the haganimpliedvol() function

params = [0.4,0.6,0.1,-0.4]

def objective(params):
    global k,sigma_iv,t,f
    a = params[0]
    B = params[1]
    v = params[2]
    p = params[1]

    for (i,j,k) in zip(k,t,f):
        calc_vols = np.array([haganimpliedvol(a,f,k,B,v,t,p)])
    return(calc_vols)

As can be seen, a few parameters in the functions are list. I want to get an array as an output. However, I keep getting the message in the subject line.

martineau
  • 119,623
  • 25
  • 170
  • 301
Aditya
  • 1
  • 1
  • Please include the full stack traceback. – SuperStormer Jun 20 '22 at 22:40
  • 2
    Does this answer your question? [ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()](https://stackoverflow.com/questions/10062954/valueerror-the-truth-value-of-an-array-with-more-than-one-element-is-ambiguous) – mkrieger1 Jun 20 '22 at 22:46
  • Don't use a `if k != f:` if `k` or `f` is an array. – hpaulj Jun 21 '22 at 00:55

3 Answers3

0

Pay attention to the variables in this call:

 for (i,j,k) in zip(k,t,f):
     calc_vols = np.array([haganimpliedvol(a,f,k,B,v,t,p)])

for the zip to work, k,t, f have to be lists or arrays of matching size;

Done use k for an iteration variable; it is already used in the zip. I think you are just being careless here; or confused.

And the arguments to the hagen... function. Are the f, k, t supposed to be variables used in the zip? It would make more sense to use the iteration variables (i,j,?). Again, this just looks like you are careless, or don't care what happens.

As for the ambiguity error, that most likely arises in the

  if k != f:

If either k or f is an array (or both) the k!=f will be a boolean array. That can't be used in if, which requires a simple True or False value. It does not iterate on the conditions. It is a basic Python if - a switch.

This ambiguity error comes up frequently, in various contexts, but all with the same basic issue - using an array in a context that requires a scalar T/F. A simple web search should provide lots of examples.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
0

@hpaulj thank you for leading me on the right path. I vectorized my function and made some edits and now it is working fine.

haganimpliedvol = np.vectorize(haganimpliedvol,excluded = ['a','B','v','p'])

params = [0.2,0.7,0.01,-0.4]

def objective(params):
    global k,sigma_iv,t,f
    a = params[0]
    B = params[1]
    v = params[2]
    p = params[1]

    calc_vols = haganimpliedvol(a,f,k,B,v,t,p)
    return(calc_vols)
    
Aditya
  • 1
  • 1
-1

Are you sure you want to pass arrays into the haganimpliedvol() function? The general convention is to write functions which take a single input type.

Maybe call it one per item in the array?

Or write the function in a way that, if it sees the input is a list it iterates and if it sees the inputs arent lists then it just calculates it one time.

See this thread for ideas How to make a function that can handle single inputs or lists of inputs

  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation), you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that do not require clarification from the asker](https://meta.stackexchange.com/questions/214173). – AlexK Jun 21 '22 at 04:53