Options Pricing Engine

HARD • Live C++ Rust Java Python
500K
OPTIONS
100
UNDERLYINGS
5
MODELS

Problem Description

Price 500,000 European options using Black-Scholes. Handle puts and calls with various strikes, expirations, volatilities, and risk-free rates.

Compute the option price and all Greeks: delta, gamma, vega, theta, and rho. All values are compared against a reference Black-Scholes implementation with a tolerance of 0.0001.

Tier System & Performance Targets

LANGUAGEGOLDSILVERBRONZE
C++ / Rust< 400ms< 1500ms< 120s
Java< 800ms< 3000ms< 120s
Python< 5000ms< 15000ms< 120s

Evaluation Criteria

Correctness: Each of the 6 output values per line (price, delta, gamma, vega, theta, rho) is compared individually. A value is "correct" if it is within 0.0001 of the reference. Your accuracy score is correct values / total values.

Performance: Wall-clock time to price all 500K options. Numerical stability matters for deep ITM/OTM contracts.

Input Format

Read from stdin. The first line is the number of contracts N. The next N lines each contain a comma-separated option:

S,K,T,r,sigma,TYPE

Where:

Output Format

For each option, output one line with 6 space-separated values to 6 decimal places:

PRICE DELTA GAMMA VEGA THETA RHO

Example

Input

3
100.0,100.0,0.5,0.05,0.25,C
100.0,90.0,1.0,0.03,0.30,P
120.0,110.0,0.25,0.04,0.20,C

Output

8.260015 0.590880 0.021979 27.474322 -9.409981 25.414001
5.946349 -0.273853 0.011099 33.298418 -3.994814 -33.331631
12.101627 0.846163 0.019759 14.226266 -9.268023 22.359476

Line 1: ATM call -- delta near 0.5, highest gamma. Line 2: OTM put -- negative delta and rho. Line 3: ITM call -- delta near 1, lower gamma.

Submission Rules

Starter Templates

C++
#include <cstdio>
#include <cmath>
#include <cstring>

int main() {
    int N;
    scanf("%d", &N);

    double S, K, T, r, sigma;
    char type;

    for (int i = 0; i < N; i++) {
        scanf("%lf,%lf,%lf,%lf,%lf,%c", &S, &K, &T, &r, &sigma, &type);

        // Implement Black-Scholes pricing
        // Compute: price, delta, gamma, vega, theta, rho
        double price = 0, delta = 0, gamma = 0, vega = 0, theta = 0, rho = 0;

        printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",
               price, delta, gamma, vega, theta, rho);
    }
    return 0;
}
Python
import sys
import math

def normal_cdf(x):
    return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))

def normal_pdf(x):
    return math.exp(-0.5 * x * x) / math.sqrt(2.0 * math.pi)

def price_option(S, K, T, r, sigma, option_type):
    sqrt_T = math.sqrt(T)
    d1 = (math.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt_T)
    d2 = d1 - sigma * sqrt_T
    # Implement Black-Scholes: compute price, delta, gamma, vega, theta, rho
    return 0, 0, 0, 0, 0, 0

for line in sys.stdin:
    parts = line.strip().split()
N = int(input())
for _ in range(N):
    parts = input().split(',')
    S = float(parts[0])
    K = float(parts[1])
    T = float(parts[2])
    r = float(parts[3])
    sigma = float(parts[4])
    option_type = parts[5].strip()

    price, delta, gamma, vega, theta, rho = price_option(S, K, T, r, sigma, option_type)
    print(f"{price:.6f} {delta:.6f} {gamma:.6f} {vega:.6f} {theta:.6f} {rho:.6f}")
Rust
use std::io::{self, BufRead, Write, BufWriter};

fn normal_cdf(x: f64) -> f64 {
    0.5 * (1.0 + libm::erf(x / std::f64::consts::SQRT_2))
}

fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut out = BufWriter::new(stdout.lock());
    let mut lines = stdin.lock().lines();

    let n: usize = lines.next().unwrap().unwrap().trim().parse().unwrap();

    for _ in 0..n {
        let line = lines.next().unwrap().unwrap();
        let parts: Vec<&str> = line.trim().split(',').collect();
        let s: f64 = parts[0].parse().unwrap();
        let k: f64 = parts[1].parse().unwrap();
        let t: f64 = parts[2].parse().unwrap();
        let r: f64 = parts[3].parse().unwrap();
        let sigma: f64 = parts[4].parse().unwrap();
        let opt_type = parts[5].trim();

        // Implement Black-Scholes: compute price, delta, gamma, vega, theta, rho
        let (price, delta, gamma, vega, theta, rho) = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);

        writeln!(out, "{:.6} {:.6} {:.6} {:.6} {:.6} {:.6}",
                 price, delta, gamma, vega, theta, rho).unwrap();
    }
}
Java
import java.util.*;
import java.io.*;

public class Solution {
    static double normalCdf(double x) {
        return 0.5 * (1.0 + erf(x / Math.sqrt(2.0)));
    }

    static double erf(double x) {
        // Horner form approximation
        double t = 1.0 / (1.0 + 0.3275911 * Math.abs(x));
        double y = 1.0 - (((((1.061405429 * t - 1.453152027) * t)
                + 1.421413741) * t - 0.284496736) * t + 0.254829592) * t * Math.exp(-x * x);
        return x >= 0 ? y : -y;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        int N = Integer.parseInt(br.readLine().trim());

        for (int i = 0; i < N; i++) {
            String[] parts = br.readLine().trim().split(",");
            double S = Double.parseDouble(parts[0]);
            double K = Double.parseDouble(parts[1]);
            double T = Double.parseDouble(parts[2]);
            double r = Double.parseDouble(parts[3]);
            double sigma = Double.parseDouble(parts[4]);
            String type = parts[5].trim();

            // Implement Black-Scholes: compute price, delta, gamma, vega, theta, rho
            double price = 0, delta = 0, gamma = 0, vega = 0, theta = 0, rho = 0;

            sb.append(String.format("%.6f %.6f %.6f %.6f %.6f %.6f%n",
                      price, delta, gamma, vega, theta, rho));
        }
        System.out.print(sb);
    }
}

Submit Your Solution

Supported formats: .cpp, .py, .rs, .java, or raw text