Skip to content

bpriyal/ccpp.math

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CCPP.Math - Quantitative Finance Mathematics Library

CCPP.Math stands for C++ Calculus Probability Puzzles Math Template Library A C++ template library for quantitative finance algorithms.

What We're Building

A C++ template library + solutions repository that implements mathematical algorithms from two quantitative finance textbooks:

  • Stefanica's "Primer for Mathematics of Financial Engineering" → Core math/numerical methods
  • Zhou's "Practical Guide to Quant Finance Interviews" → Probability puzzles + algorithms

Structure

ccpp.math/
├── include/          # Reusable template functions (integration, root finding, linear algebra, etc.)
└── src/
    ├── primer_stefanica/   # Math foundations organized by topic
    │   └── [calculus, numerical integration, Black-Scholes, PDEs, bonds, etc.]
    └── guide_zhou/         # Interview problems organized by type
        └── [brain teasers, probability puzzles, stochastic processes, algorithms]

Detailed directory structure mentioned below

Build

mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j4

Test

ctest --output-on-failure

Black-Scholes Pricing

#include "black_scholes.hpp"
using namespace ccpp::math;

BlackScholes::Parameters p{100.0, 100.0, 0.05, 0.2, 1.0};
auto result = BlackScholes::compute_all(p);

std::cout << "Call: " << result.call_price << "\n";
std::cout << "Delta: " << result.delta_call << "\n";
std::cout << "Vega: " << result.vega << "\n";

Numerical Integration

#include "numerical_integration.hpp"

auto f = [](double x) { return x * x; };
double integral = NumericalIntegration<>::simpson(f, 0, 1, 100);

Root Finding

#include "root_finding.hpp"

auto f = [](double x) { return x*x - 2; };
auto df = [](double x) { return 2*x; };
auto result = RootFinding<>::newton(f, df, 1.5);

Gambler's Ruin

#include "GamblersRuin.cpp"

double win_prob = GamblersRuin::win_probability(50, 100, 0.5);
double duration = GamblersRuin::expected_duration(50, 100, 0.51);

Detailed Directory Layout

