using BaseOUDAL; using System.Text.RegularExpressions; using YLErp.Modules.CalculationModule; namespace YLErp.Modules.VolatilityModule.SkewMapVolModule { /// /// 从数据库中查询SkewVol /// public class SkewVolQueryService { public static volatility GetVol(int userId, SkewVolRequest req) { if (req is null) { throw new ArgumentNullException(nameof(req)); } if (string.IsNullOrWhiteSpace(req.VolType)) { throw new Exception("波动率类型不能为空"); } var userGroup = UserBLL.GetUserGroup(userId); var vols = VolatilityHelper.GetVol(req.valueDate, "交易", req.UnderlyingCode, userGroup); if (vols == null || string.IsNullOrEmpty(vols.VolSurfaceMode)) { throw new InvalidOperationException($"找不到波动率曲面{req.UnderlyingCode}"); } var singleVols = vols.VolTable; for (var i = 0; i < singleVols.Count; i++) { if (!Regex.IsMatch(singleVols[i].Expire, @"\d")) { continue; } var ExerciseDate = GetExerciseDate(req.valueDate, singleVols[i].Expire); singleVols[i].Vol = SkewMapVolHelper.GetInterpolatedVol( volSurface: vols, valueDate: req.valueDate, underlyingCode: req.UnderlyingCode, exerciseDate: ExerciseDate, strikePrice: req.Strike, isBuy: req.VolType == "报价Bid", isCall: false, spotPrice: req.Strike, skewMapVolVar: (int)(req.VolType == "报价Bid" ? vols.GetBidVar() : vols.GetAskVar()) ); } vols.Data = singleVols.ToJson(); return vols; } private static DateTime GetExerciseDate(DateTime valueDate, string term) { var result = valueDate; var m = Regex.Match(term, @"^(?\d+)(?[D|W|M|Y])$"); if (!m.Success) { return result; } var number = int.Parse(m.Groups["num"].Value); switch (m.Groups["unit"].Value) { case "D": result = result.AddDays(number); break; case "W": result = result.AddDays(number * 7); break; case "M": result = result.AddMonths(number).AddDays(-1); break; case "Y": result = result.AddYears(number).AddDays(-1); break; } return result; } } public class SkewVolRequest { public DateTime valueDate { get; set; } public string VolType { get; set; } public string UnderlyingCode { get; set; } public double Strike { get; set; } } }