Fixed Income


Forwards

Forward Rate Agreement

class ql.ForwardRateAgreement(valueDate, maturityDate, position, strikeForward, notional, iborIndex, discountCurve=ql.YieldTermStructureHandle())
fra = ql.ForwardRateAgreement(
    ql.Date(15,6,2020),
    ql.Date(15,12,2020),
    ql.Position.Long,
    0.01,
    1e6,
    ql.Euribor6M(yts),
    yts
)
.NPV()
.businessDayConvention()
.calendar()
.dayCounter()
.discountCurve()
.fixingDate()
.forwardRate()
.forwardValue()
.impliedYield(underlyingSpotValue, forwardValue, settlementDate, compoundingConvention, dayCounter)
.incomeDiscountCurve()
.isExpired()
.settlementDate()
.spotIncome(yts)
.spotValue()

FixedRateBondForward

class ql.FixedRateBondForward(valueDate, maturityDate, Position::Type, strike, settlementDays, dayCounter, calendar, businessDayConvention, FixedRateBond, yieldTermStructure=ql.YieldTermStructureHandle(), incomeDiscountCurve=ql.YieldTermStructureHandle())

Position:

  • ql.Position.Long

  • ql.Position.Short

valueDate = ql.Date(24, 6, 2020)
maturityDate = ql.Date(31, 5, 2032)
position = ql.Position.Long
strike = 100
settlementDays = 2
dayCounter = ql.Actual360()
calendar = ql.TARGET()
businessDayConvention = ql.Following
bond = ql.FixedRateBond(2, ql.TARGET(), 100.0, ql.Date(31, 5, 2032), ql.Date(30, 5, 2035), ql.Period('1Y'), [0.05], ql.ActualActual())
bond.setPricingEngine(engine)
fwd = ql.FixedRateBondForward(
    valueDate, maturityDate, position, strike, settlementDays,
    dayCounter , calendar, businessDayConvention, bond, yts, yts)

Bonds

Bond

Redemptions and maturity are calculated from the coupon data, if available. Therefore, redemptions must not be included in the passed cash flows.

class ql.Bond(settlementDays, calendar, issueDate, coupons)
start = ql.Date(15,12,2019)
maturity = ql.Date(15,12,2020)
schedule = ql.MakeSchedule(start, maturity, ql.Period('6M'))

interest = ql.FixedRateLeg(schedule, ql.Actual360(), [100.], [0.05])
bond = ql.Bond(0, ql.TARGET(), start, interest)
.bondYield(dayCounter, compounding, frequency, accuracy=1e-08, maxEvaluations=100)
.bondYield(cleanPrice, dayCounter, compounding, frequency, settlementDate=Date, accuracy=1e-08, maxEvaluations=100)
bond.bondYield(100, ql.Actual360(), ql.Compounded, ql.Annual)
.dirtyPrice()
bond.dirtyPrice()
.dirtyPrice(yield, dayCount, compounding, frequency)
bond.dirtyPrice(0.05, ql.Actual360(), ql.Compounded, ql.Annual)

ZeroCouponBond

ql.ZeroCouponBond(settlementDays, calendar, faceAmount, maturityDate)
bond = ql.ZeroCouponBond(2, ql.TARGET(), 100, ql.Date(20,6,2020))

FixedRateBond

ql.FixedRateBond(settlementDays, calendar, faceAmount, startDate, maturityDate, tenor, coupon, paymentConvention)
ql.FixedRateBond(settlementDays, faceAmount, schedule, coupon, paymentConvention)
bond = ql.FixedRateBond(2, ql.TARGET(), 100.0, ql.Date(15,12,2019), ql.Date(15,12,2024), ql.Period('1Y'), [0.05], ql.ActualActual())

AmortizingFixedRateBond

ql.AmortizingFixedRateBond(settlementDays, notionals, schedule, coupons, accrualDayCounter, paymentConvention=Following, issueDate=Date())
notionals = [100,100,100,50]
schedule = ql.MakeSchedule(ql.Date(25,1,2018), ql.Date(25,1,2022), ql.Period('1y'))
bond = ql.AmortizingFixedRateBond(0, notionals, schedule, [0.03], ql.Thirty360())

FloatingRateBond

ql.FloatingRateBond(settlementDays, faceAmount, schedule, index, dayCounter, paymentConvention)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('6m'))
index = ql.Euribor6M()
ql.FloatingRateBond(2,100, schedule, index, ql.Actual360(), spreads=[0.01])

AmortizingFloatingRateBond

