using Newtonsoft.Json; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using YLErp.Abstract; using YLErp.Models; namespace YLErp.DBModels { [Table("volatility")] public class volatility : DBModelWithOperator, IVolatility, IDataTraceV2, IClonable { public static string LogClass = "波动率信息"; /// /// Bid偏移量 /// [NotMapped] public double? Bid_Deviation { get; set; } /// /// Ask偏移量 /// [NotMapped] public double? Ask_Deviation { get; set; } /// /// 波动率表格 /// [NotMapped] public List VolTable { get { if ((_volTable == null || _volTable.Count == 0) && !string.IsNullOrWhiteSpace(_data)) { _volTable = JsonConvert.DeserializeObject>(_data); } return _volTable; } set { //api/v1/saveVolatility 需要用到此字段的反序列化 _volTable = value; _data = JsonHelper.Serialize(_volTable); } } [DisplayName("插值方法")] public string InterpolationMethod { get; set; } [DisplayName("波动率模式")] public string VolSurfaceMode { get; set; } private string _data; private string userGroup = string.Empty; private List _volTable; [DisplayName("波动率表格数据")] public string Data { get { return _data; } set { _data = value; _volTable = null; } } [DisplayName("波动率类型")] public string VolType { get; set; } /// /// /// [DisplayName("UnderlyingId")] public int? UnderlyingId { set; get; } /// /// 报价日期 /// [DisplayName("报价日期")] public DateTime QuotationDate { set; get; } /// /// 合约代码 /// [DisplayName("合约代码"), Required] public string ContractCode { set; get; } /// /// 所属用户组 /// [Required(AllowEmptyStrings = true)] public string UserGroup { get { return userGroup; } set { userGroup = value ?? string.Empty; } } /// /// 审核波动率下限 /// public double ReviewDownLimit { get; set; } /// /// 审核波动率上限 /// public double ReviewUpLimit { get; set; } public volatility Clone() { return (volatility)MemberwiseClone(); } public volatility Clone(DateTime QuotationDate) { var clone = (volatility)MemberwiseClone(); clone.QuotationDate = QuotationDate; return clone; } public volatility Clone(string volType) { var clone = (volatility)MemberwiseClone(); clone.VolType = volType ?? throw new ArgumentNullException(nameof(volType)); return clone; } public override string ToString() { return $"{ContractCode}--{QuotationDate}--{VolType}--{VolSurfaceMode}"; } public string GetDataTraceKeyId() { return $"{id},{ContractCode},{VolType}"; } /// /// 通过此方式设置波动率Data字段值,用于避免波动率为0.3但是存入数据库时是0.29999.. /// public void SetData(IEnumerable VolTable) { if (VolTable is null) { throw new ArgumentNullException(nameof(VolTable)); } Data = JsonConvert.SerializeObject(VolTable, new SingleVolJsonConverter()); } /// /// skewmap模式下的ask var /// public double? GetAskVar() { return VolTable?.LastOrDefault(n => n.Expire == "AskVar")?.Vol; } /// /// skewmap模式下的bid var /// public double? GetBidVar() { return VolTable?.LastOrDefault(n => n.Expire == "BidVar")?.Vol; } public string GetDataTraceKeyInfo() { return VolType + "波动率:" + ContractCode; } class SingleVolJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var obj = (SingleVol)value; writer.WriteStartObject(); writer.WritePropertyName(nameof(SingleVol.Expire)); writer.WriteValue(obj.Expire); writer.WritePropertyName(nameof(SingleVol.Strike)); writer.WriteValue(Convert.ToDecimal(obj.Strike.ToString("0.0#####"))); //if (double.IsNaN(obj.Vol)) writer.WritePropertyName(nameof(SingleVol.Vol)); writer.WriteValue(Convert.ToDecimal(obj.Vol.ToString("0.0#####"))); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanRead { get { return false; } } public override bool CanConvert(Type objectType) { return objectType == typeof(SingleVol); } } } [NotMapped] public class VolatilityDto : volatility { } /// /// 专用于默认波动率(0.3) /// [NotMapped] public class VolatilityDefault : volatility { } }