ccpp.math/
├── CMakeLists.txt
├── README.md
├── .gitignore
├── include/
│   ├── numerical_integration.hpp
│   │   └── integrate_simpson(f, a, b, n)          // O(h^4) convergence, loop unrolling
│   │   └── integrate_trapezoidal(f, a, b, n)      // O(h^2), vectorized sum
│   │   └── integrate_midpoint(f, a, b, n)         // O(h^2), cache-friendly
│   │
│   ├── root_finding.hpp
│   │   └── solve_newton(f, df, x0, tol)           // Quadratic convergence
│   │   └── solve_bisection(f, a, b, tol)          // Linear convergence, robust
│   │   └── solve_secant(f, x0, x1, tol)           // Superlinear convergence
│   │
│   ├── finite_differences.hpp
│   │   └── first_deriv_central(f, x, h)           // (f(x+h) - f(x-h))/(2h)
│   │   └── second_deriv_central(f, x, h)          // (f(x+h) - 2f(x) + f(x-h))/h^2
│   │   └── first_deriv_forward(f, x, h)           // (f(x+h) - f(x))/h
│   │   └── first_deriv_backward(f, x, h)          // (f(x) - f(x-h))/h
│   │
│   ├── linear_algebra.hpp
│   │   └── lu_decompose(A)                        // Gaussian elimination, O(n^3)
│   │   └── cholesky_decompose(A)                  // A = R^T * R, O(n^3/3)
│   │   └── solve_tridiagonal(a, b, c, d)          // Thomas algorithm, O(n)
│   │   └── matrix_multiply(A, B)                  // Cache-blocked, O(n^3)
│   │
│   ├── statistics.hpp
│   │   └── mean(data)                             // Single-pass
│   │   └── variance(data, mean)                   // Welford's algorithm
│   │   └── covariance(x, y)                       // Online covariance
│   │   └── correlation(x, y)                      // Pearson coefficient
│   │
│   └── random_generator.hpp
│       └── box_muller_transform()                 // Generates N(0,1) pairs
│       └── inverse_transform_sampling(F_inv)      // Uses uniform RNG
│       └── acceptance_rejection(f, M, g)          // Rejection sampling
│
└── src/
    │
    ├── primer_stefanica/
    │   │
    │   ├── 00_math_preliminaries/
    │   │   ├── even_odd_functions/
    │   │   │   └── func_parity.cpp
    │   │   │       └── is_even(f, domain)         // Check f(-x) = f(x)
    │   │   │       └── is_odd(f, domain)          // Check f(-x) = -f(x)
    │   │   │
    │   │   ├── useful_sums/
    │   │   │   └── summation_formulas.cpp
    │   │   │       └── arithmetic_sum(a, d, n)    // n(2a + (n-1)d)/2
    │   │   │       └── geometric_sum(a, r, n)     // a(1-r^n)/(1-r)
    │   │   │       └── power_sum_squares(n)       // n(n+1)(2n+1)/6
    │   │   │       └── power_sum_cubes(n)         // [n(n+1)/2]^2
    │   │   │
    │   │   ├── linear_recursions/
    │   │   │   └── fibonacci_recursion.cpp
    │   │   │       └── fib_matrix_exp(n)          // O(log n) via matrix exponentiation
    │   │   │       └── fib_binet(n)               // Closed form: φ^n/√5
    │   │   │       └── fib_memoized(n)            // DP memoization
    │   │   │
    │   │   └── big_o_notation/
    │   │       └── complexity_analyzer.cpp
    │   │           └── measure_runtime(algo)      // Benchmarking
    │   │           └── estimate_complexity(data)  // Curve fitting
    │   │
    │   ├── 01_calculus_options/
    │   │   ├── differentiation/
    │   │   │   └── derivatives.cpp
    │   │   │       └── power_rule(n, x)           // d/dx(x^n) = nx^(n-1)
    │   │   │       └── chain_rule(f, g, x)        // (f∘g)' = f'(g(x))g'(x)
    │   │   │       └── product_rule(f, g, x)      // (fg)' = f'g + fg'
    │   │   │       └── quotient_rule(f, g, x)     // (f/g)' = (f'g - fg')/g^2
    │   │   │
    │   │   ├── integration/
    │   │   │   └── integrals.cpp
    │   │   │       └── integrate_power(n, a, b)   // ∫x^n dx = x^(n+1)/(n+1)
    │   │   │       └── integrate_exp(a, b)        // ∫e^x dx = e^x
    │   │   │       └── integrate_trig(func, a, b) // ∫sin, cos, tan
    │   │   │       └── integrate_by_parts(u, dv)  // ∫u dv = uv - ∫v du
    │   │   │
    │   │   ├── limits/
    │   │   │   └── limit_solver.cpp
    │   │   │       └── lhopital_rule(f, g, x0)    // lim f/g = lim f'/g'
    │   │   │       └── squeeze_theorem(g, f, h)   // g ≤ f ≤ h convergence
    │   │   │       └── epsilon_delta(f, x0, L)    // Formal definition check
    │   │   │
    │   │   ├── multivariable_functions/
    │   │   │   └── gradients_hessians.cpp
    │   │   │       └── compute_gradient(f, x)     // ∇f = [∂f/∂x₁, ...]
    │   │   │       └── compute_hessian(f, x)      // H_ij = ∂²f/∂xᵢ∂xⱼ
    │   │   │       └── directional_deriv(f, x, v) // ∇f · v̂
    │   │   │
    │   │   ├── european_options/
    │   │   │   └── plain_vanilla_payoff.cpp
    │   │   │       └── call_payoff(S, K)          // max(S - K, 0)
    │   │   │       └── put_payoff(S, K)           // max(K - S, 0)
    │   │   │       └── forward_payoff(S, K)       // S - K
    │   │   │
    │   │   └── put_call_parity/
    │   │       └── parity_check.cpp
    │   │           └── verify_parity(C, P, S, K)  // C - P = S - Ke^(-rT)
    │   │           └── synthetic_call(P, S, K)    // C = P + S - Ke^(-rT)
    │   │           └── synthetic_put(C, S, K)     // P = C - S + Ke^(-rT)
    │   │
    │   ├── 02_numerical_integration_bonds/
    │   │   ├── integration_rules/
    │   │   │   └── composite_rules.cpp
    │   │   │       └── adaptive_simpson(f, a, b)  // Recursive subdivision
    │   │   │       └── romberg_integration(f, a, b) // Richardson extrapolation
    │   │   │       └── gaussian_quadrature(f, a, b) // Legendre polynomials
    │   │   │
    │   │   ├── interest_rate_curves/
    │   │   │   ├── forward_rates.cpp
    │   │   │   │   └── compute_forward_rate(t1, t2) // f(t1,t2) = -∂ln P(t)/∂t
    │   │   │   │   └── instantaneous_forward(t)    // f(0,t) from zero curve
    │   │   │   │
    │   │   │   └── compounding.cpp
    │   │   │       └── continuous_compound(r, t)   // e^(rt)
    │   │   │       └── discrete_compound(r, n, t)  // (1 + r/n)^(nt)
    │   │   │       └── effective_annual_rate(r, m) // (1 + r/m)^m - 1
    │   │   │
    │   │   └── bond_math/
    │   │       ├── bond_pricing.cpp
    │   │       │   └── price_from_ytm(flows, y)   // Σ CF_i * e^(-y*t_i)
    │   │       │   └── ytm_from_price(flows, P)   // Newton solve for y
    │   │       │   └── spot_rate_discount(flows)  // Bootstrap zero rates
    │   │       │
    │   │       └── duration_convexity.cpp
    │   │           └── macaulay_duration(flows)    // -B'/B
    │   │           └── modified_duration(D, y)     // D/(1+y)
    │   │           └── dv01(B, y)                  // -dB/dy per bp
    │   │           └── convexity(flows, y)         // B''/B
    │   │
    │   ├── 03_probability_black_scholes/
    │   │   ├── continuous_probability/
    │   │   │   └── pdf_cdf_utils.cpp
    │   │   │       └── normal_pdf(x, μ, σ)        // (2πσ²)^(-1/2) exp(-(x-μ)²/2σ²)
    │   │   │       └── normal_cdf(x)              // 0.5 * erfc(-x/√2)
    │   │   │       └── lognormal_pdf(x, μ, σ)     // Transform from normal
    │   │   │       └── inverse_normal_cdf(p)      // Beasley-Springer-Moro
    │   │   │
    │   │   ├── black_scholes_formula/
    │   │   │   └── bs_pricer_optimized.cpp
    │   │   │       └── calculate_d1_d2(S, K, r, σ, T) // d1, d2 formulas
    │   │   │       └── call_price(S, K, r, σ, T)  // S*N(d1) - K*e^(-rT)*N(d2)
    │   │   │       └── put_price(S, K, r, σ, T)   // K*e^(-rT)*N(-d2) - S*N(-d1)
    │   │   │       └── digital_call(S, K, r, σ, T) // e^(-rT)*N(d2)
    │   │   │
    │   │   ├── greeks/
    │   │   │   └── delta_gamma_vega.cpp
    │   │   │       └── call_delta(S, K, r, σ, T)  // N(d1)
    │   │   │       └── put_delta(S, K, r, σ, T)   // N(d1) - 1
    │   │   │       └── gamma(S, K, r, σ, T)       // N'(d1)/(S*σ*√T)
    │   │   │       └── vega(S, K, r, σ, T)        // S*√T*N'(d1)
    │   │   │       └── theta_call(S, K, r, σ, T)  // -S*N'(d1)*σ/2√T - rKe^(-rT)N(d2)
    │   │   │       └── rho_call(S, K, r, σ, T)    // K*T*e^(-rT)*N(d2)
    │   │   │
    │   │   └── hedging/
    │   │       └── delta_hedge_simulator.cpp
    │   │           └── rebalance_portfolio(Δ, S)  // Adjust shares to match Δ
    │   │           └── pnl_tracking(positions)    // Mark-to-market
    │   │           └── hedging_error(actual, theo) // Discretization + transaction costs
    │   │
    │   ├── 04_lognormal_risk_neutral/
    │   │   ├── lognormal_variables/
    │   │   │   └── lognormal_dist.cpp
    │   │   │       └── lognormal_mean(μ, σ)       // exp(μ + σ²/2)
    │   │   │       └── lognormal_variance(μ, σ)   // (e^(σ²) - 1)e^(2μ+σ²)
    │   │   │       └── lognormal_moments(μ, σ, n) // E[X^n] = exp(nμ + n²σ²/2)
    │   │   │
    │   │   └── risk_neutral_derivation/
    │   │       └── risk_neutral_expectation.cpp
    │   │           └── drift_adjustment(μ, σ, r)  // μ → r - σ²/2
    │   │           └── martingale_check(S_process) // E^Q[S_T|F_t] = S_t*e^(r(T-t))
    │   │           └── girsanov_transform(dW, θ)  // dW^Q = dW + θ dt
    │   │
    │   ├── 05_taylor_series/
    │   │   ├── one_variable/
    │   │   │   └── taylor_expansion_1d.cpp
    │   │   │       └── taylor_exp(x, n_terms)     // Σ x^n/n!
    │   │   │       └── taylor_sin(x, n_terms)     // Σ (-1)^n x^(2n+1)/(2n+1)!
    │   │   │       └── taylor_ln(x, n_terms)      // Σ (-1)^(n+1)(x-1)^n/n
    │   │   │
    │   │   ├── multivariable/
    │   │   │   └── taylor_expansion_nd.cpp
    │   │   │       └── taylor_2d(f, x0, h)        // f + ∇f·h + h^T*H*h/2
    │   │   │       └── quadratic_approx(f, x0)    // Second-order expansion
    │   │   │
    │   │   └── atm_approximations/
    │   │       └── bs_approx_formulas.cpp
    │   │           └── atm_call_approx(S, σ, T)   // S*σ*√(T/2π)
    │   │           └── atm_vega_approx(S, σ, T)   // S*√T/√(2π)
    │   │           └── delta_approx_moneyness(m)  // N(m/(σ√T))
    │   │
    │   ├── 06_finite_difference_pde/
    │   │   ├── finite_differences/
    │   │   │   └── difference_schemes.cpp
    │   │   │       └── forward_difference(u, dx)   // (u_{i+1} - u_i)/dx
    │   │   │       └── backward_difference(u, dx)  // (u_i - u_{i-1})/dx
    │   │   │       └── central_difference(u, dx)   // (u_{i+1} - u_{i-1})/(2dx)
    │   │   │       └── three_point_laplacian(u, dx) // (u_{i+1} - 2u_i + u_{i-1})/dx²
    │   │   │
    │   │   └── bs_pde/
    │   │       └── bs_pde_grid_solver.cpp
    │   │           └── explicit_euler(grid, dt)    // u^(n+1) = u^n + α(...), α < 0.5
    │   │           └── implicit_euler(grid, dt)    // Solve tridiagonal system
    │   │           └── crank_nicolson(grid, dt)    // θ = 0.5 scheme
    │   │           └── boundary_conditions(grid)   // Dirichlet/Neumann
    │   │
    │   ├── 07_multivariable_calculus/
    │   │   ├── extrema/
    │   │   │   └── lagrange_optimizer.cpp
    │   │   │       └── lagrange_multiplier(f, g)  // ∇f = λ∇g
    │   │   │       └── constrained_min(f, constraints) // KKT conditions
    │   │   │       └── classify_critical_point(H) // Eigenvalues of Hessian
    │   │   │
    │   │   └── random_generation/
    │   │       └── box_muller_generator.cpp
    │   │           └── box_muller()                // Z1 = √(-2ln U1)cos(2πU2)
    │   │           └── polar_rejection()           // Alternate method
    │   │           └── validate_normality(samples) // χ² test
    │   │
    │   └── 08_roots_implied_vol/
    │       ├── nonlinear_solvers/
    │       │   ├── newton_raphson.cpp
    │       │   │   └── solve_scalar(f, df, x0)    // x_new = x - f/f'
    │       │   │   └── solve_vector(F, J, x0)     // Newton for systems
    │       │   │
    │       │   ├── bisection.cpp
    │       │   │   └── solve(f, a, b, tol)        // Halve interval [a,b]
    │       │   │   └── illinois_method(f, a, b)   // Modified regula falsi
    │       │   │
    │       │   └── secant.cpp
    │       │       └── solve(f, x0, x1, tol)      // x_new = x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))
    │       │
    │       ├── implied_volatility/
    │       │   └── implied_vol_solver.cpp
    │       │       └── solve_iv_newton(C_mkt, params) // Newton on C_mkt - BS(σ)
    │       │       └── solve_iv_brent(C_mkt, params)  // Brent's method
    │       │       └── vega_analytical(σ, params) // Derivative for Newton
    │       │       └── iv_initial_guess(K, S)     // Brenner-Subrahmanyam
    │       │
    │       └── bootstrapping/
    │           └── yield_curve_bootstrap.cpp
    │               └── bootstrap_zero_rates(bonds) // Iterative solve
    │               └── interpolate_rates(t, knots) // Linear/cubic spline
    │               └── forward_rate_from_zeros(r, t1, t2) // (r2*t2 - r1*t1)/(t2-t1)
    │
    └── guide_zhou/
        │
        ├── brain_teasers/
        │   ├── screwy_pirates/
        │   │   └── PirateGoldSplit.cpp
        │   │       └── solve_distribution(N)       // Backward induction
        │   │       └── pirate_gets_coin(i, N)      // i odd → gets 1
        │   │
        │   ├── tiger_and_sheep/
        │   │   └── TigerSurvival.cpp
        │   │       └── will_eat(N_tigers)          // (N-1) % 2 == 0
        │   │
        │   ├── birthday_problem/
        │   │   └── BirthdayParadox.cpp
        │   │       └── prob_collision(n)           // 1 - 365!/(365^n*(365-n)!)
        │   │       └── min_people_for_prob(p)      // Binary search for n
        │   │
        │   ├── burning_ropes/
        │   │   └── RopeTimer.cpp
        │   │       └── measure_time(t_target)      // Light both ends strategy
        │   │
        │   ├── defective_ball/
        │   │   └── BallWeighing.cpp
        │   │       └── min_weighings(N_balls)      // log_3(N)
        │   │       └── decision_tree(weights)      // Ternary tree
        │   │
        │   ├── trailing_zeros/
        │   │   └── FactorialZeros.cpp
        │   │       └── count_zeros(n)              // Σ floor(n/5^i)
        │   │
        │   ├── box_packing/
        │   │   └── BoxPacker.cpp
        │   │       └── can_pack(boxes, container)  // 3D bin packing heuristic
        │   │
        │   ├── calendar_cubes/
        │   │   └── CubeFaceSolver.cpp
        │   │       └── find_digits()               // Constraint satisfaction
        │   │
        │   ├── coin_piles/
        │   │   └── CoinFlipper.cpp
        │   │       └── expected_flips(n)           // Geometric series
        │   │
        │   ├── mislabeled_bags/
        │   │   └── FruitBagLogic.cpp
        │   │       └── identify_bags()             // Single draw logic
        │   │
        │   └── wise_men/
        │       └── WiseMenStrategy.cpp
        │           └── determine_hat_color()       // Parity strategy
        │
        ├── calculus_linear_algebra/
        │   ├── limits_derivatives/
        │   │   └── DerivativeCalculator.cpp
        │   │       └── symbolic_derivative(expr)   // AD implementation
        │   │       └── numerical_derivative(f, x)  // Central difference
        │   │
        │   ├── integration/
        │   │   └── IntegralSolver.cpp
        │   │       └── symbolic_integral(expr)     // Pattern matching
        │   │       └── numerical_integral(f, a, b) // Adaptive quadrature
        │   │
        │   ├── matrix_operations/
        │   │   └── MatrixOps.cpp
        │   │       └── eigenvalues_qr(A)           // QR algorithm
        │   │       └── determinant_lu(A)           // Via LU decomposition
        │   │       └── inverse_gauss_jordan(A)     // Augmented matrix
        │   │
        │   └── decompositions/
        │       └── LUCholesky.cpp
        │           └── lu_factorize(A)             // Doolittle algorithm
        │           └── cholesky_factorize(A)       // R^T*R decomposition
        │           └── solve_linear_system(L, U, b) // Forward/back substitution
        │
        ├── probability_theory/
        │   ├── coin_toss_game/
        │   │   └── CoinGameSim.cpp
        │   │       └── expected_payoff()           // E = Σ P(i)*payoff(i)
        │   │       └── variance_payoff()           // E[X²] - E[X]²
        │   │
        │   ├── drunk_passenger/
        │   │   └── SeatProbability.cpp
        │   │       └── prob_correct_seat(n)        // 0.5 for n ≥ 2
        │   │       └── recursive_formula(n)        // Symmetry argument
        │   │
        │   ├── n_points_circle/
        │   │   └── CirclePoints.cpp
        │   │       └── prob_semicircle(n)          // n/2^(n-1)
        │   │
        │   ├── poker_hands/
        │   │   └── PokerCombinatorics.cpp
        │   │       └── prob_flush()                // C(13,5)*4 / C(52,5)
        │   │       └── prob_straight()             // Count straights
        │   │
        │   ├── hopping_rabbit/
        │   │   └── RabbitStairs.cpp
        │   │       └── ways_to_top(n)              // F(n) = F(n-1) + F(n-2)
        │   │
        │   ├── application_letters/
        │   │   └── EnvelopeDerangement.cpp
        │   │       └── count_derangements(n)       // !n = (n-1)*(!(n-1) + !(n-2))
        │   │       └── prob_no_match(n)            // !n / n!
        │   │
        │   ├── monty_hall/
        │   │   └── MontyHallSim.cpp
        │   │       └── simulate_stay_strategy()    // Win rate = 1/3
        │   │       └── simulate_switch_strategy()  // Win rate = 2/3
        │   │
        │   ├── amoeba_population/
        │   │   └── AmoebaExtinction.cpp
        │   │       └── extinction_prob()           // Branching process
        │   │
        │   ├── candies_jar/
        │   │   └── CandyProbability.cpp
        │   │       └── prob_last_candy(color)      // Combinatorial argument
        │   │
        │   └── russian_roulette/
        │       └── RouletteSurvival.cpp
        │           └── survival_prob(strategy)     // Compare spin vs no-spin
        │
        ├── stochastic_process/
        │   ├── gamblers_ruin/
        │   │   └── GamblersRuin.cpp
        │   │       └── win_probability(i, N, p)    // (1-(q/p)^i)/(1-(q/p)^N)
        │   │       └── expected_duration(i, N, p)  // i/(p-q) - N(1-(q/p)^i)/(...)
        │   │
        │   ├── dice_question/
        │   │   └── DiceRollExpectation.cpp
        │   │       └── expected_rolls_until_6()    // Geometric: 1/p = 6
        │   │       └── expected_distinct_faces()   // Coupon collector
        │   │
        │   ├── coin_triplets/
        │   │   └── CoinSequenceMartingale.cpp
        │   │       └── expected_flips_HHT()        // 8 (vs 10 for HTT)
        │   │       └── martingale_proof()          // E[T_A] derivation
        │   │
        │   ├── color_balls/
        │   │   └── BallColorMarkov.cpp
        │   │       └── transition_matrix()         // P_ij for state transitions
        │   │       └── stationary_distribution()   // π = πP
        │   │
        │   ├── drunk_man_walk/
        │   │   └── RandomWalk1D.cpp
        │   │       └── first_passage_time(x0, a)   // E[T] for symmetric walk
        │   │       └── probability_reach_a(x0, a, b) // Gambler's ruin
        │   │
        │   ├── dynamic_dice/
        │   │   └── DynamicProgrammingDice.cpp
        │   │       └── optimal_stopping(n_rolls)   // V(n) = max(accept, continue)
        │   │       └── threshold_values()          // Precompute optimal thresholds
        │   │
        │   └── dynamic_card/
        │       └── OptimalCardStopping.cpp
        │           └── secretary_problem()         // Optimal strategy: n/e
        │           └── expected_value()            // 1/e ≈ 0.37
        │
        ├── finance_options/
        │   ├── put_call_parity/
        │   │   └── ParityArbitrage.cpp
        │   │       └── detect_arbitrage(C, P, S, K) // Check C - P = S - Ke^(-rT)
        │   │       └── arbitrage_pnl()             // Profit from violation
        │   │
        │   ├── american_vs_european/
        │   │   └── OptionComparison.cpp
        │   │       └── early_exercise_boundary()   // Optimal exercise for American
        │   │       └── price_difference(params)    // American premium
        │   │
        │   ├── straddle_bull_spread/
        │   │   └── OptionStrategyPayoff.cpp
        │   │       └── straddle_payoff(S, K)       // |S - K|
        │   │       └── bull_spread_payoff(S, K1, K2) // max(0, min(S-K1, K2-K1))
        │   │
        │   ├── portfolio_optimization/
        │   │   └── MeanVarianceOptimizer.cpp
        │   │       └── efficient_frontier(μ, Σ)    // Markowitz optimization
        │   │       └── optimal_weights(target_return) // Solve QP
        │   │
        │   └── value_at_risk/
        │       └── VaRCalculator.cpp
        │           └── historical_var(returns, α)  // α-quantile
        │           └── parametric_var(μ, σ, α)     // Gaussian assumption
        │           └── monte_carlo_var(model, α)   // Simulation-based
        │
        └── algorithms_numerical/
            ├── number_swap/
            │   └── BitwiseSwap.cpp
            │       └── swap_xor(a, b)              // a ^= b; b ^= a; a ^= b
            │
            ├── unique_elements/
            │   └── UniqueFilter.cpp
            │       └── find_unique_xor(arr)        // XOR all elements
            │       └── find_unique_hash(arr)       // Hash set O(n)
            │
            ├── horners_algorithm/
            │   └── PolynomialEval.cpp
            │       └── horner_eval(coeffs, x)      // a_n + x(a_(n-1) + x(...))
            │
            ├── moving_average/
            │   └── MovingAvgWindow.cpp
            │       └── sma_sliding_window(data, k) // O(n) with queue
            │       └── ema_exponential(data, α)    // α*x_t + (1-α)*EMA_(t-1)
            │
            ├── sorting_algorithms/
            │   └── QuickMergeSort.cpp
            │       └── quicksort_inplace(arr)      // Average O(n log n)
            │       └── mergesort_stable(arr)       // Guaranteed O(n log n)
            │       └── heapsort(arr)               // In-place O(n log n)
            │
            ├── random_permutation/
            │   └── KnuthShuffle.cpp
            │       └── fisher_yates_shuffle(arr)   // Swap arr[i] with arr[rand(i,n)]
            │
            ├── fibonacci_numbers/
            │   └── FibOptimized.cpp
            │       └── fib_iterative(n)            // O(n) space O(1)
            │       └── fib_matrix_power(n)         // [[1,1],[1,0]]^n, O(log n)
            │
            ├── max_contiguous_subarray/
            │   └── KadaneAlgorithm.cpp
            │       └── kadane(arr)                 // current_max = max(arr[i], current_max + arr[i])
            │
            └── pi_estimation/
                └── MonteCarloPi.cpp
                    └── estimate_pi_circle(n_samples) // 4 * (points_in_circle / total)
                    └── estimate_pi_buffon(n_drops)   // 2L/(πd) for needle drops