ql.FloatingRateBond(settlementDays, notionals, schedule, index, dayCounter)
notional = [100, 50]
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('1Y'))
index = ql.Euribor6M()
ql.AmortizingFloatingRateBond(2, notional, schedule, index, ql.ActualActual())

CMS Rate Bond

ql.CmsRateBond(settlementDays, faceAmount, schedule, index, dayCounter, paymentConvention, fixingDays, gearings, spreads, caps, floors)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('1Y'))
index = ql.EuriborSwapIsdaFixA(ql.Period('10y'))
ql.CmsRateBond(2, 100, schedule, index, ql.Actual360(), ql.ModifiedFollowing, fixingDays=2, gearings=[1], spreads=[0], caps=[], floors=[])

Callable Bond

ql.CallableFixedRateBond(settlementDays, faceAmount, schedule, coupons, accrualDayCounter, paymentConvention, redemption, issueDate, putCallSchedule)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('1Y'))
putCallSchedule = ql.CallabilitySchedule()

callability_price  = ql.CallabilityPrice(100, ql.CallabilityPrice.Clean)

putCallSchedule.append(
    ql.Callability(callability_price, ql.Callability.Call, ql.Date(15,6,2021))
)

ql.CallableFixedRateBond(2, 100, schedule, [0.01], ql.Actual360(), ql.ModifiedFollowing, 100, ql.Date(15,6,2020), putCallSchedule)

Convertible Bond

BondFunctions

bond = ql.FixedRateBond(
    2, ql.TARGET(), 100.0,
    ql.Date(15,12,2019), ql.Date(15,12,2024), ql.Period('1Y'),
    [0.05], ql.ActualActual())

Date Inspectors

ql.BondFunctions.startDate(bond)
ql.BondFunctions.maturityDate(bond)
ql.BondFunctions.isTradable(bond)

Cashflow Inspectors

ql.BondFunctions.previousCashFlowDate(bond)
ql.BondFunctions.previousCashFlowDate(bond, ql.Date(15,12,2020))
ql.BondFunctions.previousCashFlowAmount(bond)
ql.BondFunctions.previousCashFlowAmount(bond, ql.Date(15,12,2020))
ql.BondFunctions.nextCashFlowDate(bond)
ql.BondFunctions.nextCashFlowDate(bond, ql.Date(15,12,2020))
ql.BondFunctions.nextCashFlowAmount(bond)
ql.BondFunctions.nextCashFlowAmount(bond, ql.Date(15,12,2020))

Coupon Inspectors

ql.BondFunctions.previousCouponRate(bond)
ql.BondFunctions.nextCouponRate(bond)
ql.BondFunctions.accrualStartDate(bond)
ql.BondFunctions.accrualEndDate(bond)
ql.BondFunctions.accrualPeriod(bond)
ql.BondFunctions.accrualDays(bond)
ql.BondFunctions.accruedPeriod(bond)
ql.BondFunctions.accruedDays(bond)
ql.BondFunctions.accruedAmount(bond)

YieldTermStructure

crv = ql.FlatForward(2, ql.TARGET(), 0.04, ql.Actual360())
ql.BondFunctions.cleanPrice(bond, crv)
ql.BondFunctions.bps(bond, crv)
ql.BondFunctions.atmRate(bond, crv)

Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions

rate = ql.InterestRate(0.05, ql.Actual360(), ql.Compounded, ql.Annual)
ql.BondFunctions.cleanPrice(bond, rate)
ql.BondFunctions.bps(bond, rate)
ql.BondFunctions.duration(bond, rate)
ql.BondFunctions.convexity(bond, rate)
ql.BondFunctions.basisPointValue(bond, rate)
ql.BondFunctions.yieldValueBasisPoint(bond, rate)

Z-spread functions

crv = ql.FlatForward(2, ql.TARGET(), 0.04, ql.Actual360())
ql.BondFunctions.zSpread(bond, 101, crv, ql.Actual360(), ql.Compounded, ql.Annual)

Swaps

VanillaSwap

ql.VanillaSwap(type, nominal, fixedSchedule, fixedRate, fixedDayCount, floatSchedule, index, spread, floatingDayCount)

Types:

  • ql.VanillaSwap.Payer

  • ql.VanillaSwap.Receiver

calendar = ql.TARGET()
start = ql.Date(17,6,2019)
maturity = calendar.advance(start, ql.Period('5y'))

fixedSchedule = ql.MakeSchedule(start, maturity, ql.Period('1Y'))

floatSchedule = ql.MakeSchedule(start, maturity, ql.Period('6M'))

