157 lines
5.7 KiB
C#
157 lines
5.7 KiB
C#
using System.Reflection;
|
|
|
|
namespace YLErp.Modules.ApiModule.PricingModule
|
|
{
|
|
/// <summary>
|
|
/// OptionPricingApiHelper
|
|
/// </summary>
|
|
public static class OptionPricingApiHelper
|
|
{
|
|
static readonly Dictionary<string, (Func<string, object> valueConv, Action<OptionPricingModelV2, object> valueSet)> _dic;
|
|
|
|
static OptionPricingApiHelper()
|
|
{
|
|
_dic = new Dictionary<string, (Func<string, object> valueConv, Action<OptionPricingModelV2, object> valueSet)>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据模型属性名设置属性值
|
|
/// </summary>
|
|
public static void SetValueByPropName(OptionPricingModelV2 model, string propName, string value)
|
|
{
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_dic.TryGetValue(propName, out var tuple))
|
|
{
|
|
Func<string, object> 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));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查请求数据是否正确
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|