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

192 lines
8.2 KiB
C#

using YLErp.BLL.Calculation;
using YLErp.DBModels.Helpers;
using YLErp.QdpModule;
namespace YLErp.BLL.MarginCalculation
{
/// <summary>
/// 安粮
/// </summary>
public class ALQHMarginCalculation : MarginCalculationBase
{
// 定义一个静态变量来保存类的实例
public static readonly ALQHMarginCalculation Instance;
static ALQHMarginCalculation()
{
Instance = new ALQHMarginCalculation();
}
// 定义私有构造函数,使外界不能创建该类实例
private ALQHMarginCalculation()
{
}
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>
private List<trade_span> StockMarginCalculation(RunMarginCalculationReq req)
{
var tradeSpans = new List<trade_span>();
if (req.tradeList == null || req.tradeList.Count < 1)
{
return tradeSpans;
}
var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider);
var marginRation = valuedateBLL.SystemDate.MarginRatio ?? 0.15;
foreach (var t in req.tradeList)
{
var client = helper.GetClient(t.ClientId);
if (client == null)
{
continue;
}
//未设置相关预付金系数默认为1.0
var clientRatio = client?.Ratio ?? 1.0;
//如果是股票去名义本金,如果是期货取:份额 * 即期价格
var baseValue = (t.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(t.Notional * t.SpotPrice, t.ParticipationRate, t.AnnualizeFactor) : t.StockEqvNotional) * marginRation;
var value = baseValue * (t.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.MarginOptionType == 1 ? -1 : 0)) * clientRatio;
var twoSideMargin = baseValue * (t.BuySell == "买入" ? 1 : -1) * clientRatio;
tradeSpans.Add(new trade_span
{
TradeId = t.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = client.ClientId,
UnderlyingId = t.UnderlyingId,
UnderlyingCode = t.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = value,
Spv2 = value,
Spv3 = value,
Spv4 = value,
WorstCastClientPayable = value,
TwoSideMargin = twoSideMargin
});
}
return tradeSpans;
}
/// <summary>
/// 商品期权计算预付金
/// </summary>
public List<trade_span> FutureMarginCalculation(RunMarginCalculationReq req)
{
var futureTradeList = req.tradeList;
var tradeSpans = new List<trade_span>();
if (req.tradeList == null || req.tradeList.Count < 1)
{
return tradeSpans;
}
var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider);
helper.SetFieldsByTradeType();
var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(
valueDate: req.settleDate,
tradeList: futureTradeList,
calcScenario: req.GetCalcScenario(),
priceProvider: req.PriceProvider,
pricingRequest: QdpPricingRequest.BASIC_GREEKS,
addVolRateDic: null,
volType: req.volType,
settlementType: req.settlementType,
isUseTradeVol: PS.Config.IsTradeVol,
preciseTimeMode: req.CalcMarginType != Enums.CalcMarginTypeEnum.EodMargin);
var deltaCoefficient = valuedateBLL.SystemDate.FutureMarginDeltaCoefficient ?? 1;
var vegaCoefficient = valuedateBLL.SystemDate.FutureMarginVegaCoefficient ?? 3;
var omegaCoefficient = valuedateBLL.SystemDate.FutureMarginOmegaCoefficient ?? 2.5;
var alphaRate = valuedateBLL.SystemDate.FutureMarginAlphaRate ?? 1;
foreach (var item in tradeRiskResult.Results)
{
var tempTrade = futureTradeList.FirstOrDefault(t => t.id == item.Trade.id);
var optionValue = item.ValueResult;
var tempVariety = _underlyingDataProvider.GetVariety(tempTrade.UnderlyingId);
var closePrice = req.PriceProvider.GetPrice(tempTrade.UnderlyingCode);
var client = helper.GetClient(item.Trade.ClientId);
if (tempTrade != null && item.ValueResult != null && tempVariety != null)
{
//未设置相关预付金系数默认为1.0
var clientRatio = client?.Ratio ?? 1.0;
//预付金 = ( a * DeltaCash + b* GammaCash * PricingVol / 16) * 当前标的预付金率 + c * Vega
var value = ((optionValue.DeltaCash * deltaCoefficient
+ optionValue.GammaCash * 0.01 * (optionValue.Vol / 16) * omegaCoefficient) * tempVariety.Margin
+ optionValue.Vega * vegaCoefficient
) * alphaRate * (tempTrade.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.MarginOptionType == 1 ? 1 : 0)) * clientRatio;
var twoSideMargin = ((optionValue.DeltaCash * deltaCoefficient
+ optionValue.GammaCash * 0.01 * (optionValue.Vol / 16) * omegaCoefficient) * tempVariety.Margin
+ optionValue.Vega * vegaCoefficient
) * alphaRate * (tempTrade.BuySell == "买入" ? 1 : -1) * clientRatio;
tradeSpans.Add(new trade_span
{
TradeId = tempTrade.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = tempTrade.ClientId,
UnderlyingId = tempTrade.UnderlyingId,
UnderlyingCode = tempTrade.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = value,
Spv2 = value,
Spv3 = value,
Spv4 = value,
WorstCastClientPayable = value,
TwoSideMargin = twoSideMargin
});
}
}
return tradeSpans;
}
public override double GetTradeMargin(GetTradeMarginReq req)
{
var marginReq = req.GetRunMarginCalculationReq();
var tradeMargin = RunMarginCalculation(marginReq);
if (null != tradeMargin)
{
return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0;
}
return 0.0;
}
}
}