swap = ql.VanillaSwap(
    ql.VanillaSwap.Payer, 100,
    fixedSchedule, 0.01, ql.Thirty360(),
    floatSchedule, ql.Euribor6M(), 0, ql.Actual360()
)

Swap

ql.Swap(firstLeg, secondLeg)
fixedSchedule = ql.MakeSchedule(start, maturity, ql.Period('1Y'))
fixedLeg = ql.FixedRateLeg(fixedSchedule, ql.Actual360(), [100], [0.01])

floatSchedule = ql.MakeSchedule(start, maturity, ql.Period('6M'))
floatLeg = ql.IborLeg([100], floatSchedule, ql.Euribor6M(), ql.Actual360())

swap = ql.Swap(fixedLeg, floatLeg)

MakeVanillaSwap

ql.MakeVanillaSwap(tenor, index, fixedRate, forwardStart)

Optional params:

  • fixedLegDayCount

  • Nominal

  • receiveFixed,

  • swapType

  • settlementDays

  • effectiveDate

  • terminationDate

  • dateGenerationRule

  • fixedLegTenor

  • fixedLegCalendar

  • fixedLegConvention

  • fixedLegDayCount

  • floatingLegTenor

  • floatingLegCalendar

  • floatingLegConvention

  • floatingLegDayCount

  • floatingLegSpread

  • discountingTermStructure

  • pricingEngine

  • fixedLegTerminationDateConvention

  • fixedLegDateGenRule

  • fixedLegEndOfMonth

  • fixedLegFirstDate

  • fixedLegNextToLastDate,

  • floatingLegTerminationDateConvention

  • floatingLegDateGenRule

  • floatingLegEndOfMonth

  • floatingLegFirstDate

  • floatingLegNextToLastDate

tenor = ql.Period('5y')
index = ql.Euribor6M()
fixedRate = 0.05
forwardStart = ql.Period("2D")

swap = ql.MakeVanillaSwap(tenor, index, fixedRate, forwardStart, Nominal=100)
swap = ql.MakeVanillaSwap(tenor, index, fixedRate, forwardStart, swapType=ql.VanillaSwap.Payer)

Amortizing Swap

calendar = ql.TARGET()
start = ql.Date(17,6,2019)
maturity = calendar.advance(start, ql.Period('2y'))


fixedSchedule = ql.MakeSchedule(start, maturity, ql.Period('1Y'))
fixedLeg = ql.FixedRateLeg(fixedSchedule, ql.Actual360(), [100, 50], [0.01])

floatSchedule = ql.MakeSchedule(start, maturity, ql.Period('6M'))
floatLeg = ql.IborLeg([100, 100, 50, 50], floatSchedule, ql.Euribor6M(), ql.Actual360())

swap = ql.Swap(fixedLeg, floatLeg)

FloatFloatSwap

ql.FloatFloatSwap(ql.VanillaSwap.Payer,
                [notional] * (len(float3m)-1),
                [notional] * (len(float6m)-1),
                float3m,
                index3m,
                ql.Actual360(),
                float6m,
                index6m,
                ql.Actual360(), False, False,
                [1] * (len(float3m)-1),
                [spread] * (len(float3m)-1))

AssetSwap

ql.AssetSwap(payFixed, bond, cleanPrice, index, spread)
ql.AssetSwap(payFixed, bond, cleanPrice, index, spread, schedule, dayCount, bool)
payFixedRate = True
bond = ql.FixedRateBond(2, ql.TARGET(), 100.0, ql.Date(15,12,2019), ql.Date(15,12,2024),
    ql.Period('1Y'), [0.05], ql.ActualActual()
    )
bondCleanPrice = 100
index = ql.Euribor6M()
spread = 0.0
ql.AssetSwap(payFixedRate, bond, bondCleanPrice, index, spread, ql.Schedule(), ql.ActualActual(), True)

OvernightIndexedSwap

ql.OvernightIndexedSwap(swapType, nominal, schedule, fixedRate, fixedDC, overnightIndex)

Or array of nominals

ql.OvernightIndexedSwap(swapType, nominals, schedule, fixedRate, fixedDC, overnightIndex)

Optional params:

  • spread=0.0

  • paymentLag=0

  • paymentAdjustment=ql.Following()

  • paymentCalendar=ql.Calendar()

  • telescopicValueDates=false

Types:

  • ql.OvernightIndexedSwap.Receiver

  • ql.OvernightIndexedSwap.Receiver

