2013-03-07 2 views
5

Я пытаюсь оценить очень базовую связь с плавающей процентной ставкой в ​​python, используя обломок SWIG Quantlib (v1.2). Я изменил пример, включенный в документацию.Ценообразование плавающей облигации в квантиле с использованием Python

У меня есть облигация на 4 года. Libor установлен на 10%, а спрэд облигации равен 0. Мой вопрос заключается в том, что если я дисконтирую по ставке 10%, почему нет PV облигации 100? Я получаю значение 99.54.

Спасибо!

from QuantLib import * 

frequency_enum, settle_date = 4, Date(5, 1, 2010) 
maturity_date = Date(5, 1, 2014) 
face_amount = 100.0 
settlement_days = 0 
fixing_days = 0 

calendar = NullCalendar() 
settle_date = calendar.adjust(settle_date) 
todays_date = calendar.advance(settle_date, -fixing_days, Days) 
Settings.instance().evaluationDate = todays_date 

rate = 10.0/100.0 

flat_forward = FlatForward(settle_date, 
          rate, 
          Thirty360(), 
          Compounded, 
          frequency_enum) 

discounting_term_structure = RelinkableYieldTermStructureHandle(flat_forward) 
index_term_structure = RelinkableYieldTermStructureHandle(flat_forward) 

index = USDLibor(Period(3, Months), index_term_structure) 

schedule = Schedule(settle_date, 
        maturity_date, Period(frequency_enum), 
        NullCalendar(), 
        Unadjusted, Unadjusted, 
        DateGeneration.Forward, False) 

floating_bond = FloatingRateBond(settlement_days, 
           face_amount, 
           schedule, 
           index, 
           Thirty360(), 
           Unadjusted, 
           fixing_days, 
           [], # Gearings 
           [0], # Spreads 
           [],  # Caps 
           [],  # Floors 
           False, # Fixing in arrears 
           face_amount, 
           settle_date) 

bond_engine = DiscountingBondEngine(discounting_term_structure) 
floating_bond.setPricingEngine(bond_engine) 

# coupon pricers 
pricer = BlackIborCouponPricer() 

volatility = 0.0 
vol = ConstantOptionletVolatility(settlement_days, 
            calendar, 
            Unadjusted, 
            volatility, 
            Thirty360()) 

pricer.setCapletVolatility(OptionletVolatilityStructureHandle(vol)) 
setCouponPricer(floating_bond.cashflows(), pricer) 

print floating_bond.NPV(), floating_bond.cleanPrice(), floating_bond.dirtyPrice() 

ответ

4

купоны ставки фиксируются с помощью дневного счетчика USDLibor (то есть, факт/360), которые не соответствуют день выплаты счетчика вы предоставили (30/360). Вы можете увидеть его, осматривая купоны:

cfs = floating_bond.cashflows() 
coupons = [ as_coupon(c) for c in cfs[:-1] ] # the last one is the redemption 
print [ (c.rate(), c.accrualPeriod()) for c in coupons ] 

, который дает вам T = 0,25 для всех купонов, но ставки ниже, чем на 10%.

Для того, чтобы получить цену, которую вы хотите, у вас есть соответствие скорости и периода начисления. Один из способов - передать Actual360() в качестве счетчика дневных облигаций, который дает мне цену 100.002 на моей машине (я еще не исследовал, но несоответствие может быть связано с датой окончания фиксации LIBOR, которая определяется с использованием в календаре USD и может не совпадать с окончанием купона). Другой способ - создать пользовательский индекс LIBOR с внутренним счетчиком 30/360 дней; Я не пробовал это сам, но вы можете сделать это, создав соответствующий экземпляр класса IborIndex.

+2

Большое спасибо. Я создал собственный индекс, и я получил точный результат 100.0! Пользовательский индекс: 'index = IborIndex ('USD Libor', Period (3, Months), sett_days, USDCurrency(), NullCalendar(), Unadjusted, False, Thirty360(), index_term_structure)' – ducky

Смежные вопросы