public void Test()
{
Engine.MultiThread = true;
Document doc = new Document();
ProjectROV rov = new ProjectROV(doc);
doc.Part.Add(rov);
doc.DefaultProject.NMethods.m_UseAntiteticPaths = true;
int n_sim = 20000;
int n_steps = 1024;
double a = 0.2;
double DR = 0.02;
double r0 = 0.015;
double a1 = 0.02;
double sigma1 = 0.01;
double maturityOpt = 5.0;
double strike = 0.005;
double tau = 0.5;
double strike2 = 1.0 / (1.0 + strike * tau);
ModelParameter PT = new ModelParameter(maturityOpt, "TT");
PT.VarName = "TT";
rov.Symbols.Add(PT);
ModelParameter Ptau = new ModelParameter(tau, "tau");
Ptau.VarName = "tau";
rov.Symbols.Add(Ptau);
ModelParameter Pa = new ModelParameter(a, "a");
Pa.VarName = "a";
rov.Symbols.Add(Pa);
ModelParameter PDR = new ModelParameter(DR, "PDR");
PDR.VarName = "DR";
rov.Symbols.Add(PDR);
ModelParameter Pr0 = new ModelParameter(r0, "r0");
Pr0.VarName = "r0";
rov.Symbols.Add(Pr0);
ModelParameter Pstrike = new ModelParameter(strike, "strike");
Pstrike.VarName = "strike";
rov.Symbols.Add(Pstrike);
AFunction zerorate = new AFunction(rov);
zerorate.VarName = "zr";
zerorate.m_IndependentVariables = 1;
zerorate.m_Value = (RightValue)("(1-exp(-a*x1))*DR + r0");
rov.Symbols.Add(zerorate);
HW1 process = new HW1(a1, sigma1, "@zr");
StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process);
rov.Processes.AddProcess(s);
// Set the discounting.
RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo;
rfi.ActualizationType = EActualizationType.Stochastic;
rfi.m_deterministicRF = (ModelParameter)"@V1";
OptionTree op = new OptionTree(rov);
// 1) RATE FUNCTION, with this the price is higher than the theoretical one
// op.PayoffInfo.PayoffExpression = "tau*max(rate(TT;tau;@v1) - strike; 0)";
// 2) OBTAIN RATE FROM bond = exp(-rate*t),
// with this the price is higher than the theoretical one but it's more near than 1)
// op.PayoffInfo.PayoffExpression = "tau*max(-ln(bond(TT;TT+tau;@v1))/tau - strike; 0)";
// 3) CONVERT RATE from discrete to continuous through (1+r_d) = exp(r_c)
// In this way the price is the same as the theoretical one.
op.PayoffInfo.PayoffExpression = "tau*max(ln(1+rate(TT;tau;@v1)) - strike; 0)";
op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturityOpt;
op.PayoffInfo.European = true;
rov.Map.Root = op;
rov.NMethods.Technology = ETechType.T_SIMULATION;
rov.NMethods.PathsNumber = n_sim;
rov.NMethods.SimulationSteps = n_steps;
ROVSolver solver = new ROVSolver();
solver.BindToProject(rov);
solver.DoValuation(-1);
if (rov.HasErrors)
{
Console.WriteLine(rov.m_RuntimeErrorList[0]);
}
Assert.IsFalse(rov.HasErrors);
ResultItem price = rov.m_ResultList[0] as ResultItem;
double samplePrice = price.value;
double sampleDevSt = price.stdDev / Math.Sqrt(2.0 * (double)n_sim);
// Calculation of the theoretical value of the caplet.
CapHW1 cap = new CapHW1(zerorate);
double theoreticalPrice = cap.HWCaplet(a1, sigma1, maturityOpt,
maturityOpt + tau, strike2);
Console.WriteLine("Theoretical Price = " + theoreticalPrice.ToString());
Console.WriteLine("Monte Carlo Price = " + samplePrice);
Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString());
double tol = 4.0 * sampleDevSt;
Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol);
}