93 lines
3.0 KiB
C#
93 lines
3.0 KiB
C#
using BaseOUDAL;
|
|
using System.Text.RegularExpressions;
|
|
using YLErp.Modules.CalculationModule;
|
|
|
|
namespace YLErp.Modules.VolatilityModule.SkewMapVolModule
|
|
{
|
|
/// <summary>
|
|
/// 从数据库中查询SkewVol
|
|
/// </summary>
|
|
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, @"^(?<num>\d+)(?<unit>[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; }
|
|
}
|
|
}
|