2
$\begingroup$

This is the first time I'm using quantlib, and I wanted to compare the velocity of quantlib with my own Python code.

I found a tutorial about Hull and White to generate the short rate paths with quantlib: (Tutorial about Hull and White)

The author seems to say that it is very simple to change the future instantaneous rate, which is a constant in the example... But when I replace it with an array of 361 values corresponding to the values of the future rate for the differents dates defined by the time step, I get the following error: TypeError: in method 'new_SimpleQuote', argument 1 of type 'Real'

I tried to investigate and search in the quantlib library how to fix this, but I havn't learned to code in C++ yet so I may need a little help

Thank you, and have a good day

PS: My input data is the zero-coupon curve at a certain time, so if it possible to use it directly instead of converting it to a future rate curve first, I'm interesed to know how to do it

Edit: This is my code

import QuantLib as ql
import matplotlib.pyplot as plt
import numpy as np

sigma = 0.1
a = 0.1
timestep = 360
length = 30 # in years
#forward_rate = 0.05 I replaced this line by an random array and it doesn't work
forward_rate=np.random.randn(361)
day_count = ql.Thirty360()
todays_date = ql.Date(15, 1, 2015)
print(ql.QuoteHandle(ql.SimpleQuote(forward_rate)))

ql.Settings.instance().evaluationDate = todays_date
spot_curve = ql.FlatForward(todays_date, 
ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count)
spot_curve_handle = ql.YieldTermStructureHandle(spot_curve)

hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma)
rng = ql.GaussianRandomSequenceGenerator(
           ql.UniformRandomSequenceGenerator(timestep, ql.UniformRandomGenerator()))
seq = ql.GaussianPathGenerator(hw_process, length, timestep, rng, False)

def generate_paths(num_paths, timestep):
    arr = np.zeros((num_paths, timestep+1))
    for i in range(num_paths):
        sample_path = seq.next()
        path = sample_path.value()
        time = [path.time(j) for j in range(len(path))]
        value = [path[j] for j in range(len(path))]
        arr[i, :] = np.array(value)
    return np.array(time), arr

num_paths = 10
time, paths = generate_paths(num_paths, timestep)
for i in range(num_paths):
    plt.plot(time, paths[i, :], lw=0.8, alpha=0.6)
plt.title("Hull-White Short Rate Simulation")
plt.show()
$\endgroup$
2
  • $\begingroup$ Hello and welcome to SE. Could you add a minimal reproducible example to your question that anyone willing to help could run to get the same error you're getting? This will make it easier to help you :) Thanks $\endgroup$
    – byouness
    Jul 9, 2019 at 9:18
  • 1
    $\begingroup$ @byouness Ok, I'm editing my post to add the code. Apparently I can't post the code in a comment because it is too long $\endgroup$ Jul 9, 2019 at 11:29

1 Answer 1

1
$\begingroup$

When you call ql.FlatForward it simply means you are constructing a rate curve that will lead to flat forward rates.

The constructor of this curve takes the forward rate as an input. If you want to change the input (say, because the market moved and forward value changed), then you can change the quote value with the new value like this. First, keep a pointer on the quote:

forward_rate = 0.05
quote = ql.SimpleQuote(forward_rate)
spot_curve = ql.FlatForward(todays_date, ql.QuoteHandle(quote), day_count)
print(spot_curve.zeroRate(1.0, ql.Continuous))
# 5.000000 % 30/360 (Bond Basis) continuous compounding

Then use the setValue() method to update the value, like this:

quote.setValue(0.04)
print(spot_curve.zeroRate(1.0, ql.Continuous))
# 4.000000 % 30/360 (Bond Basis) continuous compounding

You cannot pass an array of value to setValue(), the quote consists in a single value (= the value of the forward rate in this case). In particular, I don't understand why you want to make this forward random?

Now, to answer your other question, you can instantiate a zero curve directly using a list of dates and list of zero rates in this way:

ql.ZeroCurve(dates, rate_values, day_counter)

For example:

zero_curve = ql.ZeroCurve([todays_date + ql.Period(p) for p in ['6M', '1Y', '5Y', '10Y']],
                          [0.04, 0.05, 0.06, 0.57], ql.Actual365Fixed())

Then you can pass this curve to your ql.YieldTermStructureHandle just as you did, with your ql.FlatForward curve.

$\endgroup$
1
  • $\begingroup$ Ok thanks, I need to use a non-flat future rate, so I think I'm going to use the second method with ql.YieldTermStructureHandle. (I used a random input just to test if I could pass an array to the function, but I got an error so I havn't try with the real future rate curve) $\endgroup$ Jul 9, 2019 at 12:36

Your Answer

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

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