using Qdp.Pricing.Base.Implementations;
using System.Data;
using YLErp.BLL.Calculation;
using YLErp.Commons;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.MarginModule;
namespace YLErp.BLL.MarginCalculation
{
public class XingYeMarginCalculation : MarginCalculationBase
{
// 定义一个静态变量来保存类的实例
public static readonly XingYeMarginCalculation Instance;
static XingYeMarginCalculation()
{
Instance = new XingYeMarginCalculation();
}
// 定义私有构造函数,使外界不能创建该类实例
protected XingYeMarginCalculation()
{
}
///
/// 完整预付金公式:
///
///
///
///
///
///
public static double TradeMargin(RunMarginCalculationReq req, trade td)
{
var sourcePath = OtcAppContext.MapPath("~/App_Docs");
var sourceFileName = Path.Combine(sourcePath, "Delta调整系数表.xlsx");
DataTable dt = new ExcelHelper().ExcelToDataTable(sourceFileName, "", true);
UnderlyingDataProvider _underlyingDataProvider = new UnderlyingDataProvider();
var reqConv = new CalculateRisksForTradesReq
{
valueDate = req.settleDate,
tradeList = new List { td },
priceProvider = req.PriceProvider,
pricingRequest = PricingRequest.Pv | PricingRequest.Delta | PricingRequest.Gamma,
addVolRateDic = null,
volType = req.volType,
isUseTradeVol = PS.Config.IsTradeVol,
PreciseTimeMode = req.CalcMarginType != Enums.CalcMarginTypeEnum.EodMargin,
isAddVolPercent = true,
overrideVolsForTrade = null,
isMarginCalc = true
};
if (req.CalcMarginType == Enums.CalcMarginTypeEnum.EodMargin)
{
reqConv.calcScenario = Enums.CalcScenarioEnum.EodSettlement;
}
var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(reqConv);
double ITM = 0;
double Margin_part = 0;
double Margin_part1 = 0;
double Margin_part2 = 0;
double maxMarginRate = 0;
new EodPriceProvider(req.settleDate, false).TryGetEodPrice(td.UnderlyingCode, out var eodPrice);
double Delta = -1;
double coefficient = 0;
var udm = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
var udmA = new underlying_manager();
var udmB = new underlying_manager();
var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider);
var mpProvider = helper.GetMarginParamProvider(MarginParamTypeEnum.MarginRate | MarginParamTypeEnum.UpDownLimit);
mpProvider.TryGetMarginRate(td.UnderlyingCode, out var marginRate);
if (eodPrice == null)
{
eodPrice = new EodPrice();
eodPrice.SettlePrice = td.SpotPrice ?? 0;
}
if (td.TradeType == "收益互换")
{
Delta = 1;
ITM = 0;
}
else
{
if (td.OptionType == "看涨")
{
ITM = (eodPrice.SettlePrice - (td.IsMoneynessOption == "是" ? (td.Strike.Value * td.SpotPrice.Value) : td.Strike.Value));
ITM = ITM > 0 ? ITM : 0;
}
else
{
ITM = ((td.IsMoneynessOption == "是" ? (td.Strike.Value * td.SpotPrice.Value) : td.Strike.Value) - eodPrice.SettlePrice);
ITM = ITM > 0 ? ITM : 0;
}
Delta = Math.Round((tradeRiskResult.Results.Where(x => x.Trade.id == td.id).FirstOrDefault().ValueResult.Delta / td.Notional), 2);
}
if (td.TradeType == "收益互换" || (td.ExerciseMode == "European" && string.IsNullOrEmpty(td.StructureType)))
{
//预付金_part1 = ((ABS(Delta) * VLOOKUP(ABS(ROUND(Delta,2)), Delta调整系数表, 2, FALSE)
//* 标的结算价 * ABS(标的规模) * 交易所预付金率) + 实值部分 * ABS(标的规模) )
DataRow[] drs2 = dt.Select("Delta='" + Math.Abs(Delta) + "'", "Delta desc");//维持系数
if (drs2.Count() > 0)
coefficient = Convert.ToDouble(drs2[0]["维持系数"]);
Margin_part1 = (Math.Abs(Delta) * coefficient
* SettlePrice(req.settleDate, td) * Math.Abs(td.TradeAmount) * marginRate);
}
else if (udm.CommodityCode == "组合标的" && td.TradeType == "收益互换")
{
//1*I2101-1*I2009
var UnderlyingCode = td.trade_swap.GetUnderlyingCode == null ? td.trade_swap.PayUnderlyingCode : td.trade_swap.GetUnderlyingCode;
var UnderlyingCodeS = UnderlyingCode.Split(new char[] { '-', '+' }).ToList(); //多字节切割
//new EodPriceProvider(req.settleDate, false).TryGetEodPrice(UnderlyingCodeS[0].Split('*')[1], out eodPriceA);
//new EodPriceProvider(req.settleDate, false).TryGetEodPrice(UnderlyingCodeS[1].Split('*')[1], out eodPriceB);
//udmA = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCodeS[0].Split('*')[1]);
//udmB = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCodeS[1].Split('*')[1]);
foreach (var code in UnderlyingCodeS)
{
if (code.Contains("*"))
{
udm = DataCacheProvider.GetUnderlyingDataSource().GetData(code.Split('*')[1]);
if (udm.MarginRate != null)
{
maxMarginRate = maxMarginRate > udm.MarginRate.Value ? maxMarginRate : udm.MarginRate.Value;
}
}
}
//预付金_part1 = (标的A收盘价 - 标的B收盘价) * ABS(标的规模) * 交易所预付金率 * 0.9
Margin_part1 = (eodPrice.ClosePrice) * Math.Abs(td.TradeAmount) * maxMarginRate * 0.9;
}
else if (udm.CommodityCode == "组合标的" && td.ExerciseMode == "European")
{
var UnderlyingCode = td.trade_swap.GetUnderlyingCode == null ? td.trade_swap.PayUnderlyingCode : td.trade_swap.GetUnderlyingCode;
var UnderlyingCodeS = UnderlyingCode.Split(new char[] { '-', '+' }).ToList(); //多字节切割
//new EodPriceProvider(req.settleDate, false).TryGetEodPrice(UnderlyingCodeS[0].Split('*')[1], out eodPriceA);
//new EodPriceProvider(req.settleDate, false).TryGetEodPrice(UnderlyingCodeS[1].Split('*')[1], out eodPriceB);
//udmA = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCodeS[0].Split('*')[1]);
//udmB = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCodeS[1].Split('*')[1]);
foreach (var code in UnderlyingCodeS)
{
if (code.Contains("*"))
{
udm = DataCacheProvider.GetUnderlyingDataSource().GetData(code.Split('*')[1]);
if (udm.MarginRate != null)
{
maxMarginRate = maxMarginRate > udm.MarginRate.Value ? maxMarginRate : udm.MarginRate.Value;
}
}
}
//预付金_part1 = (标的A收盘价 + 标的B收盘价)/2 * ABS(标的规模) * 交易所预付金率
Margin_part1 = ((eodPrice.ClosePrice) / 2) * Math.Abs(td.TradeAmount) * maxMarginRate;
}
//预付金_part2 = 期权实值部门 * ABS(标的规模)
Margin_part2 = ITM * Math.Abs(td.TradeAmount);
Margin_part = Margin_part2 + Margin_part1;
return Margin_part;
}
///
/// 标的结算价的公式为:
/// If 期权类别 = “亚式”:
/// If 当前估值日期 <= 亚式采价起始日:
/// 标的结算价 = 当日收盘价
/// Else:
/// 标的结算价 = (标的前结算价*(已采价期-1) + 当日收盘价* (剩余天数+1))/(已采价期+剩余天数)
/// Elseif 期权类别 = “价差欧式” OR 期权类别 = “价差互换” OR "欧式":
/// 标的结算价 = 当日结算价
///
///
///
///
private static double SettlePrice(DateTime settleDate, trade td)
{
EodPrice eodPrice = null;
double settlePrice = 0;
new EodPriceProvider(settleDate, false).TryGetEodPrice(td.UnderlyingCode, out eodPrice);
if (eodPrice == null)
{
eodPrice = new EodPrice();
eodPrice.SettlePrice = td.SpotPrice ?? 0;
}
var udm = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
if (td.TradeType == "亚式期权")
{
if (settleDate <= td.trade_asian_option.AveragingPeriodStartDate)
{
return eodPrice.ClosePrice;
}
else
{
TimeSpan sp = Convert.ToDateTime(settleDate).Subtract(td.trade_asian_option.AveragingPeriodStartDate.Value);
TimeSpan sp1 = Convert.ToDateTime(td.ExerciseDate.Value).Subtract(settleDate);
return (eodPrice.SettlePrice * (sp.Days - 1) + eodPrice.ClosePrice * (sp1.Days + 1)) / (sp.Days + sp1.Days);
}
}
else if (udm.CommodityCode == "组合标的" && td.ExerciseMode == "European")
{
return eodPrice.SettlePrice;
}
else if (udm.CommodityCode == "组合标的" && td.TradeType == "收益互换")
{
return eodPrice.SettlePrice;
}
else if (td.ExerciseMode == "European")
{
return eodPrice.SettlePrice;
}
else
return settlePrice;
}
}
}