# Monte Carlo valuation of European option
#
import numpy as np
import math

from app.entity.ConstantValue import ConstantValue
from numpy import cumsum

class MonteCarloEuropean:

    def getValue(self, optionType, stockPrice, strike, volatility, expiryYears, dividendYield, riskfreeRate):
        S0 = stockPrice
        K = strike
        T = expiryYears
        r = riskfreeRate
        sigma = volatility
        
        I = 20000       # number of paths
        M = 100         # number of time steps
        
        dt = float(T) / float(M)    # length of time interval
        
        z = np.random.standard_normal((M + 1, I))
        
        ST = S0 * np.exp(cumsum((r - 0.5 * sigma ** 2) * dt + \
                         sigma * np.sqrt(dt) * z, axis=0))
        
        if (optionType == ConstantValue.CALL):
            hT = np.maximum(ST[-1] - K, 0)
        else:
            hT = np.maximum(K - ST[-1], 0)
                    
        return np.exp(-r * T) * np.sum(hT) / I
