public double weight(double strike, double forward, double stdDev, List <double?> addParams) { if (Convert.ToDouble(addParams[1]) == 0.0) { return(Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0, addParams[0].Value)); } else { return(Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, 1.0)); } }
public double vega(double strike, double atmForward, double stdDev, double exerciseTime, double annuity, double displacement = 0.0) { return(Math.Sqrt(exerciseTime) * Utils.bachelierBlackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity)); }
public override void calculate() { double value = 0.0; double vega = 0.0; int optionlets = arguments_.startDates.Count; List <double> values = new InitializedList <double>(optionlets, 0.0); List <double> vegas = new InitializedList <double>(optionlets, 0.0); List <double> stdDevs = new InitializedList <double>(optionlets, 0.0); CapFloorType type = arguments_.type; Date today = vol_.link.referenceDate(); Date settlement = discountCurve_.link.referenceDate(); for (int i = 0; i < optionlets; ++i) { Date paymentDate = arguments_.endDates[i]; // handling of settlementDate, npvDate and includeSettlementFlows // should be implemented. // For the double being just discard expired caplets if (paymentDate > settlement) { double d = arguments_.nominals[i] * arguments_.gearings[i] * discountCurve_.link.discount(paymentDate) * arguments_.accrualTimes[i]; double forward = arguments_.forwards[i].Value; Date fixingDate = arguments_.fixingDates[i]; double sqrtTime = 0.0; if (fixingDate > today) { sqrtTime = Math.Sqrt(vol_.link.timeFromReference(fixingDate)); } if (type == CapFloorType.Cap || type == CapFloorType.Collar) { double strike = arguments_.capRates[i].Value; if (sqrtTime > 0.0) { stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike)); vegas[i] = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime; } // include caplets with past fixing date values[i] = Utils.bachelierBlackFormula(Option.Type.Call, strike, forward, stdDevs[i], d); } if (type == CapFloorType.Floor || type == CapFloorType.Collar) { double strike = arguments_.floorRates[i].Value; double floorletVega = 0.0; if (sqrtTime > 0.0) { stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike)); floorletVega = Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDevs[i], d) * sqrtTime; } double floorlet = Utils.bachelierBlackFormula(Option.Type.Put, strike, forward, stdDevs[i], d); if (type == CapFloorType.Floor) { values[i] = floorlet; vegas[i] = floorletVega; } else { // a collar is long a cap and short a floor values[i] -= floorlet; vegas[i] -= floorletVega; } } value += values[i]; vega += vegas[i]; } } results_.value = value; results_.additionalResults["vega"] = vega; results_.additionalResults["optionletsPrice"] = values; results_.additionalResults["optionletsVega"] = vegas; results_.additionalResults["optionletsAtmForward"] = arguments_.forwards; if (type != CapFloorType.Collar) { results_.additionalResults["optionletsStdDev"] = stdDevs; } }