# Copyright (C) 2016 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 americanGlobal(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 testAmericanOptionTest(unittest.TestCase):
    
    def test_americanBasketHermite1D(self):
  
        # dimension
        nDim = 1
        nbSimul = 100000
        nbDegree = 3
        referenceValue = 0.06031
        accuracyEqual = 1.
        # regressor
        regressor = reg.GlobalHermiteRegression(nbDegree, nDim)               
        self.assertAlmostEqual(americanGlobal(nDim, nbSimul, regressor), referenceValue, None, None, accuracyEqual)

    def test_americanBasketCanonical1D(self):
  
        # dimension
        nDim = 1
        nbSimul = 100000
        nbDegree = 3
        referenceValue = 0.06031
        accuracyEqual = 1.
        # regressor
        regressor = reg.GlobalCanonicalRegression(nbDegree, nDim)               
        self.assertAlmostEqual(americanGlobal(nDim, nbSimul, regressor), referenceValue, None, None, accuracyEqual)

    def test_americanBasketTchebychev1D(self):
  
        # dimension
        nDim = 1
        nbSimul = 100000
        nbDegree = 3
        referenceValue = 0.06031
        accuracyEqual = 1.
        # regressor
        regressor = reg.GlobalCanonicalRegression(nbDegree, nDim)               
        self.assertAlmostEqual(americanGlobal(nDim, nbSimul, regressor), referenceValue, None, None, accuracyEqual)


        


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