//===========================================================================//
// GFunctionWithShifts //
//===========================================================================//
public GFunctionWithShifts(CmsCoupon coupon, Handle <Quote> meanReversion)
{
meanReversion_ = meanReversion;
calibratedShift_ = 0.03;
tmpRs_ = 10000000.0;
accuracy_ = 1.0e-14;
SwapIndex swapIndex = coupon.swapIndex();
VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate());
swapRateValue_ = swap.fairRate();
objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_);
Schedule schedule = swap.fixedSchedule();
Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure();
DayCounter dc = swapIndex.dayCounter();
swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate());
discountAtStart_ = rateCurve.link.discount(schedule.startDate());
double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date());
shapedPaymentTime_ = shapeOfShift(paymentTime);
List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg());
int n = fixedLeg.Count;
shapedSwapPaymentTimes_ = new List <double>();
swapPaymentDiscounts_ = new List <double>();
accruals_ = new List <double>();
for (int i = 0; i < n; ++i)
{
Coupon coupon1 = fixedLeg[i] as Coupon;
accruals_.Add(coupon1.accrualPeriod());
Date paymentDate = new Date(coupon1.date().serialNumber());
double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate);
shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime));
swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate));
}
discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_;
}