using System.Reflection; namespace YLErp.Modules.ApiModule.PricingModule { /// /// OptionPricingApiHelper /// public static class OptionPricingApiHelper { static readonly Dictionary valueConv, Action valueSet)> _dic; static OptionPricingApiHelper() { _dic = new Dictionary valueConv, Action valueSet)>(StringComparer.OrdinalIgnoreCase); } /// /// 根据模型属性名设置属性值 /// public static void SetValueByPropName(OptionPricingModelV2 model, string propName, string value) { if (string.IsNullOrEmpty(value)) { return; } if (!_dic.TryGetValue(propName, out var tuple)) { Func valueConv = null; var prop = typeof(OptionPricingModelV2).GetProperty(propName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.SetProperty); if (prop != null) { if (prop.PropertyType == typeof(string)) { valueConv = s => s; } else if (prop.PropertyType == typeof(int) || prop.PropertyType.IsEnum || prop.PropertyType == typeof(int?)) { valueConv = s => int.TryParse(s, out var n) ? (object)n : throw new ServiceException("参数值不符合要求,参数名:" + propName); } else if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?)) { valueConv = s => double.TryParse(s, out var d) ? (object)d : throw new ServiceException("参数值不符合要求,参数名:" + propName); } else if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?)) { valueConv = s => s == "true"; } else if (prop.PropertyType == typeof(DateTime) || prop.PropertyType == typeof(DateTime?)) { valueConv = s => DateTime.TryParse(s, out var d) ? (object)d : throw new ServiceException("参数值不符合要求,参数名:" + propName); } else { System.Diagnostics.Debug.WriteLine("!!!ExtendSetter:没有处理值转换:" + propName); } } else { System.Diagnostics.Debug.WriteLine("!!!ExtendSetter:没有找到对应属性信息:" + propName); } _dic[propName] = tuple = (valueConv, (m, o) => prop?.SetValue(m, o)); } if (tuple.valueConv != null) { tuple.valueSet(model, tuple.valueConv(value)); } } /// /// 检查请求数据是否正确 /// public static void CheckPricingRequestData(OptionPricingModelV2 req) { if (req == null) { throw new ServiceException("参数为null"); } if (string.IsNullOrEmpty(req.UnderlyingCode)) { throw new ServiceException("缺少标的代码"); } var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode); if (underlying == null) { throw new ServiceException("没有找到标的信息:" + req.UnderlyingCode); } if (!req.MaturityDate.HasValue || req.MaturityDate.Value == default) { req.MaturityDate = req.ExerciseDate; } req.UnderlyingId = underlying.id; req.UnderlyingAssetClass = underlying.UnderlyingType; req.UnderlyingAssetName = underlying.UnderlyingName; req.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType; if (req.Notional <= 0) { throw new ServiceException("持仓份额必须大于0"); } if (req.TradeType != "香草期权" && req.ExtendFields != null && req.ExtendFields.Count > 0) { foreach (var kv in req.ExtendFields) { OptionPricingApiHelper.SetValueByPropName(req, kv.Key, kv.Value); } var isAutoCall = req.TradeType == "雪球期权" || req.TradeType == "凤凰期权"; if (isAutoCall) { req.Strike = req.SpreadStrike1; } if (!req.IsAnnualized) { req.AnnualizeFactor = 1; if (isAutoCall) { req.IsAnnualized2 = false; req.AnnualizeFactor2 = 1; } } else if (isAutoCall) { req.IsAnnualized2 = true; req.AnnualizeFactor2 = req.AnnualizeFactor; req.IsAnnualized = false; req.AnnualizeFactor = 1; } } //检查并尽可能修复数据 req.CheckAndRepairValues(); if (!req.VolValue.HasValue) { req.VolValue = 0.3; } req.Vol = req.VolValue; } } }