Black (1976)

The Black (1976) Model

In 1976, Fischer Black introduced some modifications to the Black Scholes (1973) model and adapted same to evaluate more simply options on futures contracts. The resulting Black (1976) extends Black–Scholes (1973) which was originally conceived to value options on the spot price to value options based on more particularly the Futures price. The Futures market is often considered to be more liquid than the underlying Spot Market. This would appear true for many commodities. The bond futures markets can often be more heavily traded than spot analogue. To explore the linkages between the Black (1976) and Black Scholes (1973) please see worked examples in following video:

The relationship between the Black (1976) and Black Scholes (1973) models

The Black (1976) model is an extension of the Black Scholes (1973) model. To see how the model is applied at the London Metals Exchange - please see here.

An Implementation of the Black (1976) for Bond Futures

The size of Fixed Income markets tend to dwarf many other asset classes. It is worth looking at a specific Futures contract before we consider the Black model. Bond futures contracts permit investor to purchase a "theoretical government notional bond" at a pre-determined price-quantity at a given date. Bond futures are somewhat more complex relative to other futures as the underlying bond might not always be an identifiable procurable instrument but rather a theoretical notional amalgam interpolated from a reference basket of available deliverable government bonds. Bond futures are somewhat less rigorously regulated than spot equivalents, deep and extremely liquid. The futures market is regulated by the CFTC and the spot bond market is regulated by the S.E.C. In the United States: the US Treasury bond Futures, often referred to as T Bond Future, command a high degree of trading. Each instrument with similar maturity and coupon must have a similar, if not uniform, level of default. Each instrument must be perfectly substitutable given the same issuer in each instance. Credit risk can approach zero by virtue that governments can always issue new currency to cover debt repayments once denominated in the local currency. Treasury Bond futures were introduced on the Chicago Board of Trade in 1977. This product is employed widely on an international basis by institutional and individual investors for purposes of both mitigating and controlling interest rate risk exposures. In Europe: the Bund Future in Germany (Euro denominated), and the Gilt Future in UK (Sterling denominated) play a similar anchor role for hedging, speculating and arbitraging notional contracts. Bond futures are extensively utilized to hedge interest rate risk on long maturities, especially by swap dealers typically exposed to varying longer dated maturities on the interest rate curve. Please see below an example with code and video explaining how the Black (1976) model can be applied to estimate calls and puts on Bond Futures with references to put call parity in first half:

The Black (1976) model for Bond Futures and introduction to Black Greeks

VBA code for Black (1976) Model

Function Black_Call(F, K, r, sigma, T)

'

' Inputs are Originally S changed to F

' K = strike price

' r = risk-free rate

' sigma = volatility

' q = deleted for Black model

' T = time to maturity



Dim d1, d2, N1, N2

If sigma = 0 Then

Black_Call = Application.Max(0, Exp(-r * T) * F - Exp(-r * T) * K)

Else

d1 = (Log(F / K) + (0.5 * sigma * sigma) * T) / (sigma * Sqr(T))

d2 = d1 - sigma * Sqr(T)

N1 = Application.NormSDist(d1)

N2 = Application.NormSDist(d2)

Black_Call = Exp(-r * T) * F * N1 - Exp(-r * T) * K * N2

End If

End Function


Function Black_Put(F, K, r, sigma, T)

'

' Inputs are Originally S changed to F

' K = strike price

' r = risk-free rate

' sigma = volatility

' q = deleted for Black model

' T = time to maturity


Dim d1, d2, N1, N2


d1 = (Log(F / K) + (0.5 * sigma * sigma) * T) / (sigma * Sqr(T))

d2 = d1 - sigma * Sqr(T)

NN1 = Application.NormSDist(-d1)

NN2 = Application.NormSDist(-d2)

Black_Put = Exp(-r * T) * K * NN2 - Exp(-r * T) * F * NN1


End Function

C++ code for Black (1976) Model

#include <iostream>

#include <vector>

#include <cmath>


using namespace std;


// N(0,1) density

