# Copyright (C) 2016 EDF
# All Rights Reserved
# This code is published under the GNU Lesser General Public License (GNU LGPL)
import math as mth
import utils.NormalCumulativeDistribution as cdf

# Classical call option
class CallOption :

    # Constructor
    def __init__(self) :

        return None

    # value
    # p_S        asset value
    # p_sigma   volatility
    # p_r       interest rate
    # p_strike  strike
    # p_mat     maturity
    # return option value
    def operator(self, p_S, p_sigma, p_r, p_strike, p_mat) :

        d1 = (mth.log(p_S / p_strike) + (p_r + 0.5 * p_sigma * p_sigma) * p_mat) / (p_sigma * mth.sqrt(p_mat))
        d2 = d1 - p_sigma * mth.sqrt(p_mat)
        norm = cdf.NormalCumulativeDistribution()

        return p_S * norm.operator(d1) - p_strike * mth.exp(-p_r * p_mat) * norm.operator(d2)

# Classical put option
class PutOption :

    # Constructor
    def __init__(self) :

        return None

    # value
    # p_S        asset value
    # p_sigma   volatility
    # p_r       interest rate
    # p_strike  strike
    # p_mat     maturity
    # return option value
    def operator(self, p_S, p_sigma, p_r, p_strike, p_mat) :

        d1 = (mth.log(p_S / p_strike) + (p_r + 0.5 * p_sigma * p_sigma) * p_mat) / (p_sigma * mth.sqrt(p_mat))
        d2 = d1 - p_sigma * mth.sqrt(p_mat)

        return -p_S * cdf.operator(-d1) + p_strike * mth.exp(-p_r * p_mat) * cdf.operator(-d2)
