2
$\begingroup$
import io
import pandas as pd
import QuantLib as ql

data = io.StringIO("""Start Date    Days    Ticker  Last    Rate    6 Mo    1 Yr    2 Yr    3 Yr    5 Yr    7 Yr    10 Yr
08/01/2024  48  SFRM4   94.6524 5.3476  5.062   4.741   4.236   3.988   3.823   3.843   
09/18/2024  91  SFRU4   94.955  5.045   4.872   4.551   4.11    3.902   3.777   3.815   
12/18/2024  91  SFRZ4   95.36   4.64    4.472   4.217   3.904   3.764   3.708   3.775   
03/19/2025  91  SFRH5   95.745  4.255   4.129   3.952   3.748   3.662   3.663   3.751   
06/18/2025  91  SFRM5   96.04   3.96    3.874   3.762   3.64    3.594   3.64    3.741   
09/17/2025  91  SFRU5   96.25   3.75    3.697   3.635   3.571   3.555   3.633   3.742   
12/17/2025  91  SFRZ5   96.39   3.61    3.581   3.554   3.53    3.536   3.639   3.752   
03/18/2026  91  SFRH6   96.48   3.52    3.508   3.506   3.509   3.533   3.654   3.767   
06/17/2026  91  SFRM6   96.535  3.465   3.465   3.479   3.502   3.541   3.674   3.786   
09/16/2026  91  SFRU6   96.565  3.435   3.442   3.467   3.506   3.556   3.698   3.807   
12/16/2026  91  SFRZ6   96.58   3.42    3.432   3.465   3.518   3.579   3.724   3.827   
03/17/2027  91  SFRH7   96.585  3.415   3.432   3.471   3.537   3.608   3.752   3.85    
06/16/2027  91  SFRM7   96.58   3.42    3.437   3.485   3.561   3.64    3.782       
09/15/2027  91  SFRU7   96.575  3.425   3.45    3.504   3.59    3.675   3.811       
12/15/2027  91  SFRZ7   96.555  3.445   3.471   3.531   3.625   3.711   3.84        
03/15/2028  98  SFRH8   96.535  3.465   3.495   3.562   3.665   3.75    3.871       
06/21/2028  91  SFRM8   96.505  3.495   3.528   3.599   3.709   3.79    3.9     
09/20/2028  91  SFRU28  96.47   3.53    3.566   3.638   3.752   3.827   3.928       
12/20/2028  91  SFRZ28  96.43   3.57    3.606   3.683   3.794   3.863   3.952       
03/21/2029  91  SFRH29  96.39   3.61    3.644   3.732   3.836   3.898   3.976       
06/20/2029  91  SFRM29  96.355  3.645   3.692   3.779   3.875   3.93            
09/19/2029  91  SFRU29  96.295  3.705   3.75    3.827   3.912   3.959           
12/19/2029  91  SFRZ29  96.24   3.76    3.796   3.867   3.944   3.985           
03/20/2030  91  SFRH30  96.205  3.795   3.831   3.901   3.971   4.009           
06/19/2030  91  SFRM30  96.17   3.83    3.864   3.932   3.996   4.028           
09/18/2030  91  SFRU30  96.14   3.86    3.897   3.959   4.016   4.045           
12/18/2030  91  SFRZ30  96.105  3.895   3.924   3.984   4.034   4.057           
03/19/2031  91  SFRH31  96.085  3.915   3.944   4.004   4.053   4.07            
06/18/2031  91  SFRM31  96.065  3.935   3.965   4.022   4.067               
09/17/2031  91  SFRU31  96.045  3.955   3.985   4.037   4.078               
12/17/2031  91  SFRZ31  96.025  3.975   4   4.048   4.084               
03/17/2032  91  SFRH32  96.015  3.985   4.008   4.066   4.093               
06/16/2032  91  SFRM32  96.01   3.99    4.015   4.075                   
09/15/2032  91  SFRU32  96  4   4.043   4.084                   
12/15/2032  91  SFRZ32  95.955  4.045   4.053   4.085                   
03/16/2033  91  SFRH33  95.98   4.02    4.041   4.085                   
06/15/2033  98  SFRM33  95.98   4.02    4.034                       
09/21/2033  91  SFRU33  95.995  4.005   4.046                       
12/21/2033  84  SFRZ33  95.95   4.05                            
""")
df = pd.read_csv(data, sep='\t')
df['Start Date'] = pd.to_datetime(df['Start Date'])
df['contract_month'] = df['Ticker'].apply(lambda x: 3 if x[3] == 'H' else 6 if x[3] == 'M' else 9 if x[3] == 'U' else 12)

Creating the curve

dates = []
rates = []
futures = []
for i, row in df.iterrows():
    price = row['Last']    
    year = row['Start Date'].year
    future = ql.SofrFutureRateHelper(price, row['contract_month'], year, ql.Quarterly)
    futures.append(future)

curve = ql.PiecewiseLinearZero(2, ql.TARGET(), futures, ql.Actual360())
yts = ql.YieldTermStructureHandle(curve)
engine = ql.DiscountingBondEngine(yts)

Viewing the nodes

curve.nodes()

Error

RuntimeError: 1st iteration: failed at 1st alive instrument, pillar September 18th, 2024, maturity September 18th, 2024, reference date August 1st, 2024: missing rate on June 19th, 2024 for index SOFRON Actual/360

Do I get the above error because the contract start date begins on Juneteenth? Is this a bug in the library or am I failing to construct the curve properly?

$\endgroup$

1 Answer 1

3
$\begingroup$

It's not shown in your code, but I assume you're also setting the evaluation date and adding to the SOFR instance the known past fixings, right?

If that's the case, what you're hitting was in fact a bug in the library; it was fixed in version 1.35, released last week. Upgrading should fix the problem.

$\endgroup$
2
  • 1
    $\begingroup$ I was on a version <1.35. After updating, I am now getting a new error. I do not want to hijack this question to troubleshoot the following error: RuntimeError: 1st iteration: failed at 1st alive instrument, pillar September 18th, 2024, maturity September 18th, 2024, reference date August 2nd, 2024: negative time (-0.00555556) given $\endgroup$
    – jpkey
    Commented Jul 31 at 19:06
  • 1
    $\begingroup$ I suggest you write to the QuantLib mailing list and post some code that can reproduce the problem. $\endgroup$ Commented Jul 31 at 21:19

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.