Cox-Ross-Rubinstein lattice pricing for vanilla European and American options.
The named consumer is the zen_quant operator, for comparing early-exercise
values with the European Black-Scholes-Merton prices in
ZenQuant.Options.Pricing.
Supported contract
price/4 supports :call and :put payoffs with either :european exercise
at expiry or :american exercise at every lattice step. Rates are annualized
and continuously compounded. Dividends or carry are represented by a
continuous annual :dividend_yield; discrete cash dividends are not modeled.
Time is a caller-supplied year fraction, with no calendar convention imposed.
The caller controls convergence through the step count, which defaults to
- The implementation uses O(steps) memory and O(steps²) time. At expiry it returns intrinsic value. Zero volatility is evaluated as a deterministic path, avoiding a degenerate up/down tree.
The input map uses the same fields and units as ZenQuant.Options.Pricing:
positive :spot and :strike, non-negative :time_to_expiry_years and
:volatility, and numeric :risk_free_rate and :dividend_yield.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
price | 4 | Price a vanilla European or American option with a CRR lattice. | option_type: value, exercise: value, inputs: value, steps: value |
Summary
Types
Lattice pricing failure reason.
Exercise convention supported by the lattice.
CRR input map using continuous annual rates and a caller-supplied year fraction.
Vanilla option side.
Functions
Price a vanilla European or American option with a CRR lattice.
Types
@type error_reason() :: {:invalid_option_type, term()} | {:invalid_exercise, term()} | {:missing_input, atom()} | {:invalid_input, atom()} | {:invalid_lattice, map()}
Lattice pricing failure reason.
@type exercise() :: :european | :american
Exercise convention supported by the lattice.
@type inputs() :: %{ spot: number(), strike: number(), time_to_expiry_years: number(), risk_free_rate: number(), dividend_yield: number(), volatility: number() }
CRR input map using continuous annual rates and a caller-supplied year fraction.
@type option_type() :: :call | :put
Vanilla option side.
Functions
@spec price( option_type() | term(), exercise() | term(), inputs() | term(), pos_integer() | term() ) :: {:ok, float()} | {:error, error_reason()}
Price a vanilla European or American option with a CRR lattice.
Parameters
option_type-:callor:put(value)exercise-:europeanor:american(value)inputs- Map with positive :spot/:strike, time in years, continuous annual rates/yield, and annual decimal volatility (value)steps- Positive CRR step count controlling convergence and runtime (default:500, value)
Returns
{:ok, price} in spot currency units or {:error, reason} (result_tuple)
Example
{:ok, 9.223118455216966}Errors
:invalid_option_type- Option type is not :call or :put:invalid_exercise- Exercise convention is not :european or :american:missing_input- A required map field is absent:invalid_input- A field or step count has an unsupported type or domain:invalid_lattice- Inputs imply a risk-neutral probability outside zero to one
# descripex:contract
%{
params: %{
option_type: %{description: "`:call` or `:put`", kind: :value},
exercise: %{description: "`:european` or `:american`", kind: :value},
inputs: %{
description: "Map with positive :spot/:strike, time in years, continuous annual rates/yield, and annual decimal volatility",
kind: :value
},
steps: %{
default: 500,
description: "Positive CRR step count controlling convergence and runtime",
kind: :value
}
},
errors: [
invalid_option_type: "Option type is not :call or :put",
invalid_exercise: "Exercise convention is not :european or :american",
missing_input: "A required map field is absent",
invalid_input: "A field or step count has an unsupported type or domain",
invalid_lattice: "Inputs imply a risk-neutral probability outside zero to one"
],
returns: %{
type: :result_tuple,
description: "`{:ok, price}` in spot currency units or `{:error, reason}`"
},
returns_example: {:ok, 9.223118455216966}
}