579 lines
36 KiB
C#
579 lines
36 KiB
C#
//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.MarginModule;
|
|
//using YLErp.QdpModule;
|
|
//using CalculatorHelper = YLErp.BLL.Calculation.CalculatorHelperOld;
|
|
|
|
//namespace YLErp.BLL.MarginCalculationBak
|
|
//{
|
|
// /// <summary>
|
|
// /// 瑞达保证金计算
|
|
// /// </summary>
|
|
// public class RDMarginCalculation : MarginCalculationBase
|
|
// {
|
|
// // 定义一个静态变量来保存类的实例
|
|
// public static readonly RDMarginCalculation Instance;
|
|
|
|
// static RDMarginCalculation()
|
|
// {
|
|
// Instance = new RDMarginCalculation();
|
|
// }
|
|
|
|
// // 定义私有构造函数,使外界不能创建该类实例
|
|
// protected RDMarginCalculation()
|
|
// {
|
|
// }
|
|
|
|
// 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 (!(priceDict?.Count > 0))
|
|
// {
|
|
// var codes = tradeList.Select(O => O.UnderlyingCode).ToArray();
|
|
// priceDict = 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);
|
|
// }
|
|
|
|
// //判断当日结算价是否已经入库
|
|
// //if (priceDict == null || priceDict.Count == 0)
|
|
// //{
|
|
// // throw new Exception("当日结算价还未同步,请等待结算价自动同步完成或手动同步后再执行收盘操作!");
|
|
// //}
|
|
|
|
// var tradeVolatilityRateDic = tradeList.ToDictionary(t => t.id, t => priceDict[t.UnderlyingId] / t.ActualStrike < 0.9 && t.OptionType == "看涨" || priceDict[t.UnderlyingId] / t.ActualStrike > 1.1 && t.OptionType == "看跌" ? 0.2 : (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 upLimitPricesTwoThirds = new Dictionary<int, double>();
|
|
// var upLimitPricesOneThird = new Dictionary<int, double>();
|
|
// var downLimitPrices = new Dictionary<int, double>();
|
|
// var downLimitPricesTwoThirds = new Dictionary<int, double>();
|
|
// var downLimitPricesOneThird = new Dictionary<int, double>();
|
|
// var normalLimitPrices = new Dictionary<int, double>();
|
|
// double tempDouble;
|
|
// //根据涨跌幅限制以及当日结算价计算涨停价以及跌停价
|
|
// if (priceDict != null && priceDict.Count > 0)
|
|
// {
|
|
// 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));
|
|
// upLimitPricesTwoThirds[t.Key] = t.Value * (1 + (tempDouble * 0.01) * 2.0 / 3.0);
|
|
// upLimitPricesOneThird[t.Key] = t.Value * (1 + (tempDouble * 0.01) / 3.0);
|
|
// }
|
|
// else
|
|
// {
|
|
// //绝对值
|
|
// double.TryParse(tempVaue, out double tempAbs);
|
|
// upLimitPrices[t.Key] = t.Value + Math.Abs(tempAbs);
|
|
// upLimitPricesTwoThirds[t.Key] = t.Value + Math.Abs(tempAbs) * 2.0 / 3.0;
|
|
// upLimitPricesOneThird[t.Key] = t.Value + Math.Abs(tempAbs) / 3.0;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// upLimitPrices[t.Key] = t.Value * (1 + 0.05);
|
|
// upLimitPricesTwoThirds[t.Key] = t.Value * (1 + 0.05 * 2.0 / 3.0);
|
|
// upLimitPricesOneThird[t.Key] = t.Value * (1 + 0.05 / 3.0);
|
|
// }
|
|
|
|
// //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));
|
|
// downLimitPricesTwoThirds[t.Key] = t.Value * (1 - (tempDouble * 0.01) * 2.0 / 3.0);
|
|
// downLimitPricesOneThird[t.Key] = t.Value * (1 - (tempDouble * 0.01) / 3.0);
|
|
// }
|
|
// else
|
|
// {
|
|
// //绝对值
|
|
// double.TryParse(tempVaue, out double tempAbs);
|
|
// downLimitPrices[t.Key] = t.Value - Math.Abs(tempAbs);
|
|
// downLimitPricesTwoThirds[t.Key] = t.Value - Math.Abs(tempAbs) * 2.0 / 3.0;
|
|
// downLimitPricesOneThird[t.Key] = t.Value - Math.Abs(tempAbs) / 3.0;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// downLimitPrices[t.Key] = t.Value * (1 - 0.05);
|
|
// downLimitPricesTwoThirds[t.Key] = t.Value * (1 - 0.05 * 2.0 / 3.0);
|
|
// downLimitPricesOneThird[t.Key] = t.Value * (1 - 0.05 / 3.0);
|
|
// }
|
|
|
|
// //Normal
|
|
// normalLimitPrices[t.Key] = t.Value;
|
|
// }
|
|
// eodPriceDict["up"] = upLimitPrices;
|
|
// eodPriceDict["upTwoThirds"] = upLimitPricesTwoThirds;
|
|
// eodPriceDict["upOneThird"] = upLimitPricesOneThird;
|
|
// eodPriceDict["down"] = downLimitPrices;
|
|
// eodPriceDict["downTwoThirds"] = downLimitPricesTwoThirds;
|
|
// eodPriceDict["downOneThird"] = downLimitPricesOneThird;
|
|
// eodPriceDict["normal"] = normalLimitPrices;
|
|
// }
|
|
// //波动率变化
|
|
// 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));
|
|
|
|
// 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;
|
|
// }
|
|
// else if (item.Trade.TradeType == "权益互换")
|
|
// {
|
|
// value = (item.Trade.trade_swap.GetMarginRate ?? 0) * (item.Trade.StockEqvNotional ?? 0) + Math.Max((double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv), 0);
|
|
// }
|
|
// if (resultMap.ContainsKey(item.Trade.id))
|
|
// {
|
|
// switch (key)
|
|
// {
|
|
// case "up_1":
|
|
// resultMap[item.Trade.id].Spv1 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "upTwoThirds_1":
|
|
// resultMap[item.Trade.id].Spv2 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "upOneThird_1":
|
|
// resultMap[item.Trade.id].Spv3 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "normal_1":
|
|
// resultMap[item.Trade.id].Spv4 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "down_1":
|
|
// resultMap[item.Trade.id].Spv5 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "downTwoThirds_1":
|
|
// resultMap[item.Trade.id].Spv6 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "downOneThird_1":
|
|
// resultMap[item.Trade.id].Spv7 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "normal_0":
|
|
// resultMap[item.Trade.id].Delta = item.ValueResult.Delta;
|
|
// break;
|
|
// default:
|
|
// break;
|
|
// }
|
|
// resultMap[item.Trade.id].setWorstCastClientPayable8();
|
|
// }
|
|
// else
|
|
// {
|
|
// var trade = tradeList.FirstOrDefault(t => t.id == item.Trade.id);
|
|
// var underlying = DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
|
|
// var tempTradeSpan = new trade_span
|
|
// {
|
|
// TradeId = item.Trade.id,
|
|
// ClientId = trade.ClientId,
|
|
// ValueDate = settleDate,
|
|
// VarietyId = underlying.UnderlyingTypeId,
|
|
// UnderlyingId = trade.UnderlyingId,
|
|
// UnderlyingCode = trade.UnderlyingCode,
|
|
// OptId = userId,
|
|
// OptName = userName,
|
|
// OptDate = DateTime.Now
|
|
// };
|
|
// switch (key)
|
|
// {
|
|
// case "up_1":
|
|
// tempTradeSpan.Spv1 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "upTwoThirds_1":
|
|
// tempTradeSpan.Spv2 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "upOneThird_1":
|
|
// tempTradeSpan.Spv3 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "normal_1":
|
|
// tempTradeSpan.Spv4 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "down_1":
|
|
// tempTradeSpan.Spv5 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "downTwoThirds_1":
|
|
// tempTradeSpan.Spv6 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "downOneThird_1":
|
|
// tempTradeSpan.Spv7 = item.Trade.TradeType == "自定义交易" || item.Trade.TradeType == "权益互换" ? value : (double.IsNaN(item.ValueResult.Pv) ? 0 : item.ValueResult.Pv) * clientRatio;
|
|
// break;
|
|
// case "normal_0":
|
|
// tempTradeSpan.Delta = item.ValueResult.Delta;
|
|
// break;
|
|
// default:
|
|
// break;
|
|
// }
|
|
// resultMap[item.Trade.id] = tempTradeSpan;
|
|
// }
|
|
|
|
// resultMap[item.Trade.id].UnderlyingPrice = priceDict[item.Trade.UnderlyingId];
|
|
// }
|
|
// }
|
|
// });
|
|
// }
|
|
// }
|
|
// finally
|
|
// {
|
|
// //上面的计算用到静态生成market,需要清除
|
|
// QdpMarketManager.Instance.RemovePrebuiltMarketProxy(userIdNew);
|
|
// }
|
|
|
|
// 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())
|
|
// {
|
|
// var underlyingCodes = tradeSpans.Select(t => t.UnderlyingCode).ToHashSet();
|
|
// var mpProvider = new MarginParamProvider(new OptUserInfo(0, "系统"), settleDate).Initialize(underlyingCodes, MarginParamTypeEnum.MarginRate);
|
|
|
|
// //删除
|
|
// 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)
|
|
// {
|
|
// #region Span Margin Method
|
|
|
|
// 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),
|
|
// Spv5 = t.Sum(g => g.tradeSpan.Spv5) * (-1),
|
|
// Spv6 = t.Sum(g => g.tradeSpan.Spv6) * (-1),
|
|
// Spv7 = t.Sum(g => g.tradeSpan.Spv7) * (-1),
|
|
// OptId = userId,
|
|
// OptName = userName,
|
|
// OptDate = DateTime.Now,
|
|
// SpanType = SpanType
|
|
// }).ToList();
|
|
// foreach (var item in underlyingGroup)
|
|
// {
|
|
// item.WorstCastClientPayable = Math.Min(Math.Min(Math.Min(Math.Min(Math.Min(Math.Min(item.Spv1 ?? 0, item.Spv2 ?? 0), item.Spv3 ?? 0), item.Spv4 ?? 0), item.Spv5 ?? 0), item.Spv6 ?? 0), item.Spv7 ?? 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 if (item.WorstCastClientPayable == item.Spv4)
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv4);
|
|
// }
|
|
// else if (item.WorstCastClientPayable == item.Spv5)
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv5);
|
|
// }
|
|
// else if (item.WorstCastClientPayable == item.Spv6)
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv6);
|
|
// }
|
|
// else
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = x.Spv7);
|
|
// }
|
|
|
|
// #endregion
|
|
|
|
// if (!PS.Config.ErpElement.NonInterBankMarginNetting)
|
|
// {
|
|
// item.WorstCastClientPayable = Math.Min(item.WorstCastClientPayable.Value, 0);
|
|
// }
|
|
// }
|
|
|
|
// #endregion
|
|
|
|
// #region Delta Margin Method
|
|
|
|
// var varietyGroup = clientGroup.GroupBy(t => t.trade.VarietyId).Select(t => new client_span
|
|
// {
|
|
// VarietyId = t.Key,
|
|
// ClientId = clientGroup.Key,
|
|
// ValueDate = settleDate,
|
|
// MaxSpotPrice = t.Max(g => g.tradeSpan.UnderlyingPrice),
|
|
// DeltaSell = t.Sum(g => -g.tradeSpan.Delta * (g.trade.BuySell == "买入" ? 1 : 0)),
|
|
// DeltaBuy = t.Sum(g => -g.tradeSpan.Delta * (g.trade.BuySell == "卖出" && g.tradeSpan.Delta < 0 ? 1 : 0)),
|
|
// DeltaBuyMinus = t.Sum(g => -g.tradeSpan.Delta * (g.trade.BuySell == "卖出" && g.tradeSpan.Delta > 0 ? 1 : 0)),
|
|
// OptId = userId,
|
|
// OptName = userName,
|
|
// OptDate = DateTime.Now,
|
|
// SpanType = SpanType
|
|
// }).ToList();
|
|
|
|
// foreach (var item in varietyGroup)
|
|
// {
|
|
// #region 更新tradeSpan,通过Delta品种级别求和算法,给tradeSpan的deltaMargin赋值
|
|
|
|
// var marginRate = mpProvider.GetVarietyData(item.VarietyId ?? 0, MarginParamTypeEnum.MarginRate);
|
|
|
|
// var tradeSpansUpdate = db.trade_span.Where(x => x.ClientId == item.ClientId && x.VarietyId == item.VarietyId && x.ValueDate == settleDate).ToList();
|
|
// //DeltaSell为客户角度卖出,且为客户角度看Delta
|
|
// if (item.DeltaSell > 0)
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x =>
|
|
// {
|
|
// var trade = tradeSpanInfo.FirstOrDefault(y => y.trade.id == x.TradeId).trade;
|
|
// //客户角度卖出的交易
|
|
// //客户角度买入的交易,客户角度Delta<0,即交易员角度Delta>0
|
|
// if (trade.BuySell == "买入" || x.Delta > 0)
|
|
// {
|
|
// x.DeltaMargin = -x.Delta * item.MaxSpotPrice * marginRate;
|
|
// }
|
|
// });
|
|
// item.DeltaMargin = -Math.Max((item.DeltaSell ?? 0 + item.DeltaBuyMinus ?? 0), 0) * item.MaxSpotPrice * marginRate;
|
|
// }
|
|
// else
|
|
// {
|
|
// tradeSpansUpdate.ForEach(x =>
|
|
// {
|
|
// var trade = tradeSpanInfo.FirstOrDefault(y => y.trade.id == x.TradeId).trade;
|
|
// //客户角度卖出的交易
|
|
// //客户角度买入的交易,客户角度Delta>0,即交易员角度Delta<0
|
|
// if (trade.BuySell == "买入" || x.Delta < 0)
|
|
// {
|
|
// x.DeltaMargin = x.Delta * item.MaxSpotPrice * marginRate;
|
|
// }
|
|
// });
|
|
// item.DeltaMargin = Math.Min((item.DeltaSell ?? 0 + item.DeltaBuyMinus ?? 0), 0) * item.MaxSpotPrice * marginRate;
|
|
// }
|
|
|
|
// #endregion
|
|
// }
|
|
|
|
// #endregion
|
|
|
|
// 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),
|
|
// Spv5 = underlyingGroup.Sum(g => g.Spv5),
|
|
// Spv6 = underlyingGroup.Sum(g => g.Spv6),
|
|
// Spv7 = underlyingGroup.Sum(g => g.Spv7),
|
|
// DeltaMargin = varietyGroup.Sum(g => g.DeltaMargin),
|
|
// //负数代表客户应缴保证金,正数代表客户应收保证金
|
|
// WorstCastClientPayable = underlyingGroup.Sum(g => g.WorstCastClientPayable) < 0 ? underlyingGroup.Sum(g => g.WorstCastClientPayable) : 0,
|
|
// OptId = userId,
|
|
// OptName = userName,
|
|
// OptDate = DateTime.Now,
|
|
// SpanType = SpanType,
|
|
// AdditionalWorstCastClientPayable = clientAdditionalMarginDic == null ? 0 : (clientAdditionalMarginDic.ContainsKey(clientGroup.Key ?? 0) ? clientAdditionalMarginDic[clientGroup.Key ?? 0] : 0)
|
|
// };
|
|
// if (clientSpan.WorstCastClientPayable > clientSpan.DeltaMargin)
|
|
// {
|
|
// clientSpan.WorstCastClientPayable = clientSpan.DeltaMargin;
|
|
// }
|
|
// clientSpanNews.Add(clientSpan);
|
|
// }
|
|
|
|
// //span类型为实时删除所有实时计算的交易的保证金信息
|
|
// if (SpanType == client_span.SpanType_RealTime)
|
|
// {
|
|
// if (RefreshClientIds != null)
|
|
// {
|
|
// 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.BulkInsert(db, clientSpanNews);
|
|
// }
|
|
// else
|
|
// {
|
|
// 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)
|
|
// .Select(n => new { n.ValueDate, n.ClientId }).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;
|
|
// }
|
|
// }
|
|
//}
|