Skip to content

Commit a68720f

Browse files
committed
docs: add exotic option API docs, stubs, and changelog entries
Add API documentation for lookback, cliquet, compound, chooser, Margrabe, forward-start, and quanto option instruments and engines. Update type stubs and changelog.
1 parent c2ce1fa commit a68720f

5 files changed

Lines changed: 533 additions & 2 deletions

File tree

docs/api/instruments.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,190 @@ asian_arith = ql.DiscreteAveragingAsianOption(
645645
asian_arith.setPricingEngine(ql.TurnbullWakemanAsianEngine(process))
646646
```
647647

648+
## Lookback Options
649+
650+
### ContinuousFloatingLookbackOption
651+
652+
```{eval-rst}
653+
.. autoclass:: pyquantlib.ContinuousFloatingLookbackOption
654+
```
655+
656+
Continuous floating-strike lookback option. The strike is determined at expiry as the minimum (call) or maximum (put) of the asset price over the option's life.
657+
658+
```python
659+
payoff = ql.FloatingTypePayoff(ql.Call)
660+
exercise = ql.EuropeanExercise(expiry)
661+
option = ql.ContinuousFloatingLookbackOption(100.0, payoff, exercise)
662+
```
663+
664+
### ContinuousFixedLookbackOption
665+
666+
```{eval-rst}
667+
.. autoclass:: pyquantlib.ContinuousFixedLookbackOption
668+
```
669+
670+
Continuous fixed-strike lookback option. The payoff is based on the maximum (call) or minimum (put) of the asset price over the option's life.
671+
672+
```python
673+
payoff = ql.PlainVanillaPayoff(ql.Call, 100.0)
674+
exercise = ql.EuropeanExercise(expiry)
675+
option = ql.ContinuousFixedLookbackOption(100.0, payoff, exercise)
676+
```
677+
678+
### ContinuousPartialFloatingLookbackOption
679+
680+
```{eval-rst}
681+
.. autoclass:: pyquantlib.ContinuousPartialFloatingLookbackOption
682+
```
683+
684+
Partial floating-strike lookback option with a lookback period ending before expiry.
685+
686+
```python
687+
option = ql.ContinuousPartialFloatingLookbackOption(
688+
100.0, 1.0, lookback_end, payoff, exercise,
689+
)
690+
```
691+
692+
### ContinuousPartialFixedLookbackOption
693+
694+
```{eval-rst}
695+
.. autoclass:: pyquantlib.ContinuousPartialFixedLookbackOption
696+
```
697+
698+
Partial fixed-strike lookback option with a lookback period starting after inception.
699+
700+
```python
701+
option = ql.ContinuousPartialFixedLookbackOption(
702+
lookback_start, payoff, exercise,
703+
)
704+
```
705+
706+
## Cliquet Options
707+
708+
### CliquetOption
709+
710+
```{eval-rst}
711+
.. autoclass:: pyquantlib.CliquetOption
712+
```
713+
714+
Cliquet (ratchet) option with periodic resets. The strike resets at each reset date to the then-current spot price.
715+
716+
```python
717+
payoff = ql.PercentageStrikePayoff(ql.Call, 1.0)
718+
exercise = ql.EuropeanExercise(expiry)
719+
reset_dates = [today + ql.Period(f"{i}M") for i in range(3, 12, 3)]
720+
option = ql.CliquetOption(payoff, exercise, reset_dates)
721+
```
722+
723+
## Compound Options
724+
725+
### CompoundOption
726+
727+
```{eval-rst}
728+
.. autoclass:: pyquantlib.CompoundOption
729+
```
730+
731+
Compound option (option on an option). The mother option gives the right to buy/sell the daughter option.
732+
733+
```python
734+
mother_payoff = ql.PlainVanillaPayoff(ql.Call, 5.0)
735+
mother_exercise = ql.EuropeanExercise(today + ql.Period("6M"))
736+
daughter_payoff = ql.PlainVanillaPayoff(ql.Call, 100.0)
737+
daughter_exercise = ql.EuropeanExercise(expiry)
738+
option = ql.CompoundOption(
739+
mother_payoff, mother_exercise, daughter_payoff, daughter_exercise,
740+
)
741+
```
742+
743+
## Chooser Options
744+
745+
### SimpleChooserOption
746+
747+
```{eval-rst}
748+
.. autoclass:: pyquantlib.SimpleChooserOption
749+
```
750+
751+
Simple chooser option. The holder chooses at a future date whether the option is a call or put.
752+
753+
```python
754+
option = ql.SimpleChooserOption(choosing_date, 100.0, exercise)
755+
```
756+
757+
### ComplexChooserOption
758+
759+
```{eval-rst}
760+
.. autoclass:: pyquantlib.ComplexChooserOption
761+
```
762+
763+
Complex chooser option with different strikes and exercise dates for the call and put legs.
764+
765+
```python
766+
option = ql.ComplexChooserOption(
767+
choosing_date, call_strike, put_strike, call_exercise, put_exercise,
768+
)
769+
```
770+
771+
## Margrabe Options
772+
773+
### MargrabeOption
774+
775+
```{eval-rst}
776+
.. autoclass:: pyquantlib.MargrabeOption
777+
```
778+
779+
Margrabe option (exchange option): the right to exchange one asset for another.
780+
781+
```python
782+
option = ql.MargrabeOption(1, 1, exercise)
783+
option.setPricingEngine(engine)
784+
print(option.delta1(), option.delta2())
785+
print(option.gamma1(), option.gamma2())
786+
```
787+
788+
## Forward-Start Options
789+
790+
### ForwardVanillaOption
791+
792+
```{eval-rst}
793+
.. autoclass:: pyquantlib.ForwardVanillaOption
794+
```
795+
796+
Forward-start vanilla option. The strike is set at a future reset date based on a moneyness ratio.
797+
798+
```python
799+
option = ql.ForwardVanillaOption(1.0, reset_date, payoff, exercise)
800+
```
801+
802+
## Quanto Options
803+
804+
### QuantoVanillaOption
805+
806+
```{eval-rst}
807+
.. autoclass:: pyquantlib.QuantoVanillaOption
808+
```
809+
810+
Quanto vanilla option with currency adjustment. Provides quanto-specific greeks: `qvega()`, `qrho()`, `qlambda()`.
811+
812+
```python
813+
option = ql.QuantoVanillaOption(payoff, exercise)
814+
option.setPricingEngine(engine)
815+
print(option.qvega(), option.qrho(), option.qlambda())
816+
```
817+
648818
## Payoffs
649819

820+
### FloatingTypePayoff
821+
822+
```{eval-rst}
823+
.. autoclass:: pyquantlib.FloatingTypePayoff
824+
```
825+
826+
Floating-strike payoff for lookback options.
827+
828+
```python
829+
payoff = ql.FloatingTypePayoff(ql.Call)
830+
```
831+
650832
### PlainVanillaPayoff
651833

652834
```{eval-rst}

docs/api/pricingengines.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,131 @@ engine = ql.MCDiscreteArithmeticAPEngine(
370370
)
371371
```
372372

373+
## Lookback Engines
374+
375+
### AnalyticContinuousFloatingLookbackEngine
376+
377+
```{eval-rst}
378+
.. autoclass:: pyquantlib.AnalyticContinuousFloatingLookbackEngine
379+
```
380+
381+
### AnalyticContinuousFixedLookbackEngine
382+
383+
```{eval-rst}
384+
.. autoclass:: pyquantlib.AnalyticContinuousFixedLookbackEngine
385+
```
386+
387+
### AnalyticContinuousPartialFloatingLookbackEngine
388+
389+
```{eval-rst}
390+
.. autoclass:: pyquantlib.AnalyticContinuousPartialFloatingLookbackEngine
391+
```
392+
393+
### AnalyticContinuousPartialFixedLookbackEngine
394+
395+
```{eval-rst}
396+
.. autoclass:: pyquantlib.AnalyticContinuousPartialFixedLookbackEngine
397+
```
398+
399+
```python
400+
payoff = ql.FloatingTypePayoff(ql.Call)
401+
exercise = ql.EuropeanExercise(expiry)
402+
option = ql.ContinuousFloatingLookbackOption(100.0, payoff, exercise)
403+
option.setPricingEngine(ql.AnalyticContinuousFloatingLookbackEngine(process))
404+
print(option.NPV())
405+
```
406+
407+
## Cliquet Engines
408+
409+
### AnalyticCliquetEngine
410+
411+
```{eval-rst}
412+
.. autoclass:: pyquantlib.AnalyticCliquetEngine
413+
```
414+
415+
```python
416+
engine = ql.AnalyticCliquetEngine(process)
417+
cliquet.setPricingEngine(engine)
418+
print(cliquet.NPV())
419+
```
420+
421+
## Exotic Engines
422+
423+
### AnalyticCompoundOptionEngine
424+
425+
```{eval-rst}
426+
.. autoclass:: pyquantlib.AnalyticCompoundOptionEngine
427+
```
428+
429+
### AnalyticSimpleChooserEngine
430+
431+
```{eval-rst}
432+
.. autoclass:: pyquantlib.AnalyticSimpleChooserEngine
433+
```
434+
435+
### AnalyticComplexChooserEngine
436+
437+
```{eval-rst}
438+
.. autoclass:: pyquantlib.AnalyticComplexChooserEngine
439+
```
440+
441+
### AnalyticEuropeanMargrabeEngine
442+
443+
```{eval-rst}
444+
.. autoclass:: pyquantlib.AnalyticEuropeanMargrabeEngine
445+
```
446+
447+
Takes two Black-Scholes-Merton processes and a correlation parameter.
448+
449+
```python
450+
engine = ql.AnalyticEuropeanMargrabeEngine(process1, process2, 0.5)
451+
option.setPricingEngine(engine)
452+
```
453+
454+
### AnalyticAmericanMargrabeEngine
455+
456+
```{eval-rst}
457+
.. autoclass:: pyquantlib.AnalyticAmericanMargrabeEngine
458+
```
459+
460+
## Forward-Start Engines
461+
462+
### ForwardEuropeanEngine
463+
464+
```{eval-rst}
465+
.. autoclass:: pyquantlib.ForwardEuropeanEngine
466+
```
467+
468+
### ForwardPerformanceEuropeanEngine
469+
470+
```{eval-rst}
471+
.. autoclass:: pyquantlib.ForwardPerformanceEuropeanEngine
472+
```
473+
474+
```python
475+
option = ql.ForwardVanillaOption(1.0, reset_date, payoff, exercise)
476+
option.setPricingEngine(ql.ForwardEuropeanEngine(process))
477+
print(option.NPV())
478+
```
479+
480+
## Quanto Engines
481+
482+
### QuantoVanillaEngine
483+
484+
```{eval-rst}
485+
.. autoclass:: pyquantlib.QuantoVanillaEngine
486+
```
487+
488+
Quanto European option engine (currency-adjusted Black-Scholes). Accepts explicit Handle arguments or raw objects (hidden handles).
489+
490+
```python
491+
engine = ql.QuantoVanillaEngine(
492+
process, foreign_rate, fx_vol, correlation,
493+
)
494+
option.setPricingEngine(engine)
495+
print(option.NPV(), option.qvega(), option.qrho(), option.qlambda())
496+
```
497+
373498
## Cap/Floor Engines
374499

375500
### BlackCapFloorEngine

docs/changelog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
#### Core
1717
- `Forward` ABC for forward contracts (in `pyquantlib.base`) with inspectors (`settlementDate`, `forwardValue`, `spotValue`, `spotIncome`, `impliedYield`)
1818
- `ForwardTypePayoff` for long/short forward payoffs
19+
- `FloatingTypePayoff` for floating-strike lookback options
1920

2021
#### Indexes
2122
- `EquityIndex` with minimal, full Handle, and hidden-handle constructors
@@ -30,6 +31,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3031
- `SoftCallability` with trigger level for soft-call provisions
3132
- `ConvertibleBond` base class with `conversionRatio()` and `callability()`
3233
- `ConvertibleZeroCouponBond`, `ConvertibleFixedCouponBond`, `ConvertibleFloatingRateBond`
34+
- **Lookback options**: `ContinuousFloatingLookbackOption`, `ContinuousFixedLookbackOption`, `ContinuousPartialFloatingLookbackOption`, `ContinuousPartialFixedLookbackOption`
35+
- `CliquetOption` cliquet (ratchet) option with periodic resets
36+
- `CompoundOption` option on an option (mother/daughter)
37+
- `SimpleChooserOption` and `ComplexChooserOption` chooser options
38+
- `MargrabeOption` exchange option with `delta1()`, `delta2()`, `gamma1()`, `gamma2()`
39+
- `ForwardVanillaOption` forward-start vanilla option
40+
- `QuantoVanillaOption` quanto option with `qvega()`, `qrho()`, `qlambda()`
3341

3442
#### Cash Flows
3543
- `Dividend` ABC (in `pyquantlib.base`) for custom dividend implementations
@@ -39,6 +47,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3947

4048
#### Pricing Engines
4149
- `BinomialConvertibleEngine` Tsiveriotis-Fernandes lattice engine for convertible bonds (7 tree types: jr, crr, eqp, trigeorgis, tian, lr, joshi)
50+
- **Lookback engines**: `AnalyticContinuousFloatingLookbackEngine`, `AnalyticContinuousFixedLookbackEngine`, `AnalyticContinuousPartialFloatingLookbackEngine`, `AnalyticContinuousPartialFixedLookbackEngine`
51+
- `AnalyticCliquetEngine` analytic cliquet option engine
52+
- `AnalyticCompoundOptionEngine` analytic compound option engine
53+
- `AnalyticSimpleChooserEngine` and `AnalyticComplexChooserEngine` chooser option engines
54+
- `AnalyticEuropeanMargrabeEngine` and `AnalyticAmericanMargrabeEngine` exchange option engines
55+
- `ForwardEuropeanEngine` and `ForwardPerformanceEuropeanEngine` forward-start option engines
56+
- `QuantoVanillaEngine` quanto European option engine with hidden handle constructors
4257

4358
#### Experimental
4459
- `CallableBond` ABC (in `pyquantlib.base`) with OAS, effective duration/convexity, implied volatility

0 commit comments

Comments
 (0)