110 {
111
114
115
116
117 if (swaptionVolatility()->volatilityType() == ShiftedLognormal) {
118 effectiveLowerIntegrationBound = std::max(
120 }
121
122
123
124 if (optionType == Option::Call)
125 effectiveLowerIntegrationBound = std::max(effectiveLowerIntegrationBound, strike);
126 else
127 effectiveUpperIntegrationBound = std::min(effectiveUpperIntegrationBound, strike);
128
130 Real omega = optionType == Option::Call ? 1.0 : -1.0;
131
132
133
134 if (effectiveLowerIntegrationBound < effectiveUpperIntegrationBound &&
135 !
close_enough(effectiveLowerIntegrationBound, effectiveUpperIntegrationBound)) {
136
137 auto f = [this, strike, omega](const Real S) -> Real {
139 };
140
141 auto fp = [this, strike, omega](const Real S) -> Real {
143 return omega * (omega * S > omega * strike ? 1.0 : 0.0);
144 } else {
145 Real dp = 0.0;
147 dp -=
static_cast<Real
>(i + 1) / std::pow(1.0 + this->
swapRate_, i + 2);
148 }
150 dp * std::max(omega * (S - strike), 0.0);
151 }
152 };
153
154 auto fpp = [this, strike, omega](const Real S) -> Real {
156 return 0.0;
157 } else {
158 Real dp1 = 0.0, dp2 = 0.0;
160 dp1 -=
static_cast<Real
>(i + 1) / std::pow(1.0 + this->
swapRate_, i + 2);
161 dp2 +=
static_cast<Real
>(i + 1) *
static_cast<Real
>(i + 2) / std::pow(1.0 + this->
swapRate_, i + 3);
162 }
163 return dp1 * omega * (omega * S > omega * strike ? 1.0 : 0.0) +
164 dp2 * std::max(omega * (S - strike), 0.0);
165 }
166 };
167
168 auto integrand = [this, &f, &fp, &fpp](const Real S) -> Real {
169 Real f2 = 0.0;
172 }
174 Real f0 = 0.0;
178 };
179
180
181 Real tmpBound;
182 tmpBound = std::min(effectiveUpperIntegrationBound,
swapRate_);
183 if (tmpBound > effectiveLowerIntegrationBound)
184 integral += (*integrator_)(integrand, effectiveLowerIntegrationBound, tmpBound);
185 tmpBound = std::max(effectiveLowerIntegrationBound,
swapRate_);
186 if (effectiveUpperIntegrationBound > tmpBound)
187 integral += (*integrator_)(integrand, tmpBound, effectiveUpperIntegrationBound);
188
189 integral = (*integrator_)(integrand, effectiveLowerIntegrationBound, effectiveUpperIntegrationBound);
190 }
191
192
193
194 Real singularTerms =
198
200}
Real integral(const CrossAssetModel &model, const E &e, const Real a, const Real b)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)