Pricing Options in C using Python Wrappers

This project explores the Black-Scholes model for pricing European call and put options. Implemented in C, the project uses Python wrappers to make it easier for a user to try out.

You can modify parameters and see how volatility affects pricing.

Get the code on GitHub →

But what are options?

Let's define what we're actually pricing.

  • A call option gives the holder the right, but not the obligation, to buy an asset at a fixed price (called the strike price KK) before or at a specified expiration date.
  • A put option gives the holder the right to sell an asset at the strike price before or at expiration.

These options are financial contracts used for speculation or hedging.

In this case, we are using the Black-Scholes equation, which only concerns European Options. There are different types of options, such as American and Exotic options.

Where Does the Black-Scholes Equation Come From?

We assume that stock prices follow a geometric Brownian Motion:

dS=μSdt+σSWtdS = \mu S dt + \sigma S W_t

This equation says that the change in the stock price SS over a small time dtdt has two parts:

  • A deterministic trend (like expected return over time):
μSdt\mu S dt
  • A random component (fluctuations from market noise):
σSdWt\sigma S dW_t

Here:

  • SS = asset price
  • μ\mu = expected return
  • σ\sigma = volatility
  • WtW_t = Wiener process (random noise)

We use Itô’s Lemma, which is a tool from stochastic calculus that tells us how a function of a stochastic process behaves. Stochastic means random.

Applying Itô’s Lemma to V(S,t)V(S, t) gives:

dV=Vtdt+VSdS+122VS2σ2S2dtdV = \frac{\partial V}{\partial t}\,dt + \frac{\partial V}{\partial S}\,dS + \frac{1}{2} \frac{\partial^2 V}{\partial S^2} \sigma^2 S^2\,dt

We now create a hedged portfolio by holding one option and shorting Δ=VS\Delta = \frac{\partial V}{\partial S} shares of stock. This eliminates the dSdS (random) term, making the portfolio risk-free over an infinitesimal time interval.

Since a risk-free portfolio should earn the risk-free interest rate rr, we equate the return of the portfolio to rr and arrive at the Black-Scholes Partial Differential Equation (PDE):

Vt+12σ2S22VS2+rSVSrV=0\frac{\partial V}{\partial t} + \frac{1}{2} \sigma^2 S^2 \frac{\partial^2 V}{\partial S^2} + r S \frac{\partial V}{\partial S} - r V = 0

Solving this PDE under boundary conditions for a European call option gives the celebrated Black-Scholes equation:

C=S0N(d1)KerTN(d2)C = S_0 N(d_1) - K e^{-rT} N(d_2)

where

d1=ln(S0/K)+(r+σ2/2)TσT,d2=d1σTd_1 = \frac{\ln(S_0/K) + (r + \sigma^2 / 2)T}{\sigma \sqrt{T}}, \quad d_2 = d_1 - \sigma \sqrt{T}

And What About Put Options?

For a European put option, the solution to the same PDE leads to:

P=KerTN(d2)S0N(d1)P = K e^{-rT} N(-d_2) - S_0 N(-d_1)

Where the terms are still:

d1=ln(S0/K)+(r+σ2/2)TσT,d2=d1σTd_1 = \frac{\ln(S_0/K) + (r + \sigma^2 / 2)T}{\sigma \sqrt{T}}, \quad d_2 = d_1 - \sigma \sqrt{T}

This is derived using put-call parity and represents the fair value of a put option assuming no arbitrage, continuous hedging, and no early exercise (i.e., European style).