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

382 lines
19 KiB
C#

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text.RegularExpressions;
//using YLErp.DBModels;
//using YLErp.Helpers;
//using YLErp.Model;
//using YLErp.Modules.DataProviderModule;
//namespace YLErp.BLL.MarginCalculationBak
//{
// /// <summary>
// /// 保证金计算
// /// </summary>
// public class MarginCalculationBase
// {
// protected static readonly Abstract.ILogger logger = LogFactory.GetLogger("保证金计算");
// protected readonly UnderlyingDataProvider _underlyingDataProvider;
// protected MarginCalculationBase()
// {
// _underlyingDataProvider = new UnderlyingDataProvider();
// }
// public virtual bool MarginCalcNeedSpecial => false;
// public virtual 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 = true, Dictionary<int, double> clientAdditionalMarginDic = null)
// {
// using (var 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();
// if (OnlyBuyer)
// {
// tradeSpanInfo = tradeSpanInfo.Where(t => t.trade.BuySell == "买入").ToList();
// }
// var clientSpanNews = new List<client_span>(100);
// var clientGroups = tradeSpanInfo.GroupBy(t => t.trade.ClientId);
// foreach (var clientGroup in clientGroups)
// {
// var spvList = new[] {
// clientGroup.Sum(g => g.tradeSpan.Spv1??0),
// clientGroup.Sum(g => g.tradeSpan.Spv2??0),
// clientGroup.Sum(g => g.tradeSpan.Spv3??0),
// clientGroup.Sum(g => g.tradeSpan.Spv4??0)
// };
// var maxSpv = spvList.Max();
// var twoSideMargin = PS.Config.ErpElement.TwoSideMargin && clientList.FirstOrDefault(x => x.id == clientGroup.Key)?.HasTwoSideMargin == 1;
// var clientSpan = new client_span
// {
// ClientId = clientGroup.Key,
// ValueDate = settleDate,
// Spv1 = -spvList[0],
// Spv2 = -spvList[1],
// Spv3 = -spvList[2],
// Spv4 = -spvList[3],
// WorstCastClientPayable = twoSideMargin ? -maxSpv : -Math.Max(maxSpv, 0),
// TwoSideMargin = -maxSpv,
// RiskExposure = -clientGroup.Sum(g => g.tradeSpan.RiskExposure),
// OptId = userId,
// OptName = userName,
// OptDate = DateTime.Now,
// SpanType = SpanType,
// AdditionalWorstCastClientPayable = clientAdditionalMarginDic != null && clientAdditionalMarginDic.TryGetValue(clientGroup.Key ?? 0, out var dd) ? dd : 0
// };
// clientSpanNews.Add(clientSpan);
// }
// var tradeSpanInfoOtherSide = (from tradeSpan in tradeSpansOtherSide
// join trade in tradeList on tradeSpan.TradeId equals trade.id
// where tradeSpan.ValueDate == settleDate
// select new { trade, tradeSpan }).ToList();
// //处理从客户角度的保证金计算(将交易买卖方向反向处理)
// var compareZero = !PS.Config.ErpElement.NonInterBankMarginNetting;
// var clientGroupsOtherSide = tradeSpanInfoOtherSide.GroupBy(t => t.trade.ClientId);
// foreach (var clientGroup in clientGroupsOtherSide)
// {
// var clientSpan = clientSpanNews.FirstOrDefault(x => x.ClientId == clientGroup.Key && x.ValueDate == settleDate);
// if (clientSpan != null)
// {
// clientSpan.OtherSideMargin = clientGroup.Sum(g =>
// {
// var arr = new[] { g.tradeSpan.Spv1 ?? 0, g.tradeSpan.Spv2 ?? 0, g.tradeSpan.Spv3 ?? 0, g.tradeSpan.Spv4 ?? 0 };
// return compareZero ? Math.Min(arr.Min(), 0) : arr.Min();
// });
// }
// }
// //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}");
// }
// MySqlBulkExtensions.BulkInsert(db, clientSpanNews);
// }
// else
// {
// var sql = $"{nameof(client_span.ValueDate)}='{settleDate.ToSqlDate()}' and {nameof(client_span.SpanType)}={SpanType} and {nameof(client_span.ModifiedFlag)}=0";
// db.BulkDelete<client_span>(sql);
// 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 virtual 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)
// {
// var tradeSpans = new List<trade_span>();
// if (tradeList != null && tradeList.Count > 0)
// {
// using (var db = new YLContext())
// {
// var marginRation = valuedateBLL.SystemDate.MarginRatio ?? 0.15;
// 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();
// if (clientList != null)
// {
// tradeList.ForEach(t =>
// {
// var client = clientList.FirstOrDefault(c => c.client.id == t.ClientId);
// if (client != null)
// {
// //未设置相关保证金系数默认为1.0
// var clientRatio = client.clientlevel == null ? 1.0 : (client.clientlevel.Ratio ?? 1.0);
// //如果是股票去名义本金,如果是期货取:份额 * 即期价格
// var value = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.client.HasTwoSideMargin == 1 ? -1 : 0)) * clientRatio;
// var twoSideMargin = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : -1) * clientRatio;
// tradeSpans.Add(new trade_span
// {
// TradeId = t.id,
// OptDate = DateTime.Now,
// OptId = userId,
// OptName = userName,
// ClientId = client.client.id,
// UnderlyingId = t.UnderlyingId,
// UnderlyingCode = t.UnderlyingCode,
// ValueDate = settleDate,
// Spv1 = value,
// Spv2 = value,
// Spv3 = value,
// Spv4 = value,
// WorstCastClientPayable = value,
// TwoSideMargin = twoSideMargin
// });
// }
// });
// }
// }
// }
// return tradeSpans;
// }
// public virtual double GetTradeMargin(trade trade, double price, bool isInitialMargin = false, bool hasOptionInfo = false)
// {
// 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;
// }
// private double GetUpDownValue(string upDownLimit, double settlePrice, double minPriceChange)
// {
// double result = 0, haifPrice = minPriceChange / 2;
// if (upDownLimit.Contains("%"))
// {
// //百分比
// double.TryParse(upDownLimit.Replace("%", ""), out result);
// result = settlePrice * (result * 0.01);
// }
// else
// {
// //绝对值
// double.TryParse(upDownLimit, out result);
// }
// double diff = result % minPriceChange;
// result -= diff;
// if (diff >= haifPrice) { result += minPriceChange; }
// return result;
// }
// /// <summary>
// /// 获取涨跌幅
// /// </summary>
// /// <param name="underlyingId">标的Id</param>
// /// <returns>
// /// <para>Key:标的Id;</para>
// /// <para>Value:[0]:涨幅;</para>
// /// <para>Value:[1]:跌幅;</para>
// /// <para>Value:[2]:最小价格变动;</para>
// /// </returns>
// protected Dictionary<int, string[]> GetUpDownLimitRate(IEnumerable<int> underlyingId)
// {
// Dictionary<int, string[]> result = new Dictionary<int, string[]>();
// using (YLContext db = new YLContext())
// {
// var underlyingIds = underlyingId.ToList();
// //获取标的涨跌幅限制
// var umDatas = (from um in db.underlying_manager
// join variety in db.variety on um.UnderlyingTypeId equals variety.id
// where underlyingIds.Contains(um.id)
// select new
// {
// um.id,
// um.VolatilityRate,
// um.UpDownLimit,
// variety.MinPriceChange,
// defUpLimit = variety.UpLimit,
// defDownLimit = variety.DownLimit,
// defVolatilityRate = variety.VolatilityRate
// }).ToList();
// if (umDatas != null && umDatas.Count > 0)
// {
// umDatas.ForEach(t =>
// {
// string[] limitArr = new string[3];
// if (!string.IsNullOrWhiteSpace(t.UpDownLimit))
// {
// limitArr[0] = t.UpDownLimit;//百分比或绝对值
// limitArr[1] = t.UpDownLimit;
// }
// else
// {
// limitArr[0] = t.defUpLimit?.ToString() ?? "5%";
// limitArr[1] = t.defDownLimit?.ToString() ?? "5%";
// }
// if (string.IsNullOrEmpty(t.MinPriceChange))
// {
// limitArr[2] = "0.01";
// }
// else
// {
// limitArr[2] = Regex.Match(t.MinPriceChange, @"\d+(?=元.+)").Value;
// if (string.IsNullOrEmpty(t.MinPriceChange))
// {
// limitArr[2] = "0.01";
// }
// }
// result[t.id] = limitArr;
// });
// }
// }
// return result;
// }
// /// <summary>
// /// 获取涨跌幅价格
// /// </summary>
// /// <param name="upDownLimit">
// /// <para>[0]:涨幅;</para>
// /// <para>[1]:跌幅;</para>
// /// </param>
// /// <param name="price">基准价</param>
// /// <param name="minPriceChange">最小价格变动</param>
// /// <returns>
// /// <para>[0]:涨停价;</para>
// /// <para>[1]:跌停价;</para>
// /// </returns>
// protected double[] GetUpDownLimitPrice(string[] upDownLimit, double price, double minPriceChange)
// {
// double[] priceArr = new double[2];
// double tempDouble, haifPrice = minPriceChange / 2;
// #region 涨幅
// tempDouble = GetUpDownValue(upDownLimit[0], price, minPriceChange);
// priceArr[0] = price + Math.Abs(tempDouble);
// #endregion
// #region 跌幅
// tempDouble = GetUpDownValue(upDownLimit[1], price, minPriceChange);
// priceArr[1] = price - Math.Abs(tempDouble);
// #endregion
// return priceArr;
// }
// /// <summary>
// /// 获取涨跌停价格
// /// </summary>
// /// <param name="priceDict">
// /// 当前价格
// /// <para>Key:标的Id;</para>
// /// <para>Value:标的价格;</para>
// /// </param>
// /// <returns>
// /// <para>Key:标的Id;</para>
// /// <para>Value:[0]:涨停价;</para>
// /// <para>Value:[1]:跌停价;</para>
// /// </returns>
// protected Dictionary<int, double[]> GetUpDownLimitPrice(Dictionary<int, double> priceDict)
// {
// Dictionary<int, double[]> result = new Dictionary<int, double[]>();
// Dictionary<int, string[]> upDownLimitRate = GetUpDownLimitRate(priceDict.Keys);
// foreach (var item in upDownLimitRate)
// { result[item.Key] = GetUpDownLimitPrice(item.Value, priceDict[item.Key], double.Parse(item.Value[2])); }
// return result;
// }
// //为了算客户角度的一个保证金数值
// //RunMarginCalculation时forOtherSide为true时调用
// protected List<trade_span> RunMarginCalculationOtherSide(int userId, string userName, List<trade> tradeList, DateTime settleDate, Dictionary<int, double> priceDict, bool hasOptionInfo, bool isEodSettle, bool forSingleTrade, string volType)
// {
// void RevertBuySell()
// {
// foreach (var x in tradeList)
// {
// x.BuySell = x.BuySell == "买入" ? "卖出" : "买入";
// if (x.SubTrades != null && x.SubTrades.Any())
// {
// foreach (var xs in x.SubTrades)
// {
// xs.BuySell = xs.BuySell == "买入" ? "卖出" : "买入";
// }
// }
// }
// }
// RevertBuySell();
// var results = RunMarginCalculation(userId, userName, tradeList, settleDate, priceDict, hasOptionInfo, isEodSettle, forSingleTrade, volType, false);
// RevertBuySell();
// return results;
// }
// /// <summary>
// /// 获取currentDate参数前一日的结算价
// /// </summary>
// /// <param name="codes"></param>
// /// <param name="currentDate">当前日期</param>
// /// <param name="settlePriceMode">
// /// 结算价模式,默认为结算价模式
// /// <para>valuedate.EodSettlePriceMode_***</para>
// /// </param>
// /// <returns></returns>
// protected Dictionary<int, double> GetSettlePrice(IEnumerable<string> codes, DateTime currentDate, string settlePriceMode = "")
// {
// //默认情况选择结算价
// bool isClosePrice = "收盘价".Equals(settlePriceMode ?? "");
// codes = codes.ToHashSet();
// Dictionary<int, double> priceDict = new Modules.MarginModule.eod_commodity_future_priceBLLBak().GetEodPriceToId(codes, currentDate, isClosePrice ? 2 : 3);
// return priceDict;
// }
// }
//}