Files
zszq-trs/YLErpUnitTest/Modules/MarginModule/MarginCalculation/GDGZMarginCalculation.cs
T
2024-05-09 14:06:26 +08:00

609 lines
34 KiB
C#

//using BaseOUDAL;
//using Qdp.Foundation.Implementations;
//using Qdp.Pricing.Base.Implementations;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using YLErp.BLL.Calculation.V2;
//using YLErp.Commons;
//using YLErp.DBModels;
//using YLErp.DBModels.Consts;
//using YLErp.Model;
//using YLErp.Modules.DataCacheModule;
//using YLErp.Modules.VolatilityModule;
//using YLErp.Modules.VolatilityModule.SkewMapVolModule;
//using YLErp.QdpModule;
//using CalculatorHelper = YLErp.BLL.Calculation.CalculatorHelperOld;
//namespace YLErp.BLL.MarginCalculationBak
//{
// public class GDGZMarginCalculation : MarginCalculationBase
// {
// // 定义一个静态变量来保存类的实例(单例模式)
// public static readonly GDGZMarginCalculation Instance;
// static GDGZMarginCalculation()
// {
// Instance = new GDGZMarginCalculation();
// }
// // 定义私有构造函数,使外界不能创建该类实例
// private GDGZMarginCalculation()
// {
// }
// public override List<trade_span> RunMarginCalculation(int userId, string userName, List<trade> tradeList, DateTime settleDate, Dictionary<int, double> priceDict, bool hasOptionInfo = false, bool isEodSettle = false, bool forSingleTrade = true, string volType = "交易", bool forOtherSide = false)
// {
// //结果集
// Dictionary<int, trade_span> resultMap = new Dictionary<int, trade_span>();
// using (YLContext db = new YLContext())
// {
// //为了算客户角度的一个保证金数值
// if (forOtherSide)
// {
// tradeList.ForEach(x => x.BuySell = x.BuySell == "买入" ? "卖出" : "买入");
// }
// if (!(priceDict?.Count > 0))
// {
// var codes = tradeList.Select(O => O.UnderlyingCode).ToArray();
// priceDict = base.GetSettlePrice(codes, settleDate);
// }
// if (priceDict.Count == 0)
// {
// //如果价格没有传入也没从数据库获取到,就直接返回,没必要往下运行了。但不应该报错;
// return resultMap.Values.ToList();
// }
// var underlyingIds = priceDict.Keys.ToList();
// //获取标的涨跌幅限制
// var umDatas = (from um in db.underlying_manager
// join variety in db.variety on um.CommodityCode equals variety.VarietyCode
// where underlyingIds.Contains(um.id)
// select new
// {
// um.id,
// um.VolatilityRate,
// um.UpDownLimit,
// defUpLimit = variety.UpLimit,
// defDownLimit = variety.DownLimit,
// defVolatilityRate = variety.VolatilityRate
// }).ToList();
// var UpLimitDict = new Dictionary<int, string>();
// var DownLimitDict = new Dictionary<int, string>();
// var umVolatilityRateDic = new Dictionary<int, double>();
// if (umDatas != null && umDatas.Count > 0)
// {
// umDatas.ForEach(t =>
// {
// //OTC-8856 Start
// //1.波动率变化
// if (DataConvert.TryParsePercentValue(t.VolatilityRate, out double pvalue) && (Math.Abs(pvalue) >= 1e-5))
// {
// umVolatilityRateDic[t.id] = pvalue;
// }
// else if (DataConvert.TryParsePercentValue(t.defVolatilityRate, out pvalue) && (Math.Abs(pvalue) >= 1e-5))
// {
// umVolatilityRateDic[t.id] = pvalue;
// }
// //2.涨跌停板幅度
// if (!string.IsNullOrWhiteSpace(t.UpDownLimit))
// {
// UpLimitDict[t.id] = t.UpDownLimit;//百分比或绝对值
// DownLimitDict[t.id] = t.UpDownLimit;
// }
// else
// {
// UpLimitDict[t.id] = t.defUpLimit?.ToString() ?? "5%";
// DownLimitDict[t.id] = t.defDownLimit?.ToString() ?? "5%";
// }
// });
// }
// if (!hasOptionInfo)
// {
// tradeBLL.SetFieldsByTradeType(tradeList);
// }
// var tradeVolatilityRateDic = tradeList.ToDictionary(t => t.id, t => umVolatilityRateDic.ContainsKey(t.UnderlyingId) ? umVolatilityRateDic[t.UnderlyingId] : 0)
// .Where(d => d.Value > 0).ToDictionary(d => d.Key, d => d.Value);
// Dictionary<string, Dictionary<int, double>> eodPriceDict = new Dictionary<string, Dictionary<int, double>>();
// var upLimitPrices = new Dictionary<int, double>();
// var downLimitPrices = new Dictionary<int, double>();
// double tempDouble;
// //根据涨跌幅限制以及当日结算价计算涨停价以及跌停价
// foreach (var t in priceDict)
// {
// //OTC-8856 Start
// //UpLimit
// if (UpLimitDict.ContainsKey(t.Key))
// {
// var tempVaue = UpLimitDict[t.Key];
// if (tempVaue.Contains("%"))
// {
// //百分比
// double.TryParse(tempVaue.Replace("%", ""), out tempDouble);
// upLimitPrices[t.Key] = t.Value * (1 + (tempDouble * 0.01));
// }
// else
// {
// //绝对值
// double.TryParse(tempVaue, out double tempAbs);
// upLimitPrices[t.Key] = t.Value + Math.Abs(tempAbs);
// }
// }
// else
// {
// upLimitPrices[t.Key] = t.Value * 1.05;
// }
// //DownLimit
// if (DownLimitDict.ContainsKey(t.Key))
// {
// var tempVaue = DownLimitDict[t.Key];
// if (tempVaue.Contains("%"))
// {
// //百分比
// double.TryParse(tempVaue.Replace("%", ""), out tempDouble);
// downLimitPrices[t.Key] = t.Value * (1 - (tempDouble * 0.01));
// }
// else
// {
// //绝对值
// double.TryParse(tempVaue, out double tempAbs);
// downLimitPrices[t.Key] = t.Value - Math.Abs(tempAbs);
// }
// }
// else
// {
// downLimitPrices[t.Key] = t.Value * 0.95;
// }
// //End
// }
// eodPriceDict["up"] = upLimitPrices;
// eodPriceDict["down"] = downLimitPrices;
// //波动率变化
// var addVolRateList = new List<Dictionary<int, double>> { null, tradeVolatilityRateDic };
// //交易对应客户信息
// var clientIds = tradeList.Select(t => t.ClientId).ToList();
// var clientList = (from client in db.client
// join clientlevel in db.clientlevel
// on client.LevelId equals clientlevel.id into tempClientlevel
// from clientlevelTT in tempClientlevel.DefaultIfEmpty()
// where clientIds.Contains(client.id)
// select new
// {
// client,
// clientlevel = clientlevelTT
// }).ToList();
// var userIdNew = UniqueTimeId.Get().ToString();
// try
// {
// foreach (var price in eodPriceDict)
// {
// addVolRateList.ForEach(addVolRateDic =>
// {
// var key = $"{price.Key}_{(addVolRateDic == null ? 0 : 1)}";
// var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(
// userIdNew, // userId + "_" + price.Key,
// settleDate,
// tradeList,
// price.Value,
// ValueCalculator.PV_ONLY,
// addVolRateDic,
// isEodSettle,
// volType,
// isUseTradeVol: PS.Config.IsTradeVol,
// PreciseTimeMode: !isEodSettle,
// isAddVolPercent: false);
// if (tradeRiskResult.Results != null && tradeRiskResult.Results.Count > 0)
// {
// foreach (var item in tradeRiskResult.Results)
// {
// var client = clientList.FirstOrDefault(c => c.client.id == item.Trade.ClientId);
// var clientRatio = client == null ? 1.0 : (client.clientlevel == null ? 1.0 : (client.clientlevel.Ratio ?? 1.0));
// var noMinusPv = !PS.Config.ErpElement.TwoSideMargin || client == null || client.client == null || client.client.HasTwoSideMargin != 1;
// double value = 0;
// if (item.Trade.TradeType == "自定义交易")
// {
// var eodTradeRiskManual = db.eod_trade_risk_manual.Where(x => x.ValueDate <= settleDate && x.TradeId == item.Trade.id).OrderByDescending(x => x.ValueDate).FirstOrDefault();
// //收盘时如果自定义交易还活着且没有维护当日风险,并且收的时系统日期当日的盘,抛出exception
// if (isEodSettle && !ConsTrade.TradeCompleteStatus.Contains(item.Trade.TradeStatus) && settleDate == valuedateBLL.SystemDate.ValueDate)
// {
// if (eodTradeRiskManual == null || eodTradeRiskManual.ValueDate != settleDate)
// {
// var error = $"TradeNumber:{item.Trade.TradeNumber}在{settleDate.ToString("yyyy-MM-dd")}需先进行交易风险维护";
// throw new Exception(error);
// }
// }
// value = eodTradeRiskManual?.Margin ?? 0;
// }
// if (resultMap.ContainsKey(item.Trade.id))
// {
// switch (key)
// {
// case "up_0":
// resultMap[item.Trade.id].Spv1 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "up_1":
// resultMap[item.Trade.id].Spv2 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "down_0":
// resultMap[item.Trade.id].Spv3 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "down_1":
// resultMap[item.Trade.id].Spv4 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// default:
// break;
// }
// //非双向保证金,pv为负的情况置为0
// if (noMinusPv)
// {
// resultMap[item.Trade.id].Spv1 = Math.Max(resultMap[item.Trade.id].Spv1 ?? 0, 0);
// resultMap[item.Trade.id].Spv2 = Math.Max(resultMap[item.Trade.id].Spv2 ?? 0, 0);
// resultMap[item.Trade.id].Spv3 = Math.Max(resultMap[item.Trade.id].Spv3 ?? 0, 0);
// resultMap[item.Trade.id].Spv4 = Math.Max(resultMap[item.Trade.id].Spv4 ?? 0, 0);
// }
// resultMap[item.Trade.id].setWorstCastClientPayable4();
// }
// else
// {
// var trade = tradeList.FirstOrDefault(t => t.id == item.Trade.id);
// var tempTradeSpan = new trade_span
// {
// TradeId = item.Trade.id,
// ClientId = trade.ClientId,
// ValueDate = settleDate,
// UnderlyingId = trade.UnderlyingId,
// UnderlyingCode = trade.UnderlyingCode,
// OptId = userId,
// OptName = userName,
// OptDate = DateTime.Now
// };
// switch (key)
// {
// case "up_0":
// tempTradeSpan.Spv1 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "up_1":
// tempTradeSpan.Spv2 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "down_0":
// tempTradeSpan.Spv3 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// case "down_1":
// tempTradeSpan.Spv4 = item.Trade.TradeType == "自定义交易" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
// break;
// default:
// break;
// }
// //非双向保证金,pv为负的情况置为0
// if (noMinusPv)
// {
// tempTradeSpan.Spv1 = Math.Max(tempTradeSpan.Spv1 ?? 0, 0);
// tempTradeSpan.Spv2 = Math.Max(tempTradeSpan.Spv2 ?? 0, 0);
// tempTradeSpan.Spv3 = Math.Max(tempTradeSpan.Spv3 ?? 0, 0);
// tempTradeSpan.Spv4 = Math.Max(tempTradeSpan.Spv4 ?? 0, 0);
// }
// resultMap[item.Trade.id] = tempTradeSpan;
// }
// }
// }
// });
// }
// }
// finally
// {
// //上面的计算用到静态生成market,需要清除
// QdpMarketManager.Instance.RemovePrebuiltMarketProxy(userIdNew);
// }
// //为了保持原有交易买卖方向不变
// if (forOtherSide)
// {
// tradeList.ForEach(x => x.BuySell = x.BuySell == "买入" ? "卖出" : "买入");
// }
// return resultMap.Values.ToList();
// }
// }
// public override bool CalcClientMargin(int userId, string userName, DateTime settleDate, List<trade_span> tradeSpans, List<trade_span> tradeSpansOtherSide, int SpanType = 0, List<int> RefreshClientIds = null, bool OnlyBuyer = false, Dictionary<int, double> clientAdditionalMarginDic = null)
// {
// using (YLContext db = new YLContext())
// {
// //删除
// if (tradeSpans != null && tradeSpans.Count > 0)
// {
// var tradeIds = tradeSpans.Select(t => t.TradeId).ToList();
// var tradeList = db.trade.AsNoTracking().Where(t => tradeIds.Contains(t.id)).ToList();
// var clientIds = tradeSpans.Select(t => t.ClientId).Distinct().ToList();
// var clientList = db.client.Where(x => clientIds.Contains(x.id)).ToList();
// var tradeSpanInfo = (from tradeSpan in tradeSpans
// join
// trade in tradeList on tradeSpan.TradeId equals trade.id
// where tradeSpan.ValueDate == settleDate
// select new { trade, tradeSpan }).ToList();
// var clientSpanNews = new List<client_span>();
// var clientGroups = tradeSpanInfo.GroupBy(t => t.trade.ClientId);
// foreach (var clientGroup in clientGroups)
// {
// var underlyingGroup = clientGroup.GroupBy(t => t.trade.UnderlyingId).Select(t => new client_span
// {
// UnderlyingId = t.Key,
// ClientId = clientGroup.Key,
// ValueDate = settleDate,
// Spv1 = t.Sum(g => g.tradeSpan.Spv1) * (-1),
// Spv2 = t.Sum(g => g.tradeSpan.Spv2) * (-1),
// Spv3 = t.Sum(g => g.tradeSpan.Spv3) * (-1),
// Spv4 = t.Sum(g => g.tradeSpan.Spv4) * (-1),
// OptId = userId,
// OptName = userName,
// OptDate = DateTime.Now,
// SpanType = SpanType
// }).ToList();
// foreach (var item in underlyingGroup)
// {
// item.WorstCastClientPayable = Math.Min(Math.Min(Math.Min(item.Spv1 ?? 0, item.Spv2 ?? 0), item.Spv3 ?? 0), item.Spv4 ?? 0);
// item.TwoSideMargin = Math.Min(Math.Min(Math.Min(item.Spv1 ?? 0, item.Spv2 ?? 0), item.Spv3 ?? 0), item.Spv4 ?? 0);
// #region 更新tradeSpan,使得每笔交易的持仓保证金和客户保证金计算用的Spv组保持一致
// var tradeSpansUpdate = db.trade_span.Where(x => x.ClientId == item.ClientId && x.UnderlyingId == item.UnderlyingId && x.ValueDate == settleDate).ToList();
// if (item.WorstCastClientPayable == item.Spv1)
// {
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv1);
// }
// else if (item.WorstCastClientPayable == item.Spv2)
// {
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv2);
// }
// else if (item.WorstCastClientPayable == item.Spv3)
// {
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv3);
// }
// else
// {
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv4);
// }
// #endregion
// if (!PS.Config.ErpElement.TwoSideMargin || clientList.FirstOrDefault(x => x.id == clientGroup.Key) == null || clientList.FirstOrDefault(x => x.id == clientGroup.Key).HasTwoSideMargin != 1)
// {
// item.WorstCastClientPayable = Math.Min(item.WorstCastClientPayable.Value, 0);
// }
// }
// var clientSpan = new client_span
// {
// ClientId = clientGroup.Key,
// ValueDate = settleDate,
// Spv1 = underlyingGroup.Sum(g => g.Spv1),
// Spv2 = underlyingGroup.Sum(g => g.Spv2),
// Spv3 = underlyingGroup.Sum(g => g.Spv3),
// Spv4 = underlyingGroup.Sum(g => g.Spv4),
// //负数代表客户应缴保证金,正数代表客户应收保证金
// WorstCastClientPayable = (PS.Config.ErpElement.TwoSideMargin && clientList.FirstOrDefault(x => x.id == clientGroup.Key) != null && clientList.FirstOrDefault(x => x.id == clientGroup.Key).HasTwoSideMargin == 1) ? underlyingGroup.Sum(g => g.WorstCastClientPayable) : underlyingGroup.Sum(g => g.WorstCastClientPayable) < 0 ? underlyingGroup.Sum(g => g.WorstCastClientPayable) : 0,
// TwoSideMargin = underlyingGroup.Sum(g => g.TwoSideMargin),
// OptId = userId,
// OptName = userName,
// OptDate = DateTime.Now,
// SpanType = SpanType,
// AdditionalWorstCastClientPayable = clientAdditionalMarginDic == null ? 0 : (clientAdditionalMarginDic.ContainsKey(clientGroup.Key ?? 0) ? clientAdditionalMarginDic[clientGroup.Key ?? 0] : 0)
// };
// clientSpanNews.Add(clientSpan);
// }
// //span类型为实时删除所有实时计算的交易的保证金信息
// if (SpanType == client_span.SpanType_RealTime)
// {
// //var clientIds = clientSpanNews.Select(t => t.ClientId).Distinct().ToList();
// //var clientSpanOlds = db.client_span.Where(t => t.SpanType == SpanType);
// if (RefreshClientIds != null)
// {
// //clientSpanOlds = db.client_span.Where(t => RefreshClientIds.Contains(t.ClientId ?? 0));
// db.BulkDelete<client_span>($"{nameof(client_span.ClientId)} in @ids", new { ids = RefreshClientIds });
// }
// else
// {
// db.BulkDelete<client_span>($"{nameof(client_span.SpanType)}=@SpanType", new { SpanType });
// }
// //MySqlBulkExtensions.BulkDelete(db, clientSpanOlds);
// MySqlBulkExtensions.BulkInsert(db, clientSpanNews);
// }
// else
// {
// //var clientSpanOldsWithOutFlag = db.client_span.Where(t => t.ValueDate == settleDate && t.SpanType == SpanType && !t.ModifiedFlag).ToList();
// //MySqlBulkExtensions.BulkDelete(db, clientSpanOldsWithOutFlag);
// db.BulkDelete<client_span>($"{nameof(client_span.ValueDate)}=@settleDate and {nameof(client_span.SpanType)}=@SpanType and {nameof(client_span.ModifiedFlag)}=0", new { settleDate, SpanType });
// var clientSpanOldsWithFlag = db.client_span.Where(t => t.ValueDate == settleDate && t.SpanType == SpanType && t.ModifiedFlag).ToList();
// //筛选出可以修改的clientSpan
// clientSpanNews = clientSpanNews.Where(c => !clientSpanOldsWithFlag.Any(t => t.ValueDate == c.ValueDate && t.ClientId == c.ClientId)).ToList();
// MySqlBulkExtensions.BulkInsert(db, clientSpanNews);
// }
// db.SaveChanges();
// }
// return true;
// }
// }
// public override double GetTradeMargin(trade trade, double price, bool isInitialMargin = false, bool hasOptionInfo = false)
// {
// using (YLContext db = new YLContext())
// {
// if (trade.TradeType == "结构化交易")
// {
// trade.SubTrades = db.trade.Where(x => x.ParentTradeId == trade.id).ToList();
// }
// }
// var tradeMargin = RunMarginCalculation(0, "系统", new List<trade> { trade }, isInitialMargin ? (trade.TradeDate ?? valuedateBLL.ValueDate) : valuedateBLL.ValueDate, new Dictionary<int, double> { { trade.UnderlyingId, price } }, hasOptionInfo: hasOptionInfo);
// if (null != tradeMargin)
// {
// return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0;
// }
// return 0.0;
// }
// /// <summary>
// /// 获取初始保证金
// /// </summary>
// public double GetInitialMargin(trade trade)
// {
// return DoInitialMarginCalculationV2(trade);
// }
// public double DoInitialMarginCalculationV2(trade trade)
// {
// if (trade.BuySell == "卖出")
// {
// return 0;
// }
// //string userId = "0";
// var underlying = DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingId);
// var under = underlying.Clone();
// under.QuotationDate = trade.TradeDate;
// var variety = DataCacheManager.GetVarietyDataSource().GetData(under.UnderlyingTypeId);
// double clientRatio = 1;
// if (trade.ClientId > 0)
// {
// using (YLContext db = new YLContext())
// {
// var query = from c in db.client
// join cl in db.clientlevel on c.LevelId equals cl.id
// where c.id == trade.ClientId
// select cl.Ratio;
// clientRatio = query.FirstOrDefault() ?? 1;
// }
// }
// if (PS.Config.IsTradeVol)
// {
// //如果没有开仓波动率,则调用接口计算出一个开仓波动率
// if (trade.TradeOpenVolatility == null || trade.TradeOpenVolatility == 0)
// {
// string userGroup = UserBLL.GetUserGroup(trade.TraderId ?? 0);
// var vol = VolatilityHelper.GetVol(
// trade.TradeDate.Value,
// "交易",
// under.UnderlyingCode,
// userGroup);
// var baseVol = BaseVolService.GetBaseVol(new BaseVolReq(under, trade), trade.TraderId ?? 0);
// var skewvol = new SkewVolReq
// {
// AskVar = vol.GetAskVar(),
// BidVar = vol.GetBidVar(),
// BaseVol = baseVol
// };
// trade.TradeOpenVolatility = SingleVolService.GetSingleVol(new SingleVolReq(trade, under, skewvol), trade.TraderId ?? 0);
// }
// }
// else
// {
// throw new ServiceException("光大光子仅支持TradeVol");
// }
// if (under.QuotationDate != valuedateBLL.ValueDate.Date)
// {
// //为了暂时修复一个QDP计算方式与客户需求不匹配的情况
// //在非精确模式下,QDP不包括交易日当天的时间价值,但根据报价需求,需要将交易日当天的时间价值计算在内,
// //所以要将交易日向前移动一天。未来QDP支持传递TTM来计算时,可以直接在TTM上加1,而不用移动交易日
// //注意:当前这个临时修改必须在InitializeMarketProxy之前调用,这样才能正确设置波动率日期
// var calendar = CalendarImpl.Get("chn");
// var qdpDate = new Date(DateTime.Parse(under.QuotationDate.ToString()));
// under.QuotationDate = calendar.PrevBizDay(qdpDate).DateTime;
// }
// //OTC-8856 Start
// //UpLimit
// double priceUp = 0;
// if (!string.IsNullOrWhiteSpace(under.UpDownLimit))
// {
// var tempVaue = under.UpDownLimit;
// if (tempVaue.Contains("%"))
// {
// //百分比
// double.TryParse(tempVaue.Replace("%", ""), out double tempDouble);
// priceUp = (trade.SpotPrice ?? 0) * (1 + (tempDouble * 0.01));
// }
// else
// {
// //绝对值
// double.TryParse(tempVaue, out double tempAbs);
// priceUp = (trade.SpotPrice ?? 0) + Math.Abs(tempAbs);
// }
// }
// else
// {
// double.TryParse(variety?.UpLimit?.Replace("%", ""), out double tempDouble);
// priceUp = (trade.SpotPrice ?? 0) * (1 + (tempDouble * 0.01));
// }
// //
// double priceDown = 0;
// if (!string.IsNullOrWhiteSpace(under.UpDownLimit))
// {
// var tempVaue = under.UpDownLimit;
// if (tempVaue.Contains("%"))
// {
// //百分比
// double.TryParse(tempVaue.Replace("%", ""), out double tempDouble);
// priceDown = (trade.SpotPrice ?? 0) * (1 - (tempDouble * 0.01));
// }
// else
// {
// //绝对值
// double.TryParse(tempVaue, out double tempAbs);
// priceDown = (trade.SpotPrice ?? 0) - Math.Abs(tempAbs);
// }
// }
// else
// {
// double.TryParse(variety?.DownLimit?.Replace("%", ""), out double tempDouble);
// priceDown = (trade.SpotPrice ?? 0) * (1 - (tempDouble * 0.01));
// }
// DataConvert.TryParsePercentValue(under.VolatilityRate, out double volatilityRate);
// if (Math.Abs(volatilityRate) < 1e-5)
// {
// volatilityRate = variety.VolatilityRateValue;
// }
// var tradeSpan = new trade_span();
// var userId = Guid.NewGuid().ToString();
// var result = ValueCalculator.GetOptionValueResultV2(userId, under, trade, new double[] { trade.TradeOpenVolatility.Value }, new double[] { priceUp }, request: ValueCalculator.PV_ONLY);
// tradeSpan.Spv1 = (double.IsNaN(result.Pv) ? 0 : result.Pv) * clientRatio;
// result = ValueCalculator.GetOptionValueResultV2(userId, under, trade, new double[] { trade.TradeOpenVolatility.Value * (1 + volatilityRate) }, new double[] { priceUp }, request: ValueCalculator.PV_ONLY);
// tradeSpan.Spv2 = (double.IsNaN(result.Pv) ? 0 : result.Pv) * clientRatio;
// result = ValueCalculator.GetOptionValueResultV2(userId, under, trade, new double[] { trade.TradeOpenVolatility.Value }, new double[] { priceDown }, request: ValueCalculator.PV_ONLY);
// tradeSpan.Spv3 = (double.IsNaN(result.Pv) ? 0 : result.Pv) * clientRatio;
// result = ValueCalculator.GetOptionValueResultV2(userId, under, trade, new double[] { trade.TradeOpenVolatility.Value * (1 + volatilityRate) }, new double[] { priceDown }, request: ValueCalculator.PV_ONLY);
// tradeSpan.Spv4 = (double.IsNaN(result.Pv) ? 0 : result.Pv) * clientRatio;
// tradeSpan.setWorstCastClientPayable4();
// return tradeSpan.WorstCastClientPayable ?? 0;
// }
// }
//}