if !(VERSION.major==0&&VERSION.minor<=6)
	using Test
else
	using Base.Test
end
using FinancialToolbox

print_colored("Starting Complex Number Test\n",:green)

#Test Parameters
testToll=1e-14;
spot=10;K=10;r=0.02;T=2.0;sigma=0.2;d=0.01;
assert_(value,toll)=@test abs(value)<toll

#EuropeanCall Option
PriceCall=blsprice(spot,K,r,T,sigma,d);
DeltaCall=blsdelta(spot,K,r,T,sigma,d);
ThetaCall=blstheta(spot,K,r,T,sigma,d);
LambdaCall=blslambda(spot,K,r,T,sigma,d);
RhoCall=blsrho(spot,K,r,T,sigma,d);

#EuropeanPut Option
PricePut=blsprice(spot,K,r,T,sigma,d,false);
DeltaPut=blsdelta(spot,K,r,T,sigma,d,false);
ThetaPut=blstheta(spot,K,r,T,sigma,d,false);
RhoPut=blsrho(spot,K,r,T,sigma,d,false);
LambdaPut=blslambda(spot,K,r,T,sigma,d,false);

#Equals for both Options
Gamma=blsgamma(spot,K,r,T,sigma,d);
Vega=blsvega(spot,K,r,T,sigma,d);

## Complex Test with Complex Step Approximation for European Call
#Test parameters
DerToll=1e-13;
di=1e-15;
df(f,x)=f(x+1im*di)/di;
#Function definition
Fcall1(spot)=blsprice(spot,K,r,T,sigma,d);
Gcall1(r)=blsprice(spot,K,r,T,sigma,d);
Hcall1(T)=blsprice(spot,K,r,T,sigma,d);
Lcall1(sigma)=blsprice(spot,K,r,T,sigma,d);
Pcall1(spot)=blsprice(spot,K,r,T,sigma,d)*spot.re/blsprice(spot.re,K,r,T,sigma,d);
#TEST
print_colored("--- European Call Sensitivities: Complex Step Approximation\n",:yellow)
print_colored("-----Testing Delta\n",:blue);
assert_(df(Fcall1,spot).im-DeltaCall,DerToll)
print_colored("-----Testing Rho\n",:blue);
assert_(df(Gcall1,r).im-RhoCall,DerToll)
print_colored("-----Testing Theta\n",:blue);
assert_(-df(Hcall1,T).im-ThetaCall,DerToll)
print_colored("-----Testing Lambda\n",:blue);
assert_(df(Pcall1,spot).im-LambdaCall,DerToll)

## Complex Test with Complex Step Approximation for European Put
#Function definition
Fput1(spot)=blsprice(spot,K,r,T,sigma,d,false);
Gput1(r)=blsprice(spot,K,r,T,sigma,d,false);
Hput1(T)=blsprice(spot,K,r,T,sigma,d,false);
Pput1(spot)=blsprice(spot,K,r,T,sigma,d,false)*spot.re/blsprice(spot.re,K,r,T,sigma,d,false);
#TEST
print_colored("--- European Put Sensitivities: Complex Step Approximation\n",:yellow)
print_colored("-----Testing Delta\n",:blue);
assert_(df(Fput1,spot).im-DeltaPut,DerToll)
print_colored("-----Testing Rho\n",:blue);
assert_(df(Gput1,r).im-RhoPut,DerToll)
print_colored("-----Testing Theta\n",:blue);
assert_(-df(Hput1,T).im-ThetaPut,DerToll)
print_colored("-----Testing Lambda\n",:blue);
assert_(df(Pput1,spot).im-LambdaPut,DerToll)

print_colored("-----Testing Vega\n",:blue);
assert_(df(Lcall1,sigma).im-Vega,DerToll)
print_colored("Complex Number Test Passed\n",:green)
println("")

#TEST OF INPUT VALIDATION
print_colored("Starting Input Validation Test Complex\n",:magenta)
print_colored("----Testing Negative  Spot Price \n",:cyan)
@test_throws(ErrorException, blsprice(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blkprice(-spot+1im,K,r,T,sigma))
@test_throws(ErrorException, blsdelta(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blsgamma(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blstheta(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blsrho(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blspsi(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blslambda(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blsvanna(-spot+1im,K,r,T,sigma,d))
@test_throws(ErrorException, blsvega(-spot+1im,K,r,T,sigma,d))

print_colored("----Testing Negative  Strike Price \n",:cyan)
@test_throws(ErrorException, blsprice(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blkprice(spot,-K+1im,r,T,sigma))
@test_throws(ErrorException, blsdelta(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blsgamma(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blstheta(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blsrho(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blspsi(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blslambda(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blsvanna(spot,-K+1im,r,T,sigma,d))
@test_throws(ErrorException, blsvega(spot,-K+1im,r,T,sigma,d))

print_colored("----Testing Negative  Time to Maturity \n",:cyan)
@test_throws(ErrorException, blsprice(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blkprice(spot,K,r,-T+1im,sigma))
@test_throws(ErrorException, blsdelta(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blsgamma(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blstheta(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blsrho(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blspsi(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blslambda(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blsvanna(spot,K,r,-T+1im,sigma,d))
@test_throws(ErrorException, blsvega(spot,K,r,-T+1im,sigma,d))

print_colored("----Testing Negative  Volatility \n",:cyan)
@test_throws(ErrorException, blsprice(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blkprice(spot,K,r,T,-sigma+1im))
@test_throws(ErrorException, blsdelta(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blsgamma(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blstheta(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blsrho(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blspsi(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blslambda(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blsvanna(spot,K,r,T,-sigma+1im,d))
@test_throws(ErrorException, blsvega(spot,K,r,T,-sigma+1im,d))

print_colored("Complex Input Validation Test Passed\n",:magenta)
