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

339 lines
16 KiB
C#

//using BaseOUDAL;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using YLErp.BLL.Calculation;
//using YLErp.BLL.Calculation.V2;
//using YLErp.BLL.Eod;
//using YLErp.DBModels;
//using YLErp.DBModels.Consts;
//using YLErp.Model;
//using YLErp.Modules.DataCacheModule;
//using YLErp.Modules.TradeDalModule;
//using YLErp.Modules.VolatilityModule;
//using YLErp.QdpModule;
//using CalculatorHelper = YLErp.BLL.Calculation.CalculatorHelperOld;
//namespace YLErp.BLL.MarginCalculationBak
//{
// /// <summary>
// /// 方顿
// /// </summary>
// public class FDMarginCalculation : MarginCalculationBase
// {
// // 定义一个静态变量来保存类的实例
// public static readonly FDMarginCalculation Instance;
// static FDMarginCalculation()
// {
// Instance = new FDMarginCalculation();
// }
// // 定义私有构造函数,使外界不能创建该类实例
// private FDMarginCalculation()
// {
// }
// 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)
// {
// List<trade_span> tradeSpans = new List<trade_span>();//结果集
// if (!(priceDict?.Count > 0))
// {
// var codes = tradeList.Select(O => O.UnderlyingCode).ToArray();
// priceDict = base.GetSettlePrice(codes, settleDate);
// }
// if (priceDict.Count == 0)
// {
// //如果价格没有传入也没从数据库获取到,就直接返回,没必要往下运行了。但不应该报错;
// return tradeSpans;
// }
// using (YLContext db = new YLContext())
// {
// if (!hasOptionInfo)
// {
// tradeBLL.SetFieldsByTradeType(tradeList);
// }
// var lastSettleDate = EodOperationBase.GetLastSettlementDate(settleDate, true);
// var tradeIds = tradeList.Select(t => t.id).ToList();
// var tradeMetaDatas = db.TradeMeta.Where(m => tradeIds.Contains(m.TradeId)).ToList().GroupBy(t => t.TradeId).ToDictionary(g => g.Key, g => g.ToDictionary(m => m.MetaKey, m => m.MetaValue));
// var positionMaginRatioDic = db.TradeMeta.Where(m => tradeIds.Contains(m.TradeId) && m.MetaKey == ConsTradeMetaKey.PositionMarginRate)
// .ToList().ToDictionary(m => m.TradeId, m => DataConvert.ToDouble(m.MetaValue));
// new TradeDalService(new OptUserInfo(userId, userName)).SetSubTradeList(tradeList);
// var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(userId + "", settleDate, tradeList, priceDict, ValueCalculator.BASIC_PRICING, null, isEodSettle, volType, isUseTradeVol: PS.Config.IsTradeVol);
// logger.Info($"商品期货保证金计算,交易入:[{tradeList.Count}条],返回[{tradeRiskResult.Results.Count}],错误:{tradeRiskResult.ErrorMessage}");
// //客户对应等级系数
// 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 (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage))
// {
// throw new ServiceException(tradeRiskResult.ErrorMessage);
// }
// if (tradeRiskResult.Results.Count > 0)
// {
// var lastTradeSpanList = db.trade_span.Where(s => s.ValueDate == lastSettleDate).ToList();
// foreach (var item in tradeRiskResult.Results)
// {
// var client = clientList.FirstOrDefault(c => c.client.id == item.Trade.ClientId);
// Dictionary<string, string> metaDics = null;
// if (tradeMetaDatas.ContainsKey(item.Trade.id))
// {
// metaDics = tradeMetaDatas[item.Trade.id];
// }
// #region 维持保证金率
// var positionMaginRatio = 0.0;
// if (metaDics != null && metaDics.ContainsKey(ConsTradeMetaKey.PositionMarginRate))
// {
// positionMaginRatio = DataConvert.ToDouble(metaDics[ConsTradeMetaKey.PositionMarginRate]);
// }
// #endregion
// #region 当前保证金额
// var cashDeposit = 0.0;
// var lastTradeSpan = lastTradeSpanList.FirstOrDefault(s => s.TradeId == item.Trade.id);
// if (lastTradeSpan != null)
// {
// cashDeposit = (lastTradeSpan.CashDeposit ?? 0) + (lastTradeSpan.Margin ?? 0);
// }
// else if (metaDics != null && metaDics.ContainsKey(ConsTradeMetaKey.InitialMarginMoney))
// {
// cashDeposit = DataConvert.ToDouble(metaDics[ConsTradeMetaKey.InitialMarginMoney]);
// }
// #endregion
// var value = Math.Abs(item.ValueResult.DeltaCash) * positionMaginRatio * (item.Trade.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.client.HasTwoSideMargin == 1 ? -1 : 0));
// var twoSideMargin = Math.Abs(item.ValueResult.DeltaCash) * positionMaginRatio * (item.Trade.BuySell == "买入" ? 1 : -1);
// 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:yyyy-MM-dd}需先进行交易风险维护";
// throw new Exception(error);
// }
// }
// value = eodTradeRiskManual?.Margin ?? 0;
// twoSideMargin = eodTradeRiskManual?.Margin ?? 0;
// }
// #region 风险敞口
// var riskExposure = 0.0;
// if (item.Trade.BuySell == "买入")
// {
// //这个地方很诡异,GetAsianFinalPrice和ActualStrike使用了相同的逻辑取均价,不同的地方在于ActualStrike使用的是系统日期,但这样又会造成历史收盘的偏差
// riskExposure = Math.Max(0, (trade_asian_optionBLL.GetAsianFinalPrice(item.Trade, settleDate) - item.Trade.ActualStrike ?? 0) * (item.Trade.OptionType == "看涨" ? 1 : -1)) * item.Trade.Notional;
// }
// #endregion
// //是否需要追保
// var needMargin = (riskExposure - cashDeposit) > 0;
// tradeSpans.Add(new trade_span
// {
// TradeId = item.Trade.id,//默认记录为第一条交易记录中
// OptDate = DateTime.Now,
// OptId = userId,
// OptName = userName,
// ClientId = item.Trade.ClientId,
// ValueDate = settleDate,
// UnderlyingId = item.Trade.UnderlyingId,
// UnderlyingCode = item.Trade.UnderlyingCode,
// Spv1 = value,
// Spv2 = value,
// Spv3 = value,
// Spv4 = value,
// WorstCastClientPayable = value,
// TwoSideMargin = twoSideMargin,
// RiskExposure = riskExposure,
// CashDeposit = cashDeposit,
// Margin = needMargin ? (riskExposure - cashDeposit + Math.Max(value, 0)) : 0,
// Comment = $"DeltaCash:{item.ValueResult.DeltaCash},PositionMaginRatio:{positionMaginRatio}"
// });
// }
// }
// return tradeSpans;
// }
// }
// /// <summary>
// /// 获取初始保证金率
// /// </summary>
// /// <param name="trade"></param>
// /// <returns></returns>
// public double? GetInitialMarginRatio(trade trade)
// {
// if (trade == null)
// {
// return 0;
// }
// if (!trade.VarietyId.HasValue || trade.VarietyId <= 0)
// {
// return 0;
// }
// if (!trade.StockEqvNotional.HasValue)
// {
// return 0;
// }
// var variety = DataCacheManager.GetVarietyDataSource().GetData(trade.VarietyId ?? 0);
// if (variety == null)
// {
// return 0;
// }
// //OTC-8856 Start
// var UpLimitValue = variety.UpLimitValue;
// //var UpLimitValue =((Math.Abs(trade.Underlying.UpDownLimitValue) > 1e-5) ? trade.Underlying.UpDownLimitValue : variety.UpLimitValue);
// //End
// if (trade.StockEqvNotional <= 5000000)
// {
// return 2 * UpLimitValue;
// }
// else if (trade.StockEqvNotional <= 10000000)
// {
// return 2.5 * UpLimitValue;
// }
// else if (trade.StockEqvNotional <= 20000000)
// {
// return 3 * UpLimitValue;
// }
// return null;
// }
// /// <summary>
// /// 获取维持保证金率
// /// </summary>
// /// <param name="trade"></param>
// /// <returns></returns>
// public double? GetPositionMarginRatio(trade trade)
// {
// if (trade == null)
// {
// return 0;
// }
// if (!trade.VarietyId.HasValue || trade.VarietyId <= 0)
// {
// return 0;
// }
// if (!trade.StockEqvNotional.HasValue)
// {
// return 0;
// }
// //underlying_manager
// var variety = DataCacheManager.GetVarietyDataSource().GetData(trade.VarietyId ?? 0);
// if (variety == null)
// {
// return 0;
// }
// if (trade.StockEqvNotional <= 5000000)
// {
// return 1.5 * variety.UpLimitValue;
// }
// else if (trade.StockEqvNotional <= 10000000)
// {
// return 2 * variety.UpLimitValue;
// }
// else if (trade.StockEqvNotional <= 20000000)
// {
// return 2.5 * variety.UpLimitValue;
// }
// return null;
// }
// /// <summary>
// /// 获取初始保证金
// /// </summary>
// /// <param name="trade"></param>
// /// <returns></returns>
// public double GetInitialMargin(trade trade)
// {
// return DoInitialMarginCalculationV2(trade);
// }
// public double DoInitialMarginCalculationV2(trade trade)
// {
// if (trade.BuySell == "卖出")
// {
// return 0;
// }
// var underlying = DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingId);
// underlying.QuotationDate = trade.TradeDate;
// var spotPrices = new double[] { trade.SpotPrice ?? 0 };
// string userGroup = UserBLL.GetUserGroup(trade.TraderId ?? 0);
// var volSurfaceData = VolatilityHelper.GetVol(underlying.QuotationDate.Value, "交易", underlying.UnderlyingCode, userGroup);
// var vol = OptionCalculator.GetInterpolatedVol(
// VolConstructionType.Normal,
// trade.OptId.ToString(),
// volSurfaceData,
// underlying.QuotationDate?.ToString("yyyy-MM-dd"),
// underlying.UnderlyingCode,
// trade.ExerciseDate?.ToString("yyyy-MM-dd"),
// trade.Strike ?? 0.0,
// isBuy: true,
// isCall: trade.CallPut == "Call",
// spotPrice: spotPrices[0],
// isMoneynessOption: trade.IsMoneynessOptionData,
// timeToMaturityDays: trade.TTMDays ?? double.NaN);
// if (!trade.NoRiskRate.HasValue)
// {
// trade.NoRiskRate = (valuedateBLL.SystemDate.RiskFreeRate ?? 0) * 0.01;
// }
// string fixing = null;
// //亚式期权
// if (trade.TradeType == "亚式期权" || trade.StructureType == "亚式熊市价差")
// {
// fixing = CalculatorHelper.GetFixingStringForAsianOption(trade, trade.TradeDate);
// }
// var optionValue = ValueCalculator.GetOptionValueResultV2(
// trade.OptId.ToString(),
// underlying,
// trade,
// new double[] { vol },
// spotPrices,
// fixing,
// commodityFuturesPreciseTimeMode: true);
// //保证金初始价值=期初期权价值+CashDelta(t)*保证金初始比例(保证金初始比例)
// return (trade.TradePrice ?? 0) + ((optionValue == null) ? 0 : Math.Abs(optionValue.DeltaCash)) * (trade.InitialMarginRatio ?? 0);
// }
// public override 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;
// }
// }
//}