Source code for putcall.formulas.plain_vanilla_options.blackscholes

# -*- coding: utf-8 -*-

# putcall
# -------
# Collection of classical option pricing formulas.
# 
# Author:   sonntagsgesicht, based on a fork of Deutsche Postbank [pbrisk]
# Version:  0.2, copyright Wednesday, 18 September 2019
# Website:  https://github.com/sonntagsgesicht/putcall
# License:  Apache License 2.0 (see LICENSE file)


import math

from mathtoolspy.distribution.normal_distribution import cdf_abramowitz_stegun as normal_cdf
# from ..option_payoffs import option_payoff
from putcall.formulas.option_payoffs import option_payoff, digital_option_payoff


[docs]def black_scholes(spot_value, strike_value, vol_value, time_value, is_call_bool, rate=0.): """ Black Scholes option pricing formula on log-normal spot value :param forward_value: forward price of underlying at exercise date :type forward_value: real :param strike_value: strike of the option :type strike_value: real :param vol_value: volatility of underlying price :type vol_value: non-negative real :param time_value: year fraction until exercise date :type time_value: non-negative real :param is_call_bool: call -> True, put -> False :type is_call_bool: boolean :param rate: risk free rate :type rate: real :return: option price :rtype: real :return: """ if not vol_value >= 0: raise AssertionError("Negative vol in %s" % __name__) sigma = vol_value * math.sqrt(time_value) if sigma == 0: # non-random option value, e.g. on exercise date return option_payoff(spot_value, strike_value, is_call_bool) d1 = (math.log(spot_value / strike_value) + rate * time_value + 0.5 * sigma ** 2) / sigma d2 = d1 - sigma if is_call_bool: return spot_value * normal_cdf(d1) - strike_value * math.exp(-rate * time_value) * normal_cdf(d2) else: return strike_value * math.exp(-rate * time_value) * normal_cdf(-d2) - spot_value * normal_cdf(-d1)
[docs]def black_scholes_digital(spot_value, strike_value, vol_value, time_value, is_call_bool, rate=0.): """ Black Scholes digital option pricing formula on log-normal spot value :param spot_value: forward price of underlying at exercise date :type spot_value: real :param strike_value: strike of the option :type strike_value: real :param vol_value: volatility of underlying price :type vol_value: non-negative real :param time_value: year fraction until exercise date :type time_value: non-negative real :param is_call_bool: call -> True, put -> False :type is_call_bool: boolean :param rate: risk free rate :type rate: real :return: option price :rtype: real :return: """ if not vol_value >= 0: raise AssertionError("Negative vol in %s" % __name__) sigma = vol_value * math.sqrt(time_value) if sigma == 0: # non-random option value, e.g. on exercise date return digital_option_payoff(spot_value, strike_value, is_call_bool) d0 = (math.log(spot_value / strike_value) + rate * time_value - 0.5 * sigma ** 2) / sigma return math.exp(-rate * time_value) * normal_cdf(d0)
[docs]def forward_black_scholes(forward_value, strike_value, vol_value, time_value, is_call_bool, rate=0.): """ Black Scholes option pricing formula on log-normal forward value :param strike_value: strike of the option :type strike_value: real :param forward_value: forward price of underlying at exercise date :type forward_value: real :param vol_value: volatility of underlying price :type vol_value: non-negative real :param time_value: year fraction until exercise date :type time_value: non-negative real :param is_call_bool: call -> True, put -> False :type is_call_bool: boolean :param rate: risk free rate :type rate: real :return: option price :rtype: real :return: """ if not vol_value >= 0: raise AssertionError("Negative vol in %s" % __name__) sigma = vol_value * math.sqrt(time_value) if sigma == 0: # non-random option value, e.g. on exercise date return option_payoff(forward_value, strike_value, is_call_bool) d1 = (math.log(forward_value / strike_value) + 0.5 * sigma ** 2) / sigma d2 = d1 - sigma if is_call_bool: return (forward_value * normal_cdf(d1) - strike_value * normal_cdf(d2)) * math.exp(-rate * time_value) else: return (strike_value * normal_cdf(-d2) - forward_value * normal_cdf(-d1)) * math.exp(-rate * time_value)
[docs]def forward_black_scholes_digital(forward_value, strike_value, vol_value, time_value, is_call_bool, rate=0.): """ Black Scholes digital option pricing formula on log-normal forward value :param strike_value: strike of the option :type strike_value: real :param forward_value: forward price of underlying at exercise date :type forward_value: real :param vol_value: volatility of underlying price :type vol_value: non-negative real :param time_value: year fraction until exercise date :type time_value: non-negative real :param is_call_bool: call -> True, put -> False :type is_call_bool: boolean :param rate: risk free rate :type rate: real :return: option price :rtype: real :return: """ if not vol_value >= 0: raise AssertionError("Negative vol in %s" % __name__) sigma = vol_value * math.sqrt(time_value) if sigma == 0: # non-random option value, e.g. on exercise date return digital_option_payoff(forward_value, strike_value, is_call_bool) d0 = (math.log(forward_value / strike_value) + rate * time_value - 0.5 * sigma ** 2) / sigma return math.exp(-rate * time_value) * normal_cdf(d0)