192 lines
8.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|