quantitative finance in javascript

  1. introduction
  2. get started
  3. how to use
  4. release note
  5. api document
  6. test suite & example
  7. credit
  8. resource

introduction

quantlib.js aims to be a COMPLETE re-implementation of C++ QuantLib in javascript language, emscripten is NOT used. it can be used in web browser or node.js environment.

get started

  1. open https://quantlib.js.org with morden web browser, like chrome, firefox, etc...

  2. select a spec or example from menu. spec source will be displayed on left panel, spec will be run with jasmine by your web browser, and test result will be displayed on right panel

usage

load from cdn

install from npm

npm i @quantlib/ql

use in web page

ql.mjs is ESM format, when using in html script tag, make sure to have script type set to "module"

<script type="module">

import { Actual360, AnalyticEuropeanEngine, BlackConstantVol, BlackScholesProcess, DateExt, EuropeanExercise, EuropeanOption, FlatForward, Handle, Option, PlainVanillaPayoff, Settings, SimpleQuote, TARGET } from 'https://cdn.jsdelivr.net/npm/@quantlib/ql@latest/ql.mjs';

const today = DateExt.UTC('7,March,2014');
Settings.evaluationDate.set(today);

const payoff = new PlainVanillaPayoff(Option.Type.Call, 100.0);
const exercise = new EuropeanExercise(DateExt.UTC('7,June,2014'));
const option = new EuropeanOption(payoff, exercise);

const u = new SimpleQuote(100.0);
const r = new SimpleQuote(0.01);
const s = new SimpleQuote(0.2);

const riskFreeCurve = new FlatForward().ffInit3(0, new TARGET(), new Handle(r), new Actual360());
const volatility = new BlackConstantVol().bcvInit4(0, new TARGET(), new Handle(s), new Actual360());

const process = new BlackScholesProcess(new Handle(u), new Handle(riskFreeCurve), new Handle(volatility));

const engine = new AnalyticEuropeanEngine().init1(process);
option.setPricingEngine(engine);

const npv = option.NPV();
console.log(`NPV = ${npv}`);  // 4.155543462156206

</script>

use in node.js

quantlib.js works in node.js environment. after installing with npm, pass --experimental-modules to node to use ESM javascript file

node --experimental-modules test.mjs

in test.mjs

import { Actual360, AnalyticEuropeanEngine, BlackConstantVol, BlackScholesProcess, DateExt, EuropeanExercise, EuropeanOption, FlatForward, Handle, Option, PlainVanillaPayoff, Settings, SimpleQuote, TARGET } from '@quantlib/ql';

const today = DateExt.UTC('7,March,2014');
Settings.evaluationDate.set(today);

const payoff = new PlainVanillaPayoff(Option.Type.Call, 100.0);
const exercise = new EuropeanExercise(DateExt.UTC('7,June,2014'));
const option = new EuropeanOption(payoff, exercise);

const u = new SimpleQuote(100.0);
const r = new SimpleQuote(0.01);
const s = new SimpleQuote(0.2);

const riskFreeCurve = new FlatForward().ffInit3(0, new TARGET(), new Handle(r), new Actual360());
const volatility = new BlackConstantVol().bcvInit4(0, new TARGET(), new Handle(s), new Actual360());

const process = new BlackScholesProcess(new Handle(u), new Handle(riskFreeCurve), new Handle(volatility));

const engine = new AnalyticEuropeanEngine().init1(process);
option.setPricingEngine(engine);

const npv = option.NPV();
console.log(`NPV = ${npv}`);  // 4.155543462156206

typescript

ql.d.ts is published along with ql.mjs

write code in typescript, then compile with tsc or run with ts-node

in test.ts

import {Actual360, AnalyticEuropeanEngine, BlackConstantVol, BlackScholesProcess, BlackVolTermStructure, DateExt, EuropeanExercise, EuropeanOption, Exercise, FlatForward, GeneralizedBlackScholesProcess, Handle, Option, PlainVanillaPayoff, PricingEngine, Quote, Real, Settings, SimpleQuote, StrikedTypePayoff, TARGET, YieldTermStructure} from '@quantlib/ql';

const today: Date = DateExt.UTC('7,March,2014');
Settings.evaluationDate.set(today);

const payoff: StrikedTypePayoff =
    new PlainVanillaPayoff(Option.Type.Call, 100.0);
const exercise: Exercise = new EuropeanExercise(DateExt.UTC('7,June,2014'));
const option: EuropeanOption = new EuropeanOption(payoff, exercise);

const u: Quote = new SimpleQuote(100.0);
const r: Quote = new SimpleQuote(0.01);
const s: Quote = new SimpleQuote(0.2);

const riskFreeCurve: YieldTermStructure =
    new FlatForward().ffInit3(0, new TARGET(), new Handle(r), new Actual360());
const volatility: BlackVolTermStructure = new BlackConstantVol().bcvInit4(
    0, new TARGET(), new Handle(s), new Actual360());

const process: GeneralizedBlackScholesProcess = new BlackScholesProcess(
    new Handle(u), new Handle(riskFreeCurve), new Handle(volatility));

const engine: PricingEngine = new AnalyticEuropeanEngine().init1(process);
option.setPricingEngine(engine);

const npv: Real = option.NPV();
console.log(`NPV = ${npv}`); // 4.155543462156206

release note

version notes
0.3.2 fixed swaption, most of short-rate models specs and some other pricing specs, and part of bermudanswaption example
0.3.1 examples code cleanup, fixed 4 examples, global optimizers example DE tests passed
0.3.0 fixed 40+ pricing specs, started working on model tests
0.2.7 fixed default probability curves specs
0.2.6 fixed most european option test, tree engine cleanup
0.2.5 fixed piecewise zero spreaded term structure, brownian bridge, 4 american options specs, FD engine cleanup
0.2.4 fixed risk statistics, brownian bridge some piecewise yield curve specs
0.2.3 fixed termstructure spec, experimental Gaussian quadratures specs
0.2.2 termstructure constructor cleanup, fixed a few simple ts specs
0.2.1 add halley, halleysafe, inverseIncompleteGammaFunction from QuantLib-noBoost, fixed blackdeltacalculator
0.2.0 started working on instrument pricing specs, fixed some old test that passed before
0.1.x most math specs passed
0.0.x date&time, patterns, currency, misc specs passed

docs

test-suite & example

A static report is updated regularly, so you could see the overall test status. C++ example output for reference

source code in ESM javascript:

converted from the c++ quantlib test-suite & Examples

these are the code loaded and executed in https://quantlib.js.org

credit

resource