Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ColinEberhardt/3df974c557881ae4319034d4fc4c9f12 to your computer and use it in GitHub Desktop.
Save ColinEberhardt/3df974c557881ae4319034d4fc4c9f12 to your computer and use it in GitHub Desktop.
barrier.ts
// the code from this gist: https://gist.github.com/jdunkerley/323b0d1d2a9b7f96d570778402389566
// re-implemented in AssemblyScript
import "wasi";
import { Console, FileSystem, Descriptor } from "as-wasi";
class Nullable<T> {
constructor(public value: T, public isNull: bool = false) {}
get notNull(): bool {
return !this.isNull;
}
}
const NullF64 = new Nullable<f64>(0, true);
class Val {
current: f64;
min: f64;
max: f64;
}
function boxMullerRand(): f64 {
while (true) {
let x = Math.random() * 2.0 - 1;
let y = Math.random() * 2.0 - 1;
let d = x * x + y * y;
if (d < 1) {
return x * sqrt((-2 * Math.log(d)) / d);
}
}
}
function pathFinalMinMax(
initial: f64,
time: f64,
steps: i32,
volatility: f64,
riskfree: f64
): Val {
let dt = time / f64(steps);
let sdt = sqrt(dt);
let drift = Math.exp((riskfree - 0.5 * volatility * volatility) * dt);
let current = initial;
let min = current;
let max = current;
for (let i = 0; i < steps - 1; i++) {
current = current * drift * Math.exp(sdt * volatility * boxMullerRand());
if (min > current) min = current;
if (max < current) max = current;
}
return { current: current, min: min, max: max };
}
function priceOption(
strike: f64,
spot: f64,
time: i32,
volatility: f64,
risk_free: f64,
knockin: Nullable<f64> = NullF64,
knockout: Nullable<f64> = NullF64,
simulations: i32 = 2000,
steps_per_unit: i32 = 365
): f64 {
if (knockin.notNull && knockout.notNull)
throw new Error("Unable to cope with 2 barriers!");
let cp = 1; // if call_or_put == 'c' else -1
let total = 0.0;
for (let i = 0; i < simulations; i++) {
const val = pathFinalMinMax(
spot,
time,
time * steps_per_unit,
volatility,
risk_free
);
if (knockin.notNull && knockin.value > spot && val.max < knockin.value) {
// Up and In
} else if (
knockin.notNull &&
knockin.value < spot &&
val.min > knockin.value
) {
// Down and In
} else if (
knockout.notNull &&
knockout.value < spot &&
val.min < knockin.value
) {
// Down and Out
} else if (
knockout.notNull &&
knockout.value > spot &&
val.max > knockout.value
) {
// Up and Out
} else {
total += Math.max(0, cp * (val.current - strike));
}
}
return (total / simulations) * Math.exp(-time * risk_free);
}
const spot = 100.0;
const strike = 105.0;
const vol = 0.2;
const risk_free = 0.05;
const price = priceOption(strike, spot, 1, vol, risk_free);
Console.log(price.toString());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment