Marimo is a reactive notebook system in Python. Here are some thoughts on it:

  1. Reactivity is implemented by re-writing Python expressions in the cells by means of (it appears) static analysis. The on-disk format is the rewritten expression.
  2. The rewrite makes all inputs and outputs explicit parameters/return values. This rewrite turns global variables into function parameters/returns
  3. This work well for the (simple) cases tested so far. Not sure it is a that big advantage for an experienced Python developer but perhaps it is for newcomers.
  4. A reactive notebook system “Pluto” has been available for the Julia ecosystem for some time.
  5. There is a nice two-dimensional notebook layout in Marimo
  6. The on-disk format is extremely easy to read, and automatic watch functions means editing outside of Marimo works very well
  7. The usual IDE assists seem to work well in the notebook
  8. And in the time it has taken me to put together these notes and some experiments I seen they’ve been bought by Corewave: https://marimo.io/blog/joining-coreweave !

And here is a very quick illustration of the two-dimensional layout:

example

Here is a quick conversion of QuantLib American Option example:

American options

Copyright (©) 2004, 2005, 2006, 2007 StatPro Italia srl Copyright (©) 2026 BN Algorithms Ltd

Adapted from the QuantLib-SWIG example

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.

import QuantLib as ql
import pandas as pd
import qlutils

Global parameters

todaysDate = mo.ui.date()
expiryDate = mo.ui.date()
K = mo.ui.number(1, 100, step=0.1)    
mo.vstack([ mo.md(f"Today: {todaysDate}"),
            mo.md(f"Expiry: {expiryDate}"),
            mo.md(f"Strike: {K}"),
           ])

Option construction

ql.Settings.instance().evaluationDate = qlutils.qlDate(todaysDate.value)
exercise = ql.AmericanExercise(qlutils.qlDate(todaysDate.value),
                               qlutils.qlDate(expiryDate.value))
payoff = ql.PlainVanillaPayoff(ql.Option.Put, K.value)
option = ql.VanillaOption(payoff, exercise)

Market data

underlying = ql.SimpleQuote(36.0)
dividendYield = ql.FlatForward(qlutils.qlDate(todaysDate.value), 0.00, ql.Actual365Fixed())
volatility = ql.BlackConstantVol(qlutils.qlDate(todaysDate.value), ql.TARGET(), 0.20, ql.Actual365Fixed())
riskFreeRate = ql.FlatForward(qlutils.qlDate(todaysDate.value), 0.06, ql.Actual365Fixed())
process = ql.BlackScholesMertonProcess(
    ql.QuoteHandle(underlying),
    ql.YieldTermStructureHandle(dividendYield),
    ql.YieldTermStructureHandle(riskFreeRate),
    ql.BlackVolTermStructureHandle(volatility),
)

Pricing

We’ll collect tuples of method name, option value, and estimated error from the analytic formula.

Analytic approximations

option.setPricingEngine(ql.BaroneAdesiWhaleyApproximationEngine(process))
BaroneAdesiNPV = option.NPV()
mo.md(f'**Barone-Adesi-Whaley** : {BaroneAdesiNPV:.4f}')
option.setPricingEngine(ql.BjerksundStenslandApproximationEngine(process))
mo.md(f'**Bjerksund-Stensland** : {option.NPV():.4f}')

Finite-difference method

timeSteps = 801
gridPoints = 800
option.setPricingEngine(ql.FdBlackScholesVanillaEngine(process, timeSteps, gridPoints))
mo.md(f'**finite differences** : {option.NPV():.4f}')

Li, M. QD+ American engine

option.setPricingEngine(ql.QdPlusAmericanEngine(process))
mo.md(f'**QD+** : {option.NPV():.4f}')

Leif Andersen, Mark Lake and Dimitri Offengenden high performance American engine

option.setPricingEngine(
    ql.QdFpAmericanEngine(process, ql.QdFpAmericanEngine.accurateScheme())
)
mo.md(f'**QD+ fixed point** : {option.NPV():.4f}')

Binomial method

timeSteps_1 = 801
r =[]
for tree in ['JR', 'CRR', 'EQP', 'Trigeorgis', 'Tian', 'LR', 'Joshi4']:
    option.setPricingEngine(ql.BinomialVanillaEngine(process, tree, timeSteps_1))
    r.append(     mo.md(f'**Binomial ({tree}) differences** : {option.NPV():.4f}'))
mo.vstack(r)
import marimo as mo

Produces following app:

example