//! rerun every time instruments/referenceDate changes internal virtual void init() { // yield conventions DayCounter yieldDC = curve_.dayCounter(); Compounding yieldComp = Compounding.Compounded; Frequency yieldFreq = Frequency.Annual; int n = curve_.bondHelpers_.Count; costFunction_ = new FittingCost(this); costFunction_.firstCashFlow_ = new InitializedList <int>(n); for (int i = 0; i < curve_.bondHelpers_.Count; ++i) { Bond bond = curve_.bondHelpers_[i].bond(); List <CashFlow> cf = bond.cashflows(); Date bondSettlement = bond.settlementDate(); for (int k = 0; k < cf.Count; ++k) { if (!cf[k].hasOccurred(bondSettlement, false)) { costFunction_.firstCashFlow_[i] = k; break; } } } if (calculateWeights_) { //if (weights_.empty()) weights_ = new Vector(n); double squaredSum = 0.0; for (int i = 0; i < curve_.bondHelpers_.Count; ++i) { Bond bond = curve_.bondHelpers_[i].bond(); double cleanPrice = curve_.bondHelpers_[i].quote().link.value(); Date bondSettlement = bond.settlementDate(); double ytm = BondFunctions.yield(bond, cleanPrice, yieldDC, yieldComp, yieldFreq, bondSettlement); double dur = BondFunctions.duration(bond, ytm, yieldDC, yieldComp, yieldFreq, Duration.Type.Modified, bondSettlement); weights_[i] = 1.0 / dur; squaredSum += weights_[i] * weights_[i]; } weights_ /= Math.Sqrt(squaredSum); } Utils.QL_REQUIRE(weights_.size() == n, () => "Given weights do not cover all boostrapping helpers"); }
// curve optimization called here- adjust optimization parameters here internal void calculate() { FittingCost costFunction = costFunction_; Constraint constraint = new NoConstraint(); // start with the guess solution, if it exists Vector x = new Vector(size(), 0.0); if (!curve_.guessSolution_.empty()) { x = curve_.guessSolution_; } if (curve_.maxEvaluations_ == 0) { //Don't calculate, simply use given parameters to provide a fitted curve. //This turns the fittedbonddiscountcurve into an evaluator of the parametric //curve, for example allowing to use the parameters for a credit spread curve //calculated with bonds in one currency to be coupled to a discount curve in //another currency. return; } //workaround for backwards compatibility OptimizationMethod optimization = optimizationMethod_; if (optimization == null) { optimization = new Simplex(curve_.simplexLambda_); } Problem problem = new Problem(costFunction, constraint, x); double rootEpsilon = curve_.accuracy_; double functionEpsilon = curve_.accuracy_; double gradientNormEpsilon = curve_.accuracy_; EndCriteria endCriteria = new EndCriteria(curve_.maxEvaluations_, curve_.maxStationaryStateIterations_, rootEpsilon, functionEpsilon, gradientNormEpsilon); optimization.minimize(problem, endCriteria); solution_ = problem.currentValue(); numberOfIterations_ = problem.functionEvaluation(); costValue_ = problem.functionValue(); // save the results as the guess solution, in case of recalculation curve_.guessSolution_ = solution_; }