Files
zszq-trs/YLErpDAL/BLL/MarginCalculation/UniversalMarginCalculation.cs
T
2024-05-09 14:06:26 +08:00

140 lines
5.4 KiB
C#

using YLErp.Modules.MarginModule;
namespace YLErp.BLL.MarginCalculation
{
public class UniversalMarginCalculation : MarginCalculationBase
{
// 定义一个静态变量来保存类的实例
public static readonly UniversalMarginCalculation Instance;
static UniversalMarginCalculation()
{
Instance = new UniversalMarginCalculation();
}
// 定义私有构造函数,使外界不能创建该类实例
private UniversalMarginCalculation()
{
}
public override List<trade_span> RunMarginCalculation(RunMarginCalculationReq req)
{
var tradeSpans = new List<trade_span>();
if (req.tradeList != null && req.tradeList.Count > 0)
{
var tempStockTradeList = req.tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.Stock).ToList();
if (tempStockTradeList.Any())
{
var stockTradeSpanlist = StockMarginCalculation(req.Clone(tempStockTradeList));
if (stockTradeSpanlist.Count > 0)
{
tradeSpans.AddRange(stockTradeSpanlist);
}
}
var tempFutureTradeList = req.tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.CommodityFutures).ToList();
if (tempFutureTradeList.Any())
{
var futureTradeSpanlist = FutureMarginCalculation(req.Clone(tempFutureTradeList));
if (futureTradeSpanlist.Count > 0)
{
tradeSpans.AddRange(futureTradeSpanlist);
}
}
}
return tradeSpans;
}
/// <summary>
/// 股票类期权计算预付金
/// </summary>
public List<trade_span> StockMarginCalculation(RunMarginCalculationReq req)
{
//20210415:为了格林大华收盘通过
//throw new Exception("未实现");
return new List<trade_span>();
}
/// <summary>
/// 商品期权计算预付金
/// </summary>
public List<trade_span> FutureMarginCalculation(RunMarginCalculationReq req)
{
var futureTradeList = req.tradeList;
var tradeSpans = new List<trade_span>();
if (futureTradeList == null || futureTradeList.Count < 1)
{
return tradeSpans;
}
var underlyingCodes = futureTradeList.Select(O => O.UnderlyingCode).ToHashSet();
var mpProvider = new MarginParamProvider(req.UserInfo, req.settleDate)
.Initialize(underlyingCodes, MarginParamTypeEnum.MarginRate);
var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider);
foreach (var t in futureTradeList)
{
if (!helper.GetSpecialMargin(t, 0, out var value))
{
req.PriceProvider.TryGetPrice(t.UnderlyingCode, out var price);
mpProvider.TryGetMarginRate(t.UnderlyingCode, out var marginRate);
var contractSize = (_underlyingDataProvider.GetUnderlying(t.UnderlyingCode)?.ContractSize) ?? 0;
double diffPrice = 0;
switch (t.OptionType)
{
case "看涨":
diffPrice = (t.Strike ?? 0) - price;
break;
case "看跌":
diffPrice = price - (t.Strike ?? 0);
break;
}
var visualValue = Math.Max(diffPrice, 0) * contractSize;
var futureMargin = price * marginRate * contractSize;
var optionMargin1 = t.StockEqvNotional + futureMargin - 0.5 * visualValue;
var optionMargin2 = t.StockEqvNotional + futureMargin * 0.5;
value = Math.Max(optionMargin1, optionMargin2);
}
tradeSpans.Add(new trade_span
{
TradeId = t.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = t.ClientId,
UnderlyingId = t.UnderlyingId,
UnderlyingCode = t.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = value,
Spv2 = value,
Spv3 = value,
Spv4 = value,
WorstCastClientPayable = value
});
}
return tradeSpans;
}
public override double GetTradeMargin(GetTradeMarginReq req)
{
var trade = req.trade;
using (var db = new YLContext())
{
if (trade.TradeType == "结构化交易")
{
trade.SubTrades = db.trade.Where(x => x.ParentTradeId == trade.id).ToList();
}
}
var tradeMargin = RunMarginCalculation(req.GetRunMarginCalculationReq());
if (null != tradeMargin)
{
return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0;
}
return 0.0;
}
}
}