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

804 lines
42 KiB
C#

using YLErp.BLL.Calculation;
using YLErp.Configuration;
using YLErp.DBModels.Enums;
using YLErp.DBModels.Helpers;
using YLErp.Enums;
using YLErp.Model;
using YLErp.Modules;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.TradeModule;
using YLErp.QdpModule;
namespace YLErp.BLL.MarginCalculation
{
/// <summary>
///
/// </summary>
public static class MarginDefault
{
/// <summary>
/// 计算日终预付金
/// </summary>
public static List<trade_span> RunMarginCalculation(RunMarginCalculationReq req)
{
var result = new List<trade_span>();
var eodTradeids = new YLContext().eod_trade_risk_manual.Where(x => x.ValueDate == req.settleDate && x.Margin != null && string.IsNullOrEmpty(x.VolType)).Select(x => x.TradeId);
var tempTradeList = req.tradeList.Where(O => eodTradeids.Contains(O.id)).ToList();
if (tempTradeList.Any() && PS.Config.Company != CompanyEnum.广期资本)
{
result = EodtraderiskmanualCalculation(req.Clone(tempTradeList));
}
tempTradeList = req.tradeList.Where(O => O.TradeType == "现金流交易" && !eodTradeids.Contains(O.id)).ToList();
if (tempTradeList.Any())
{
result.AddRange(cashflowMarginCalculation(req.Clone(tempTradeList)));
}
tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType != MarginTypeEnum.DEFAULT && !eodTradeids.Contains(O.id)).ToList();
if (tempTradeList.Any())
{
result.AddRange(SingleMarginCalculation(req.Clone(tempTradeList)));
}
//if(PS.Config.ErpElement.SecuritiesEnvironment ){
// tempTradeList = req.tradeList.Where(O => O.TradeType == "收益互换" && !eodTradeids.Contains(O.id)).ToList();
// if (tempTradeList.Any())
// {
// result.AddRange(SwapTradeMarginCalculation(req.Clone(tempTradeList)));
// }
//}
tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType == MarginTypeEnum.DEFAULT && !eodTradeids.Contains(O.id)).ToList();
if (PS.Config.Company == CompanyEnum.广期资本)
{
tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType == MarginTypeEnum.DEFAULT).ToList();
}
if (tempTradeList.Any())
{
switch (PS.Config.Company)
{
case CompanyEnum.渤海:
case CompanyEnum.安粮:
result.AddRange(BHRSMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.申万:
result.AddRange(SYWGMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.方顿:
result.AddRange(FDMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.茂川资本:
result.AddRange(MaoChuanMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.宏源:
result.AddRange(HongYuanMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.中财资本:
result.AddRange(ZhongCaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.上期资本:
result.AddRange(SQMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.伴兴:
result.AddRange(BXMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.海通:
result.AddRange(HaiTongMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.瑞达:
result.AddRange(RDMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.兴证:
result.AddRange(XingZhengMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.弘业:
result.AddRange(HongYeMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.广期资本:
result.AddRange(GQMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.中金:
result.AddRange(ZhongJinMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.厦门象屿:
result.AddRange(XMXYMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.国海:
result.AddRange(GuoHaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.润和:
case CompanyEnum.中基石化:
result.AddRange(DongZhengRunHeMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.华安:
result.AddRange(HuaAnMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.浙期:
result.AddRange(ZheQiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.国投:
result.AddRange(GuoTouMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.湘财:
result.AddRange(XiangCaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.中粮:
result.AddRange(ZhongLiangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.长江:
result.AddRange(ChangJiangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.国信金阳:
result.AddRange(GuoXinJinYangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.东吴:
result.AddRange(DongWuMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.格林大华:
#if DEBUG
result.AddRange(GLDHMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
#endif
case CompanyEnum.国泰君安:
case CompanyEnum.光大光子:
case CompanyEnum.兴业商贸:
result.AddRange(GTJAMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.广发商贸:
result.AddRange(GFSMMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
case CompanyEnum.招证:
result.AddRange(ZhaoZhengMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
default:
result.AddRange(DefaultMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList)));
break;
}
}
foreach (var ret in result)
{
var trade = tempTradeList.FirstOrDefault(o => o.id == ret.TradeId);
if (trade != null && trade.TradeType == "现金流交易")
{
ret.WorstCastClientPayable = 0;
}
}
return result;
}
private static List<trade_span> cashflowMarginCalculation(RunMarginCalculationReq runMarginCalculationReq)
{
List<trade_span> result = new List<trade_span>();
runMarginCalculationReq.tradeList.ForEach(O =>
{
result.Add(new trade_span()
{
TradeId = O.id,
OptDate = DateTime.Now,
OptId = runMarginCalculationReq.userId,
OptName = runMarginCalculationReq.userName,
ClientId = O.ClientId,
UnderlyingId = O.UnderlyingId,
UnderlyingCode = O.UnderlyingCode,
ValueDate = runMarginCalculationReq.settleDate,
Spv1 = 0,
Spv2 = 0,
Spv3 = 0,
Spv4 = 0,
Spv5 = 0,
Spv6 = 0,
Spv7 = 0,
Spv8 = 0,
Spv = 0,
WorstCastClientPayable = 0,
TwoSideMargin = 0
});
});
return result;
}
/// <summary>
/// 收益互换预付金计算
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private static List<trade_span> SwapTradeMarginCalculation(RunMarginCalculationReq req)
{
var result = new List<trade_span>();
var clientIds = req.tradeList.Where(t => t.ParentTradeId == 0).Select(t => t.ClientId).Distinct().ToList();
//增加clientId=0,默认为全部
clientIds.Add(0);
//获取客户互换预付金预警设置
var marginRateList = new YLContext().client_marginrate.Where(t => clientIds.Contains(t.ClientId) && t.ValueDate <= req.settleDate).ToList();
//期权详情
tradeBLL.SetFieldsByTradeType(req.tradeList);
foreach (var trade in req.tradeList)
{
//剔除多空组合子交易
if (trade.ParentTradeId > 0) continue;
client_marginrate clientMarginRateSet = null;
var extendService = new TradeExtendService(req.UserInfo);
extendService.SetTradeExtend(new[] { trade });
//盈亏
var profitAndLoss = 0.0;
//计息开始日
var swapStartDate = (trade.StartDate ?? trade.TradeDate).Value.AddDays(trade.trade_swap.IncludeFirstDay ? 1 : 0);
//初始预付金比例
var initMarginRate = (trade.trade_swap.GetMarginRate ?? 0) - (trade.trade_swap.PayMarginRate ?? 0);
var initMargin = Math.Max(initMarginRate, 0) * trade.StockEqvNotional;
//利息收入 收取 - 支付
var interestIncome = PayoffSwapCalcService.GetExtraAmountBySwapRate(trade.ClientId, trade.TradeDate, trade.trade_swap.GetSwapTimeAndRate, swapStartDate, req.settleDate, trade.trade_swap.AnnualDays ?? 0, trade.StockEqvNotional)
- PayoffSwapCalcService.GetExtraAmountBySwapRate(trade.ClientId, trade.TradeDate, trade.trade_swap.PaySwapTimeAndRate, swapStartDate, req.settleDate, trade.trade_swap.AnnualDays ?? 0, trade.StockEqvNotional);
profitAndLoss += interestIncome;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
var costTradePrice = 0.0;
//是否开仓是收取手续费
if (!trade.trade_swap.IsTradePriceWhenOpen)
{
costTradePrice += (trade.trade_swap.GetSingleFee ?? 0) * (trade.trade_swap.GetNotional ?? 0) / underlying.ContractSize;
costTradePrice += (trade.trade_swap.GetUnAnnualRate ?? 0) * trade.StockEqvNotional;
costTradePrice -= (trade.trade_swap.PaySingleFee ?? 0) * (trade.trade_swap.PayNotional ?? 0) / underlying.ContractSize;
costTradePrice -= (trade.trade_swap.PayUnAnnualRate ?? 0) * trade.StockEqvNotional;
}
profitAndLoss += costTradePrice;
//多空组合
if (SwapTypeEnum.多空组合.ToString().Equals(trade.trade_swap.SwapType))
{
//标的盈亏
if (trade.get_trade_swap_details != null && trade.get_trade_swap_details.Count > 0)
{
trade.get_trade_swap_details.ForEach(a =>
{
profitAndLoss += (req.PriceProvider.GetPrice(a.UnderlyingCode) - (a.SpotPrice ?? 0.0)) * (a.Notional ?? 0.0) * ("空头".Equals(a.LongShort) ? -1.0 : 1.0) * (a.IsForGet ? 1 : -1);
});
}
//预警线
if (marginRateList.Any(a => a.Type.Equals("多空组合") && (a.ClientId == trade.ClientId || a.ClientId == 0)))
{
clientMarginRateSet = marginRateList.Where(a => a.Type.Equals("多空组合") && (a.ClientId == trade.ClientId || a.ClientId == 0)).OrderByDescending(a => a.ClientId).ThenByDescending(a => a.ValueDate).FirstOrDefault();
}
}
else
{//普通 +收取盈亏 -支付盈亏
profitAndLoss +=
PayoffSwapCalcService.GetInitialAmountSwapGet(trade, trade.trade_swap, trade.trade_swap.GetSpotPrice ?? 0, req.PriceProvider.GetPrice(trade.trade_swap.GetUnderlyingCode), trade.StockEqvNotional, req.settleDate, null)
- PayoffSwapCalcService.GetInitialAmountSwapPay(trade, trade.trade_swap, trade.trade_swap.PaySpotPrice ?? 0, req.PriceProvider.GetPrice(trade.trade_swap.PayUnderlyingCode), trade.StockEqvNotional, req.settleDate, null);
if (underlying != null && underlying.Variety != null)
{
if (marginRateList.Any(a => a.Type.Equals("品种") && (a.ClientId == trade.ClientId || a.ClientId == 0) && a.VarietyId == underlying.Variety.id))
{
clientMarginRateSet = marginRateList.Where(a => a.Type.Equals("品种") && (a.ClientId == trade.ClientId || a.ClientId == 0) && a.VarietyId == underlying.Variety.id).OrderByDescending(a => a.ClientId).ThenByDescending(a => a.ValueDate).FirstOrDefault();
}
}
}
//维持预付金
var WorstCastClientPayable = initMargin - profitAndLoss;
//持仓预付金
var positionMargin = initMargin;
var margin = 0.0;
//追保计算 未设置预警线 则取初始预付金比例
if (WorstCastClientPayable <= (clientMarginRateSet == null ? initMarginRate : clientMarginRateSet.WarningLine) * trade.StockEqvNotional)
{
margin = initMargin - WorstCastClientPayable;
//追保暂时只算单方向
positionMargin = initMargin + Math.Max(margin, 0);
}
result.Add(new trade_span()
{
TradeId = trade.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = trade.ClientId,
UnderlyingId = trade.UnderlyingId,
UnderlyingCode = trade.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = positionMargin,
Spv2 = positionMargin,
Spv3 = positionMargin,
Spv4 = positionMargin,
Spv5 = positionMargin,
Spv6 = positionMargin,
Spv7 = positionMargin,
Spv8 = positionMargin,
Spv = positionMargin,
WorstCastClientPayable = positionMargin,
Margin = margin
});
}
return result;
}
private static List<trade_span> SingleMarginCalculation(RunMarginCalculationReq req)
{
var result = new List<trade_span>();
double value = 0;
foreach (var trade in req.tradeList)
{
bool isSingleMargin = false;
switch (trade.MarginType)
{
case MarginTypeEnum.FIXED:
if (req.CalcMarginType == CalcMarginTypeEnum.InitialMargin)
{
value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate;
}
else
{
if (PS.Config.ErpElement.EodFixedMarginUseSpotPrice)
{
value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.PositionMarginRate;
}
else
{
value = (trade.StockEqvNotional == 0 || (trade.SpotPrice ?? 0) == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * req.PriceProvider.GetPrice(trade.UnderlyingCode), trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional * req.PriceProvider.GetPrice(trade.UnderlyingCode) / (trade.SpotPrice ?? 0)) * trade.PositionMarginRate;
}
}
break;
case MarginTypeEnum.FLOAT:
value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate;
if (req.CalcMarginType != CalcMarginTypeEnum.InitialMargin)
{
if (trade.TradeType == "远期")
{
var eodpriceProvider = new YLErp.Modules.DataProviderModule.EodPriceProvider(req.settleDate);
var spotPrice = eodpriceProvider.GetPrice(trade.UnderlyingCode, SettlementTypeEnum.ClosePrice);//收盘价
TradeValueResult curValue = ForwardradeCalcService.CalcValue(trade, spotPrice);
var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0;
double pnl = 0;
pnl = curValue.Pv + tradePrice * (trade.BuySell == "买入" ? -1 : 1);
value += pnl;
if (value < 0)
{ value = 0; }
}
else
{
var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(
valueDate: req.settleDate,
tradeList: new[] { trade },
calcScenario: req.GetCalcScenario(),
priceProvider: req.PriceProvider,
pricingRequest: QdpPricingRequest.PV_ONLY,
addVolRateDic: null,
volType: req.volType, isUseTradeVol: PS.Config.IsTradeVol,
preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin);
if (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage))
{
LogFactory.GetLogger<MarginCalculationBase>().Error("Pv计算失败:" + tradeRiskResult.ErrorMessage);
}
var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0;
double pnl = 0;
if (trade.BuySell == "买入")
{
pnl = tradePrice - Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv);
}
else
{
pnl = Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv) - tradePrice;
}
value += pnl;
if (value < 0)
{ value = 0; }
}
}
break;
case MarginTypeEnum.FLOATP:
if (req.CalcMarginType == CalcMarginTypeEnum.InitialMargin)
{
value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate;
}
else if (req.CalcMarginType != CalcMarginTypeEnum.InitialMargin)
{
value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * req.PriceProvider.GetPrice(trade.UnderlyingCode), trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.PositionMarginRate;
var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(
valueDate: req.settleDate,
tradeList: new[] { trade },
calcScenario: req.GetCalcScenario(),
priceProvider: req.PriceProvider,
pricingRequest: QdpPricingRequest.PV_ONLY,
addVolRateDic: null,
volType: req.volType, isUseTradeVol: PS.Config.IsTradeVol,
preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin);
if (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage))
{
LogFactory.GetLogger<MarginCalculationBase>().Error("Pv计算失败:" + tradeRiskResult.ErrorMessage);
}
var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0;
double pnl = 0;
if (trade.BuySell == "买入")
{
pnl = tradePrice - Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv);
}
else
{
pnl = Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv) - tradePrice;
}
value += pnl;
if (value < 0)
{ value = 0; }
}
break;
case MarginTypeEnum.XingYe:
value = XingYeMarginCalculation.TradeMargin(req, trade);
break;
case MarginTypeEnum.GuoTouLock:
if (trade.TradeType == "雪球期权" || trade.TradeType == "收益互换")
{
var initialMargin = (trade.InitialMargin ?? 0) * trade.StockEqvNotional / trade.OriginalStockEqvNotional.Value;
double[] lockvals = { initialMargin,
PS.Config.Company == CompanyEnum.湘财
? XiangCaiMarginCalculation.TradeMargin(req, trade)
: GuoTouMarginCalculation.TradeMargin(req, trade)
};
if (PS.Config.Company == CompanyEnum.湘财 && initialMargin < 0)
{// #OTC-5636 见备注
value = lockvals.Min();
}
else
{
value = lockvals.Max();
}
isSingleMargin = true;
}
break;
case MarginTypeEnum.GuoTouNoLock:
if (trade.TradeType == "雪球期权" || trade.TradeType == "收益互换")
{
double[] noLockvals = { 0,
PS.Config.Company == CompanyEnum.湘财
? XiangCaiMarginCalculation.TradeMargin(req, trade)
: GuoTouMarginCalculation.TradeMargin(req, trade)
};
value = noLockvals.Max();
isSingleMargin = true;
}
break;
default:
case MarginTypeEnum.NONE:
value = 0;
break;
}
result.Add(new trade_span()
{
TradeId = trade.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = trade.ClientId,
UnderlyingId = trade.UnderlyingId,
UnderlyingCode = trade.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = value,
Spv2 = value,
Spv3 = value,
Spv4 = value,
Spv5 = value,
Spv6 = value,
Spv7 = value,
Spv8 = value,
Spv = value,
WorstCastClientPayable = value,
TwoSideMargin = value,
IsSingleMargin = isSingleMargin
});
}
return result;
}
private static List<trade_span> EodtraderiskmanualCalculation(RunMarginCalculationReq req)
{
var result = new List<trade_span>();
List<int> reqids = req.tradeList.Select(x => x.id).ToList();
var eodTradeRiskManual = new YLContext().eod_trade_risk_manual.Where(x => reqids.Contains(x.TradeId) && x.ValueDate == req.settleDate && x.Margin != null && string.IsNullOrEmpty(x.VolType));
if (eodTradeRiskManual.Any())
{
var tradeRiskManuals = (from trade in req.tradeList
join riskManuals in eodTradeRiskManual on trade.id equals riskManuals.TradeId
select new { trade, riskManuals }).ToList();
foreach (var item in tradeRiskManuals)
{
double value = item.riskManuals.Margin ?? 0;
result.Add(new trade_span()
{
TradeId = item.trade.id,
OptDate = DateTime.Now,
OptId = req.userId,
OptName = req.userName,
ClientId = item.trade.ClientId,
UnderlyingId = item.trade.UnderlyingId,
UnderlyingCode = item.trade.UnderlyingCode,
ValueDate = req.settleDate,
Spv1 = value,
Spv2 = value,
Spv3 = value,
Spv4 = value,
Spv5 = value,
Spv6 = value,
Spv7 = value,
Spv8 = value,
Spv = value,
WorstCastClientPayable = value,
TwoSideMargin = value,
IsSingleMargin = true
});
}
}
return result;
}
public static List<trade_span> CalcClientMargin(CalcClientMarginReq req)
{
switch (PS.Config.Company)
{
case CompanyEnum.渤海:
return BHRSMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.安粮:
return BHRSMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.申万:
return SYWGMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.伴兴:
return BXMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.海通:
return HaiTongMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.瑞达:
return RDMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.兴证:
return XingZhengMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.宏源:
return HongYuanMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.中财资本:
return ZhongCaiMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.上期资本:
return SQMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.弘业:
return HongYeMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.广期资本:
return GQMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.方顿:
return FDMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.中金:
return ZhongJinMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.国海:
return GuoHaiMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.厦门象屿:
return XMXYMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.华安:
return HuaAnMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.浙期:
return ZheQiMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.润和:
case CompanyEnum.中基石化:
return DongZhengRunHeMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.国投:
return GuoTouMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.湘财:
return XiangCaiMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.中粮:
return ZhongLiangMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.长江:
return ChangJiangMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.国信金阳:
return GuoXinJinYangMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.东吴:
return DongWuMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.格林大华:
#if DEBUG
return GLDHMarginCalculation.Instance.CalcClientMargin(req);
#endif
case CompanyEnum.国泰君安:
case CompanyEnum.光大光子:
return GTJAMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.广发商贸:
return GFSMMarginCalculation.Instance.CalcClientMargin(req);
case CompanyEnum.招证:
return ZhaoZhengMarginCalculation.Instance.CalcClientMargin(req);
default:
return DefaultMarginCalculation.Instance.CalcClientMargin(req);
}
}
/// <summary>
/// 这个方法不明白什么意思
/// 按照历史代码,国君应该一直返回的是false,但事实是根据收盘数据看2021年9月24日及以前返回的是true
/// </summary>
public static bool IsMarginCalcNeedSpecial(DateTime valueDate)
{
//国君商品类预付金需要算反向预付金,权益类不需要
if (PS.Config.IsGuoJun && (!PS.Config.ErpElement.IsStockMargin || PS.Config.ClientElement.TwoSideMargin) && valuedateBLL.TwoSideMarginValueDate.HasValue && valueDate >= valuedateBLL.TwoSideMarginValueDate)
{
return true;
}
switch (PS.Config.Company)
{
case CompanyEnum.渤海:
case CompanyEnum.安粮:
case CompanyEnum.润和:
case CompanyEnum.中基石化:
return true;
default: return false;
}
}
public static double? GetInitialMarginRatio(trade trade)
{
switch (PS.Config.Company)
{
case CompanyEnum.方顿:
return FDMarginCalculation.Instance.GetInitialMarginRatio(trade);
default:
return 0;
}
}
public static double? GetPositionMarginRatio(trade trade)
{
switch (PS.Config.Company)
{
case CompanyEnum.方顿:
return FDMarginCalculation.Instance.GetPositionMarginRatio(trade);
default:
return 0;
}
}
public static double GetInitialMarginWithPreHandle(trade trade)
{
var tradeClone = trade.Clone();
tradeBLL.SetFieldsByTradeType(tradeClone);
var realTradeId = tradeClone.id;
tradeClone.id = 0;
tradeClone.VolType = "报价Bid";
tradeClone.TradeCloseVolatility = null;//不设置为null会影响计算结果
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeClone.UnderlyingCode);
tradeClone.StockEqvNotional = tradeClone.OriginalStockEqvNotional ?? 0;
tradeClone.Notional = tradeClone.OriginalNotional ?? 0;
tradeClone.TradeAmount = underlying != null && underlying.CountRatio != 0 ? tradeClone.Notional / underlying.CountRatio : tradeClone.Notional;
if (!tradeClone.TTMDays.HasValue)
{
tradeClone.TTMDays = TradeCalcHelper.CalculateTTMDays(tradeClone.TradeDate.Value, tradeClone.ExerciseDate.Value,
underlying?.UnderlyingTypeId ?? 0, PS.Config.ErpElement.PrecisionOfMinuteInQuote);
}
return GetInitialMargin(tradeClone, realTradeId, true);
}
public static double GetInitialMargin(trade trade, int realTradeId, bool hasOptionInfo = false)
{
if (trade is null)
{
return 0;
}
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
trade.MaturityDate = um?.MaturityDate;
///关于交易id的多义性: 1.组合交易需要真实的交易id;2.考虑到波动率不能获取持仓波动率,将id赋值为0;3.定价页面结构化交易子交易id会赋值-1和-2
var req = new GetTradeMarginReq
{
realTradeId = realTradeId,
trade = trade,
price = trade.SpotPrice ?? 0,
hasOptionInfo = hasOptionInfo,
calcMarginType = CalcMarginTypeEnum.InitialMargin
};
return GetTradeMargin(req);
}
/// <summary>
/// isInitialMargin为true: 为初始预付金
/// isInitialMargin为false: 为实时预付金
/// </summary>
public static double GetTradeMargin(GetTradeMarginReq req)
{
if (req.trade.TradeType == "结构化交易")
{
var option = StructureOption_Code.StructureOptions.FirstOrDefault(o => o.Name == req.trade.StructureType || o.CnName == req.trade.StructureType);
//自由组合时不在变更StructureType字段值,保持原有结构化交易的内容;
if (option != null)
{
req.trade.StructureType = option.CnName;
}
}
double? tempInitialMargin = null;
if (req.calcMarginType != CalcMarginTypeEnum.InitialMargin && req.trade.CalcFlag == 1)
{
tempInitialMargin = req.trade.InitialMargin;
req.trade.InitialMargin = null;
}
try
{
if (req.trade.TradeType == "现金流交易")
{
return 0;
}
else if (req.trade.MarginType != MarginTypeEnum.DEFAULT)
{
var result = SingleMarginCalculation(req.GetRunMarginCalculationReq());
return (result.FirstOrDefault()?.WorstCastClientPayable) ?? 0;
}
else
{
switch (PS.Config.Company)
{
case CompanyEnum.渤海:
return BHRSMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.安粮:
return BHRSMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.申万:
return SYWGMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.茂川资本:
return MaoChuanMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.宏源:
return HongYuanMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.伴兴:
return BXMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.海通:
return HaiTongMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.瑞达:
return RDMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.兴证:
return XingZhengMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.弘业:
return HongYeMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.广期资本:
return GQMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.方顿:
return FDMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.国海:
return GuoHaiMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.华安:
return HuaAnMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.浙期:
return ZheQiMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.润和:
return DongZhengRunHeMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.国投:
return GuoTouMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.湘财:
return XiangCaiMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.中粮:
return ZhongLiangMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.长江:
return ChangJiangMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.国信金阳:
return GuoXinJinYangMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.东吴:
return DongWuMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.格林大华:
#if DEBUG
return GLDHMarginCalculation.Instance.GetTradeMargin(req);
#endif
case CompanyEnum.广发商贸:
return GFSMMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.国泰君安:
case CompanyEnum.上期资本:
case CompanyEnum.光大光子:
return GTJAMarginCalculation.Instance.GetTradeMargin(req);
case CompanyEnum.招证:
return ZhaoZhengMarginCalculation.Instance.GetTradeMargin(req);
default:
return DefaultMarginCalculation.Instance.GetTradeMargin(req);
}
}
}
finally
{
if (req.calcMarginType == CalcMarginTypeEnum.InitialMargin && req.trade.CalcFlag == 1 && req.trade.InitialMargin == null)
{
req.trade.InitialMargin = tempInitialMargin;
}
}
}
}
}