Your first Nautilus program
This chapter walks through a complete program that uses Nautilus to compute a Black-Scholes option price.
The program
Section titled “The program”Create a file called src/my_first.ch in your project:
module Nautilus.ExampleFirstProgramimport Nautilus.Distributions (normal_cdf)export (main)def black_scholes_call(spot: f32, strike: f32, rate: f32, vol: f32, t_years: f32) -> f32 = { ln_ratio = log(div(spot, strike)) half_vol_sq = mul(cast(0.5, f32), mul(vol, vol)) d1_num = add(ln_ratio, mul(add(rate, half_vol_sq), t_years)) vol_sqrt_t = mul(vol, sqrt(t_years)) d1 = div(d1_num, vol_sqrt_t) d2 = sub(d1, vol_sqrt_t) zero = cast(0.0, f32) one = cast(1.0, f32) nd1 = normal_cdf(d1, zero, one) nd2 = normal_cdf(d2, zero, one) neg_rt = neg(mul(rate, t_years)) discount = exp(neg_rt) sub(mul(spot, nd1), mul(mul(strike, discount), nd2))}def main() -> f32 = { spot = cast(100.0, f32) strike = cast(100.0, f32) rate = cast(0.05, f32) vol = cast(0.2, f32) t_years = cast(1.0, f32) black_scholes_call(spot, strike, rate, vol, t_years)}What this does
Section titled “What this does”The program computes the Black-Scholes call option price for:
- Spot price: 100
- Strike price: 100 (at-the-money)
- Risk-free rate: 5%
- Volatility: 20%
- Time to expiry: 1 year
It imports normal_cdf from Nautilus.Distributions to evaluate the
cumulative normal distribution, which is the core of the Black-Scholes
formula.
Type-check it
Section titled “Type-check it”chelis check src/my_first.chYou should see "score": 1 with zero errors.
Build and run it
Section titled “Build and run it”chelis build src/my_first.ch -o /tmp/my_first_outThis generates C code in /tmp/my_first_out/. The expected result is
approximately 10.45 (the BS call price for ATM, 1yr, 5% rate, 20% vol).
Key things to notice
Section titled “Key things to notice”-
Imports are explicit. You import exactly the functions you need from each Nautilus module. No wildcard imports.
-
Everything is f32. Numeric literals must be wrapped in
cast(value, f32). This is Chelis's explicit-precision policy. -
Math uses named functions.
add(a, b)nota + b,mul(a, b)nota * b,log(x)notmath.log(x). Chelis has no operator overloading. -
normal_cdftakes three arguments.(x, mean, std), not just(x). For the standard normal, pass(x, 0.0, 1.0). -
AD is free. To compute delta (dPrice/dSpot), wrap the call in
grad:grad(fn (s: f32) -> black_scholes_call(s, strike, rate, vol, t))(spot).