# Copyright (C) 2017 EDF
# All Rights Reserved
# This code is published under the GNU Lesser General Public License (GNU LGPL)
import numpy as np
import math as maths
import utils.BasketOptions as bo
import simulators.BlackScholesSimulator as bs
import utils.americanOption as amer    
import StOptGrids
import StOptReg as reg
import unittest



def americanKernel(p_nDim, p_nbSimul ,regressor):
    
    initialValues = np.zeros(p_nDim) + 1.0
    sigma = np.zeros(p_nDim) + 0.2
    mu = np.zeros(p_nDim) + 0.05
    corr = np.zeros((p_nDim,p_nDim))
    T = 1.
    nDate = 10
    np.fill_diagonal(corr, 1.)
    strike = 1.

    # simulator
    simulator = bs.BlackScholesSimulator(initialValues, sigma, mu, corr, T, nDate, p_nbSimul, False)
    # payoff
    payoff = bo.BasketPut(strike)

    # bermudean value
    value = amer.resolution(simulator, payoff, regressor)
    print("value",value)
    return value

# test cases
class testAmericanKernelOptionTest(unittest.TestCase):
    
    def test_americanBasketKernelLin(self):
        # dimension
        nDim = 1
        nbSimul = 5000
        bandWidth = 0.1
        referenceValue = 0.06031
        accuracyEqual = 1.
        # regressor
        regressor = reg.LocalGridKernelRegression(bandWidth,1.,True)
        self.assertAlmostEqual(americanKernel(nDim, nbSimul, regressor), referenceValue, None, None, accuracyEqual)

    def test_americanBasketKernelConst(self):
        # dimension
        nDim = 1
        nbSimul = 5000
        bandWidth = 0.1
        referenceValue = 0.06031
        accuracyEqual = 1.
        # regressor
        regressor = reg.LocalGridKernelRegression(bandWidth,1.,False)
        self.assertAlmostEqual(americanKernel(nDim, nbSimul, regressor), referenceValue, None, None, accuracyEqual)



if __name__ == '__main__':
    unittest.main()
