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

227 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()
{
}
/// <summary>
/// 完整预付金公式:
/// </summary>
/// <param name="req"></param>
/// <param name="td"></param>
/// <param name="dt"></param>
/// <param name="tradeRiskResult"></param>
/// <returns></returns>
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<trade> { 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;
}
/// <summary>
/// 标的结算价的公式为:
/// If 期权类别 = “亚式”:
/// If 当前估值日期 <= 亚式采价起始日:
/// 标的结算价 = 当日收盘价
/// Else:
/// 标的结算价 = (标的前结算价*(已采价期-1) + 当日收盘价* (剩余天数+1))/(已采价期+剩余天数)
/// Elseif 期权类别 = “价差欧式” OR 期权类别 = “价差互换” OR "欧式"
/// 标的结算价 = 当日结算价
/// </summary>
/// <param name="req"></param>
/// <param name="td"></param>
/// <returns></returns>
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;
}
}
}