我已经引导了一条收益率曲线,并设法从该收益率曲线中提取折扣因子,但折扣因子是从评估日期引用的。这些贴现因子用于计算债券的现值,但如果评估日期与债券结算日期不同,则它们不能用于计算债券的脏价格。如何从债券结算日而不是评估日提取折扣因子。希望我的问题很清楚。
在下面找到我尝试用来提取折扣因子的部分代码;
fields = ['accrualStartDate', 'accrualEndDate', 'date', 'nominal', 'rate',
'amount', 'accrualDays', 'accrualPeriod']
BondCashflows = []
for cf in list(map(ql.as_fixed_rate_coupon, bond.cashflows()))[:-1]:
row = {fld: eval(f"cf.{fld}()") for fld in fields}
row['AccrualPeriod'] = round((row['accrualEndDate'] - row['accrualStartDate']) / 365, 4)
if row['date'] >= today:
row['ZeroRate (NPV)'] = round(curve.zeroRate(row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
row['ZeroRate (Dirty Price)'] = round(curve.forwardRate(bond.settlementDate(), row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
row['DiscFactor (NPV)'] = round(curve.discount(row['date']), 9)
row['DiscFactor (Dirty Price)'] = round(curve.discount(bond.settlementDate(), row['date']), 9)
else:
row['ZeroRate (NPV)'] = 0
row['ZeroRate (Dirty Price)'] = 0
row['DiscFactor (NPV)'] = 0 # or any other appropriate handling for dates before today
row['DiscFactor (Dirty Price)'] = 0 # or any other appropriate handling for dates before today
row['NPV'] = round(row['DiscFactor (NPV)'] * row['amount'], 9)
BondCashflows.append(row)
BondCashflows = pd.DataFrame(BondCashflows)
print(BondCashflows)
找到了一种解决方法,将评估日期到应计结束日期的折扣系数除以评估日期到债券结算日期的折扣系数,如下面的代码所示;
fields = ['accrualStartDate', 'accrualEndDate', 'date', 'nominal', 'rate',
'amount', 'accrualDays', 'accrualPeriod']
BondCashflows = []
for cf in list(map(ql.as_fixed_rate_coupon, bond.cashflows()))[:-1]:
row = {fld: eval(f"cf.{fld}()") for fld in fields}
row['AccrualPeriod'] = round((row['accrualEndDate'] - row['accrualStartDate']) / 365, 4)
if row['date'] >= today:
row['ZeroRate (NPV)'] = round(curve.zeroRate(row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
row['ZeroRate (Dirty Price)'] = round(curve.forwardRate(bond.settlementDate(), row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
row['DiscFactor (NPV)'] = round(curve.discount(row['date']), 9)
row['DiscFactor (Dirty Price)'] = round(curve.discount(row['date']) / curve.discount(bond.settlementDate()), 9)
else:
row['ZeroRate (NPV)'] = 0
row['ZeroRate (Dirty Price)'] = 0
row['DiscFactor (NPV)'] = 0 # or any other appropriate handling for dates before today
row['DiscFactor (Dirty Price)'] = 0 # or any other appropriate handling for dates before today
row['NPV'] = round(row['DiscFactor (NPV)'] * row['amount'], 9)
row['Dirty Price'] = round(row['DiscFactor (Dirty Price)'] * row['amount'], 9)
BondCashflows.append(row)
BondCashflows = pd.DataFrame(BondCashflows)
print(BondCashflows)