/// <summary> /// Вернуть время между двумя датами в соответствии с заказанным алгоритмом расчета /// </summary> /// <param name="expiry">дата экспирации</param> /// <param name="now">текущая дата</param> /// <param name="tRemainMode">режим расчета</param> /// <param name="returnDays">возвращать в долях года или в долях дней</param> /// <param name="timeAsDays">время в долях дня</param> /// <param name="timeAsYears">время в долях года</param> /// <returns>время между двумя датами</returns> public static double GetDt(DateTime expiry, DateTime now, TimeRemainMode tRemainMode, bool returnDays, out double timeAsDays, out double timeAsYears) { double days, daysInYear; double partOfDayForTrading; switch (tRemainMode) { case TimeRemainMode.PlainCalendar: { TimeSpan ts = expiry - now; days = ts.TotalDays; partOfDayForTrading = 1; daysInYear = DaysInYearPlainCalendar; } break; case TimeRemainMode.PlainCalendarWithoutWeekends: { TimeSpan ts = OptionUtils.GetDtWithoutWeekendsSlow(expiry, now); days = ts.TotalDays; partOfDayForTrading = 1; daysInYear = DaysInYearPlainCalendarWithoutWeekends; } break; case TimeRemainMode.PlainCalendarWithoutHolidays: { TimeSpan ts = OptionUtils.GetDtWithoutHolidaysSlow(expiry, now); days = ts.TotalDays; partOfDayForTrading = 1; daysInYear = DaysInYearPlainCalendarWithoutHolidays; } break; case TimeRemainMode.RtsTradingTime: { TimeSpan ts = OptionUtils.GetDtRtsTradingTime(expiry, now); days = ts.TotalDays; partOfDayForTrading = ((double)OptionUtils.TradingMinutesInDayRts) / (double)OptionUtils.MinutesInDay; daysInYear = DaysInYearRts; } break; case TimeRemainMode.LiquidProRtsTradingTime: { double tradingDaysInYear; double dT = OptionUtils.GetDtLiquidProRtsTradingTime(expiry, now, out tradingDaysInYear); timeAsDays = dT * tradingDaysInYear; timeAsYears = dT; if (returnDays) { return(timeAsDays); } else { return(timeAsYears); } } //break; default: throw new NotImplementedException("tRemainMode:" + tRemainMode); } timeAsDays = days / partOfDayForTrading; timeAsYears = days / daysInYear; if (returnDays) { return(timeAsDays); } else { return(timeAsYears); } }
protected override IEnumerable <Double2> Calculate(IOptionStrike[] strikes) { var bidList = new List <Double2>(); var finArray = new Dictionary <double, StrikeInfo>(); foreach (var optionStrike in strikes) { if (!finArray.ContainsKey(optionStrike.Strike)) { var lastUpdate = optionStrike.FinInfo.LastUpdate; if (lastUpdate == DateTime.MinValue) { continue; } var stInfo = new StrikeInfo { ExpDate = OptionUtils.YearsBetweenDates(optionStrike.ExpirationDate, lastUpdate), BasePrice = optionStrike.UnderlyingAsset.FinInfo.LastPrice ?? 0 }; FillStrikeInfo(optionStrike, stInfo); finArray.Add(optionStrike.Strike, stInfo); } else { var key = optionStrike.Strike; var stInfo = finArray[key]; FillStrikeInfo(optionStrike, stInfo); } } // выход, пустой список if (finArray.Count == 0) { return(bidList); } // расчет волатильностей foreach (var strikeInfo in finArray) { double precision; var callSigma = (strikeInfo.Value.Call != 0.0) ? FinMath.GetOptionSigma(strikeInfo.Value.BasePrice, strikeInfo.Key, strikeInfo.Value.ExpDate, strikeInfo.Value.Call, 0.0, true, out precision) : 0; var putSigma = (strikeInfo.Value.Put != 0.0) ? FinMath.GetOptionSigma(strikeInfo.Value.BasePrice, strikeInfo.Key, strikeInfo.Value.ExpDate, strikeInfo.Value.Put, 0.0, false, out precision) : 0; strikeInfo.Value.CallSigma = callSigma; strikeInfo.Value.PutSigma = putSigma; if (putSigma == 0 && callSigma == 0) { continue; } // добавим значение bidList.Add(new Double2 { V1 = strikeInfo.Key, V2 = Math.Max(callSigma, putSigma) * 100.0 }); } return(bidList); }