140 lines
5.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|