double f(double x) {

double pi = 4.0*atan(1.0);

return exp(-x*x*0.5) / sqrt(2 * pi);

}


// Boole's Rule

double Boole(double StartPoint, double EndPoint, int n) {

vector<double> X(n + 1, 0.0);

vector<double> Y(n + 1, 0.0);

double delta_x = (EndPoint - StartPoint) / double(n);

for (int i = 0; i <= n; i++) {

X[i] = StartPoint + i*delta_x;

Y[i] = f(X[i]);

}

double sum = 0;

for (int t = 0; t <= (n - 1) / 4; t++) {

int ind = 4 * t;

sum += (1 / 45.0)*(14 * Y[ind] + 64 * Y[ind + 1] + 24 * Y[ind + 2] + 64 * Y[ind + 3] + 14 * Y[ind + 4])*delta_x;

}

return sum;

}


// N(0,1) cdf by Boole's Rule

double N(double x) {

return Boole(-10.0, x, 240);

}


// Black 1976

double BlackCP(double F, double K, double T1, double r, double v, char OpType)

{

double d = (log(F / K) + T1*(0.5*v*v)) / (v*sqrt(T1));

double call = exp(-r*T1)*(F*N(d) - K*N(d - v*sqrt(T1)));

if (OpType == 'C')

return call;

else

return (call - (F - K)*exp(-r*T1));


}


int main()

{

double F = 127.09; // Bond Futures

double K = 110; // Strike Price

double T1 = 1; // Option Expiry

double r = 0.1; // Risk free interest rate

double v = 0.08; // Yearly volatility

char OpType = 'P'; // 'C'all or 'P'ut


cout << "Black Model " << BlackCP(F, K, T1, r, v, OpType) << endl;

//system("PAUSE");


};

Python Code for Black (1976)

In the code below, we apply Espen Haug's approach and set out a Generlized Black Scholes format that permits Black (1976) estimation. The Davis Edwards Github can be found here.

# This document demonstrates a Python implementation of some option models described in books written by Davis

# Edwards: "Energy Trading and Investing", "Risk Management in Trading", "Energy Investing Demystified".

# The gbs approach follows Espen Haug


# for backward compatability with Python 2.7

from __future__ import division


# import necessary libaries

import math

import numpy as np

from scipy.stats import norm

from scipy.stats import mvn


# Inputs: option_type = "p" or "c", fs = price of underlying, x = strike, t = time to expiration, r = risk free rate

# b = cost of carry, v = implied volatility

# Outputs: value, delta, gamma, theta, vega, rho

def _gbs(option_type, fs, x, t, r, b, v):

# Create preliminary calculations

t__sqrt = math.sqrt(t)

d1 = (math.log(fs / x) + (b + (v * v) / 2) * t) / (v * t__sqrt)

d2 = d1 - v * t__sqrt


if option_type == "c":

# it's a call

# _debug(" Call Option")

value = fs * math.exp((b - r) * t) * norm.cdf(d1) - x * math.exp(-r * t) * norm.cdf(d2)

else:

# it's a put

# _debug(" Put Option")

value = x * math.exp(-r * t) * norm.cdf(-d2) - (fs * math.exp((b - r) * t) * norm.cdf(-d1))

return value


# This is the public interface for European Options

# Each call does a little bit of processing and then calls the calculations located in the _gbs module


# Inputs:

# option_type = "p" or "c"

# fs = price of underlying

# x = strike

# t = time to expiration

# v = implied volatility

# r = risk free rate

# q = dividend payment

# b = cost of carry or (r - q)

# Outputs:

# value = price of the option


# Merton Model: Stocks Index, stocks with a continuous dividend yields

def merton(option_type, fs, x, t, r, q, v):

b = r - q

return _gbs(option_type, fs, x, t, r, b, v)


def black_76(option_type, fs, x, t, r, v):

b = 0

return _gbs(option_type, fs, x, t, r, b, v)



black_76('p', fs=127.09, x=110, t=1, r=0.1, v=0.08)


c = black_76('p', fs=127.09, x=110, t=1, r=0.1, v=0.08)

print( c )