Loan contracts, funding and fair rates¶
A loan contract contains principal, dates, coupon rules and repayment structure.
A trade adds position direction and trade date. The pricer selects discounting,
refinancing assumptions and fair-rate amortization behavior. This follows the
Rust library’s separation of Loan, LoanTrade and LoanPricer.
Read the constructor arguments¶
All rates and spreads are annual decimals: 0.05 means 5%, 0.01 means
100 basis points. Principal uses currency units. A blank optional argument uses
the default below; zero is a supplied value. In Excel, type the function and
press Ctrl+A to open Function Arguments, or enter
=QS.HELP("QS.INSTRUMENT.LOAN") for the same parameter help in cells.
Argument |
Required / blank default |
Meaning |
|---|---|---|
|
Required |
Your object name, e.g. |
|
Required |
Prepared market context used to construct dates and initial amortization. |
|
Required |
Advance/accrual start, as ISO text |
|
Required |
Final accrual date, after start; payment-date adjustment is a separate setting. |
|
Required |
Principal/payment currency, e.g. |
|
Required |
Positive original principal, e.g. |
|
Required |
Fixed coupon if |
|
Fixed coupon |
Floating projection index, e.g. |
|
|
French: level initial instalments. Bullet: interest with all principal at maturity. Balloon: amortization leaving a final fraction of original principal. |
|
|
Payment/accrual frequency, e.g. Monthly, Quarterly, Semiannual or Annual. Index resets and observation tenor are separate settings. |
|
Index convention for floating coupons; |
Optional coupon accrual basis for interest and initial principal amortization. |
|
No optional overrides |
Handle returned by |
|
No segment schedule |
Payment count for each successive coupon segment; |
|
Use scalar |
Annual coupon/spread for each segment. Supplied segments must cover the loan. |
|
All segments fixed |
Projection index per segment; a blank entry means fixed. An omitted array
makes every segment fixed even if scalar |
|
No dated CPR model |
Strictly increasing ISO observation dates, aligned with |
|
No dated CPR model |
Annual conditional prepayment fractions in [0,1], e.g. |
Arrays are independent row, column or spill ranges with equal entry counts within each group. Do not include headers. The final coupon count can be blank; other interior blanks are retained, not removed. Coupon arrays cannot be combined with introductory terms or a floor/cap in Loan Settings.
Choose optional settings¶
QS.LOAN.SETTINGS(name, ...) returns a settings handle. Its remaining arguments
are optional, in the order below. Leave unused argument positions empty or use
cell references so the formula remains readable.
Argument |
Blank default |
Meaning / when to supply |
|---|---|---|
|
Unset |
Residual fraction in [0,1] of original principal, e.g. |
|
Initial coupon built by the instrument constructor |
Optional annual all-in rate used to build principal instalments, e.g. |
|
No borrower default |
Borrower survival curve, e.g. |
|
|
Fraction of opening principal recovered on default; [0,1]. |
|
Index metadata |
Floating reset frequency; daily indices use payment frequency by default. Each reset must fall on a payment accrual boundary. |
|
|
Nonnegative whole business days backwards from reset to fixing. |
|
Index metadata |
Positive observation period, e.g. |
|
|
Payment/fixing calendar, e.g. |
|
|
Payment adjustment: Following, ModifiedFollowing, Preceding, ModifiedPreceding or Unadjusted. |
|
No bounds |
Annual decimal bounds on the all-in floating coupon (index plus spread),
e.g. |
|
No introduction |
Positive number of initial fixed payments; must leave at least one floating
payment. Supply |
|
No introduction |
Annual fixed coupon during the introduction; afterwards scalar |
|
No prepayment |
Constant annual prepayment fraction, [0,1], e.g. |
|
No refinancing model |
Base annual CPR, [0,1]. Supply all three refinancing fields together and
a benchmark index on |
|
No refinancing model |
Nonnegative CPR increase per unit of positive coupon-minus-benchmark
incentive; |
|
No refinancing model |
Annual CPR ceiling, [0,1], at least |
With no prepayment inputs, there is no prepayment model. Annual CPR is converted
to an interval probability as 1 - (1 - CPR)^year_fraction; it is not a
per-payment percentage. Dated CPRs use the latest observation at or before the
interval start, zero before the first date and the last rate thereafter.
Build a market context¶
For illustrative continuous zero rates, put ordered pillars in A10:A14 and rates in F10:F14. A pillar can be ISO text or a tenor such as 0D or 10Y.
B2 =QS.CONTEXT.CREATE("eur","2026-02-24","EUR","ESTR")
B3 =QS.CONTEXT.ADD.ZERO.CURVE(B2,"ESTR",A10:A14,F10:F14,"Actual360","Linear",TRUE,"Continuous","Annual")
B4 =QS.CONTEXT.ADD.ZERO.CURVE(B2,"EURIBOR12m",A10:A14,J10:J14,"Actual360","Linear",TRUE,"Continuous","Annual")
H2 =B2
ESTR discounts payments under the illustrated policy; EURIBOR12m projects the floating coupon. Use appropriate calibrated inputs for production work. The independent field arrays can have different orientations and need no table headers. Each curve addition references B2, and H2 consumes the complete array.
Create fixed and floating contracts¶
D2 =QS.LOAN.SETTINGS("balloon.options",0.25)
D3 =QS.INSTRUMENT.LOAN("balloon",B2,"2026-02-24","2031-02-24","EUR",10000,0.05,,"Balloon","Monthly","Actual365",D2)
D4 =QS.TRADE.CREATE("receipt",B2,D3,"2026-02-24","Receive")
D5 =QS.LOAN.PRICER("loan.pricer","EUR","ESTR")
D6 =QS.EVALUATE(H2,D4,"Value",D5)
D7 =QS.EVALUATE(H2,D4,"FairRate(0)",D5)
The rate is an annual decimal fixed coupon when market_index is blank and a floating spread otherwise. French, Bullet and Balloon repayment are supported. Balloon repayment requires the residual principal fraction in Loan Settings. A floating-first French/Balloon schedule requires a separate amortization rate; projection and contractual amortization assumptions are distinct.
A minimal fixed French loan needs only the six required arguments. A floating
French loan supplies an all-in amortization rate through settings; its scalar
rate is the spread. These contracts can be passed directly to QS.EVALUATE
for Receive at the context date, or wrapped in QS.TRADE.CREATE as above.
F2 =QS.INSTRUMENT.LOAN("fixed",B2,"2026-02-24","2031-02-24","EUR",10000,0.05)
F3 =QS.LOAN.SETTINGS("floating.options",,0.05)
F4 =QS.INSTRUMENT.LOAN("floating",B2,"2026-02-24","2031-02-24","EUR",10000,0.01,"EURIBOR12m","French","Monthly","Actual365",F3)
For a stepped fixed coupon, put 12 and a blank in A40:A41, and 0.03 and
0.05 in F40:F41. The first 12 monthly payments use 3%; the remainder use 5%:
F5 =QS.INSTRUMENT.LOAN("stepped",B2,"2026-02-24","2031-02-24","EUR",10000,0.03,,,,,,A40:A41,F40:F41)
To make the second segment floating, put a blank and EURIBOR12m in J40:J41
and pass that range as coupon_indices. Its 0.05 would then mean a 500 bp
spread; change it to the intended spread, for example 0.01 for 100 bp.
QS.LOAN.SETTINGS exposes named optional parameters in IntelliSense. Omitted
settings retain native defaults. These include balloon fraction, credit index,
recovery, fixing conventions, calendar, coupon bounds, introductory fixed terms
and prepayment assumptions. The loan constructor accepts the settings handle,
then independent coupon-period, rate/spread and index arrays, followed by
independent prepayment-date and annual-CPR arrays. Only the final coupon segment
may omit its period count to fill the remaining maturity.
Funding and borrower credit¶
Funding is an ordinary curve chosen by a discount policy. For a treasury spread, construct its curve in the same root, then compose a FUNDING index:
B6 =QS.CONTEXT.ADD.ZERO.CURVE(B2,"FUNDINGSPREAD",A10:A14,N10:N14,"Actual360","Linear",TRUE,"Continuous","Annual")
B7 =QS.CONTEXT.ADD.COMPOSITE.CURVE(B2,"FUNDING","EURIBOR12m","FUNDINGSPREAD")
B8 =B2
D8 =QS.LOAN.PRICER("funded.loan","EUR","FUNDING")
D9 =QS.EVALUATE(B8,D4,"Value",D8)
Keep B3:B7 exclusively for addition handles or blanks. Prepared contexts belong outside the contribution array. The full loan example separates those blocks. A composite multiplies base and spread discount factors. Contract settings do not select funding curves.
For borrower credit use an independent CDS identifier and spread array:
=QS.CONTEXT.ADD.CREDIT.CURVE(B2,"Credit:BORROWER","EUR","ESTR",0.4,A30:A36,F30:F36)
=QS.DISCOUNT.POLICY.FIXED.INCOME("policy","EUR","FUNDING")
Attach the same credit index and compatible recovery assumption through Loan Settings. Credit and prepayment can affect the future receipt schedule. Preserve those model-dependent cashflows when comparing pricing and risk results.
Prepayment and fair-rate interpretation¶
Constant annual CPR, dated CPR observations and refinancing-based prepayment models are supported through their named settings. Refinancing settings use an explicit benchmark curve on LoanPricer. Incompatible prepayment specifications fail validation instead of being silently combined.
A loan FairRate(index) solves earlier coupon segments in order, repays remaining capital at each prefix end, locks each solved coupon/spread and then extends to the requested segment. One evaluation returns one scalar fair_rate. Use separate requests for each segment. Coupon bounds remain unsupported for this solve. The pricer’s rebuild_amortization option controls whether the contractual amortization schedule is rebuilt during solving.
=QS.LOAN.PRICER("refinancing","EUR","FUNDING","EURIBOR12m",TRUE)
=QS.EVALUATE.RESULTS(H2,D4,{"Value","Cashflows","Sensitivities"},D5)
Value is signed future receipt PV under the native loan conventions and excludes the original principal advance. Cashflow tables contain signed undiscounted payments; loan legs distinguish scheduled receipts, prepayment and recovery. Sensitivities are raw per-unit derivatives. For decimal rates, multiply by 0.0001 for an approximate +1 bp change.
The editable loan study includes fixed, floating, balloon, stepped, mixed, credit, bounded and prepayment cases. A selector drives its cashflow and risk views. The context study demonstrates separate row/column inputs and historical batch pricing; see Risk, portfolios and historical snapshots for snapshot selection and batch evaluation.