40 {
41
42
43
44 Option::Type otmOptionType = strike < forward ? Option::Put : Option::Call;
45 Option::Type inputOptionType = inputOptionTypeOpt ? *inputOptionTypeOpt : otmOptionType;
46 Option::Type outputOptionType = outputOptionTypeOpt ? *outputOptionTypeOpt : otmOptionType;
47
48
49
50 if (inputMarketQuoteType == outputMarketQuoteType &&
close_enough(inputLognormalShift, outputLognormalShift) &&
51 inputOptionType == outputOptionType) {
52 return inputQuote;
53 }
54
55
56
57 Real forwardPremium;
63 forwardPremium =
64 bachelierBlackFormula(inputOptionType, strike, forward, inputQuote * std::sqrt(timeToExpiry));
66 if (strike < -inputLognormalShift)
67 forwardPremium = inputOptionType == Option::Call ? forward - strike : 0.0;
68 else {
69 forwardPremium = blackFormula(inputOptionType, strike, forward, inputQuote * std::sqrt(timeToExpiry),
70 1.0, inputLognormalShift);
71 }
72 } else {
73 QL_FAIL("ParametricVolatility::convert(): MarketQuoteType ("
74 << static_cast<int>(inputMarketQuoteType) << ") not handled. Internal error, contact dev.");
75 }
76 break;
77 default:
78 QL_FAIL(
"ParametricVolatility::convert(): MarketModelType (" <<
static_cast<int>(
marketModelType_)
79 << ") not handled. Internal error, contact dev.");
80 }
81
82
83
91 if (strike > -outputLognormalShift)
92 return blackFormulaImpliedStdDev(outputOptionType, strike, forward, forwardPremium, 1.0,
93 outputLognormalShift);
94 else
95 return 0.0;
96 } else {
97 QL_FAIL("ParametricVolatility::convert(): MarketQuoteType ("
98 << static_cast<int>(outputMarketQuoteType) << ") not handled. Internal error, contact dev.");
99 }
100 break;
101 }
102 default:
103 QL_FAIL(
"ParametricVolatility::convert(): MarketModelType (" <<
static_cast<int>(
marketModelType_)
104 << ") not handled. Internal error, contact dev.");
105 }
106}
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
Real exactBachelierImpliedVolatility(Option::Type optionType, Real strike, Real forward, Real tte, Real bachelierPrice, Real discount)