17 using MathNet.Numerics.RootFinding;
34 private decimal _impliedVolatility;
35 private Func<decimal, decimal, decimal> SmoothingFunction;
54 : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, period)
62 Convert.ToDecimal(Math.Sqrt(252))
65 _consolidator =
new(TimeSpan.FromDays(1));
66 _consolidator.DataConsolidated += (_, bar) => {
67 _roc.Update(bar.EndTime, bar.Price);
70 if (mirrorOption !=
null)
76 SmoothingFunction = (impliedVol, mirrorImpliedVol) =>
80 return mirrorImpliedVol;
84 return mirrorImpliedVol;
102 : this($
"IV({option},{mirrorOption},{riskFreeRateModel},{dividendYieldModel},{optionModel},{period})", option, riskFreeRateModel,
103 dividendYieldModel, mirrorOption, optionModel, period)
135 : this($
"IV({option},{mirrorOption},{riskFreeRateModel},{dividendYieldModel},{optionModel},{period})", option,
136 riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, period)
167 : this($
"IV({option},{mirrorOption},{riskFreeRateModel},{dividendYield},{optionModel},{period})", option, riskFreeRateModel, dividendYield,
168 mirrorOption, optionModel, period)
200 : this($
"IV({option},{mirrorOption},{riskFreeRateModel},{dividendYield},{optionModel},{period})", option, riskFreeRateModel,
201 dividendYield, mirrorOption, optionModel, period)
232 : this($
"IV({option},{mirrorOption},{riskFreeRate},{dividendYield},{optionModel},{period})", option, riskFreeRate,
233 dividendYield, mirrorOption, optionModel, period)
243 SmoothingFunction =
function;
252 SmoothingFunction =
PythonUtil.ToFunc<decimal, decimal, decimal>(
function);
279 _consolidator.Update(input);
284 throw new ArgumentException(
"The given symbol was not target or reference symbol");
287 var time =
Price.Current.Time;
294 return _impliedVolatility;
301 var timeTillExpiry = Convert.ToDecimal((
Expiry - time).TotalDays) / 365m;
305 return _impliedVolatility;
309 private decimal TheoreticalPrice(decimal volatility, decimal spotPrice, decimal strikePrice, decimal timeTillExpiry, decimal riskFreeRate,
312 if (timeTillExpiry <= 0m)
317 return optionModel
switch
320 OptionPricingModelType.BinomialCoxRossRubinstein => OptionGreekIndicatorsHelper.CRRTheoreticalPrice(volatility, spotPrice, strikePrice, timeTillExpiry, riskFreeRate, dividendYield, optionType),
321 OptionPricingModelType.ForwardTree => OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(volatility, spotPrice, strikePrice, timeTillExpiry, riskFreeRate, dividendYield, optionType),
322 _ => OptionGreekIndicatorsHelper.BlackTheoreticalPrice(volatility, spotPrice, strikePrice, timeTillExpiry, riskFreeRate, dividendYield, optionType),
336 Func<double, double> f = (vol) => (
double)(TheoreticalPrice(
338 impliedVol = Convert.ToDecimal(Brent.FindRoot(f, 1e-7d, 2.0d, 1e-4d, 100));
342 Log.
Error(
"ImpliedVolatility.CalculateIV(): Fail to converge, returning 0.");
347 var mirrorImpliedVol = 0m;
350 Func<double, double> f = (vol) => (
double)(TheoreticalPrice(
352 mirrorImpliedVol = Convert.ToDecimal(Brent.FindRoot(f, 1e-7d, 2.0d, 1e-4d, 100));
356 Log.
Error(
"ImpliedVolatility.CalculateIV(): Fail to converge, returning 0.");
359 return SmoothingFunction(impliedVol, mirrorImpliedVol);
370 _consolidator.Dispose();
371 _consolidator =
new(TimeSpan.FromDays(1));
372 _consolidator.DataConsolidated += (_, bar) => {
373 _roc.Update(bar.EndTime, bar.Price);