swapType = ql.OvernightIndexedSwap.Receiver
nominal = 100
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2021), ql.Period('1Y'), calendar=ql.TARGET())
fixedRate = 0.01
fixedDC = ql.Actual360()
overnightIndex = ql.Eonia()
ois_swap = ql.OvernightIndexedSwap(swapType, nominal, schedule, fixedRate, fixedDC, overnightIndex)

MakeOIS

ql.MakeOIS(swapTenor, overnightIndex, fixedRate)

Optional params:

  • fwdStart=Period(0, Days)

  • receiveFixed=True,

  • swapType=OvernightIndexedSwap.Payer

  • nominal=1.0

  • settlementDays=2

  • effectiveDate=None

  • terminationDate=None

  • dateGenerationRule=DateGeneration.Backward

  • paymentFrequency=Annual

  • paymentAdjustmentConvention=Following

  • paymentLag=0

  • paymentCalendar=None

  • endOfMonth=True

  • fixedLegDayCount=None

  • overnightLegSpread=0.0

  • discountingTermStructure=None

  • telescopicValueDates=False

  • pricingEngine=None

swapTenor = ql.Period('1Y')
overnightIndex = ql.Eonia()
fixedRate = 0.01
ois_swap = ql.MakeOIS(swapTenor, overnightIndex, fixedRate)

NonstandardSwap

ql.NonstandardSwap(swapType, fixedNominal, floatingNominal, fixedSchedule, fixedRate, fixedDayCount, floatingSchedule, iborIndex, gearing, spread, floatDayCount)

Optional params:

  • intermediateCapitalExchange = False

  • finalCapitalExchange = False,

  • paymentConvention = None

swapType = ql.VanillaSwap.Payer
fixedNominal = [100, 100]
floatingNominal  = [100] * 4
fixedSchedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('1Y'))
fixedRate = [0.02] * 2
fixedDayCount = ql.Thirty360()
floatingSchedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Period('6M'))
iborIndex = ql.Euribor6M()
gearing = [1.] * 4
spread = [0.] * 4
floatDayCount = iborIndex.dayCounter()
nonstandardSwap = ql.NonstandardSwap(
    swapType, fixedNominal, floatingNominal,
    fixedSchedule, fixedRate, fixedDayCount,
    floatingSchedule, iborIndex, gearing, spread, floatDayCount)

Swaptions

Exercises

  • ql.EuropeanExercise(start)

  • ql.AmericanExercise(earliestDate, latestDate)

  • ql.BermudanExercise(dates)

Settlement Type/Method

  • ql.Settlement.Cash
    • ql.Settlement.CollateralizedCashPrice

    • ql.Settlement.ParYieldCurve

  • ql.Settlement.Physical
    • ql.Settlement.PhysicalCleared

    • ql.Settlement.PhysicalOTC

Swaption

ql.Swaption(swap, exercise, settlementType=ql.Settlement.Physical, settlementMethod=ql.Settlement.PhysicalOTC)
calendar = ql.TARGET()
today = ql.Date().todaysDate()
exerciseDate = calendar.advance(today, ql.Period('5y'))
exercise = ql.EuropeanExercise(exerciseDate)
swap = ql.MakeVanillaSwap(ql.Period('5y'), ql.Euribor6M(), 0.05, ql.Period('5y'))
swaption = ql.Swaption(swap, exercise)

swaption = ql.Swaption(swap, exercise, ql.Settlement.Cash, ql.Settlement.ParYieldCurve)
swaption = ql.Swaption(swap, exercise, ql.Settlement.Physical, ql.Settlement.PhysicalCleared)

Nonstandard Swaption

FloatFloatSwaption


Caps & Floors

Cap

ql.Cap(floatingLeg, exerciseRates)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(16,6,2022), ql.Period('6M'))
ibor_leg = ql.IborLeg([100], schedule, ql.Euribor6M())
strike = 0.01
cap = ql.Cap(ibor_leg, [strike])

Floor

ql.Floor(floatingLeg, exerciseRates)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(16,6,2022), ql.Period('6M'))
ibor_leg = ql.IborLeg([100], schedule, ql.Euribor6M())
strike = 0.00
floor = ql.Floor(ibor_leg, [strike])

Collar

ql.Collar(floatingLeg, capRates, floorRates)
schedule = ql.MakeSchedule(ql.Date(15,6,2020), ql.Date(16,6,2022), ql.Period('6M'))
ibor_leg = ql.IborLeg([100], schedule, ql.Euribor6M())
capStrike = 0.02
floorStrike = 0.00
collar = ql.Collar(ibor_leg, [capStrike], [floorStrike])