References

  • Stefanica, D. "A Primer for the Mathematics of Financial Engineering" (2nd ed.)

    • Chapters: Calculus, Integration, Probability, Black-Scholes, PDEs, Bonds, Implied Vol
  • Zhou, P., Serrano-Fontaine, A. "A Practical Guide to Quantitative Finance Interviews"

    • Sections: Brain teasers, Probability, Stochastic processes, Option strategies

Compiler Requirements

  • C++17 or higher (for std::optional, structured bindings)
  • GCC 7+, Clang 5+, MSVC 2017+
  • OpenMP for parallel algorithms (optional)

Mathematical Completeness

  • Calculus: Derivatives, integrals, limits, multivariable functions
  • Probability: Continuous distributions, normal/lognormal PDFs, Black-Scholes
  • Numerical Methods: Finite differences, PDE solvers, Taylor series
  • Bonds & Rates: Duration, convexity, yield curve bootstrapping
  • Stochastic: Lognormal processes, risk-neutral valuation, Girsanov
  • Interview Problems: Brain teasers, probability puzzles, stochastic processes

Compilation

# Create build directory
mkdir build && cd build

# Configure (C++17 required)
cmake .. -DCMAKE_BUILD_TYPE=Release

# Compile
make -j4

# Run tests
ctest --output-on-failure

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published