从山证v2.3.0拷贝

This commit is contained in:
吴方海
2024-05-09 14:06:26 +08:00
parent 566ff33259
commit f9d8a256a6
4471 changed files with 1203456 additions and 9 deletions
@@ -0,0 +1,141 @@
using CsvHelper;
using Qdp.Foundation.Implementations;
using Qdp.Pricing.Library.Options.Products.Autocall.Snowball;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YLErp.Abstract;
using YLErp.BLL;
using YLErp.DBModels;
using YLErp.DBModels.Helpers;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.TradeModule.ExoticOptionModule;
using YLErp.Modules.TradeModule.KnockOutModule.Dto;
namespace YLErp.Modules.TradeModule.KnockOutModule
{
/// <summary>
/// 雪球期权敲出计算服务
/// </summary>
public class SnowBallTradeKnockOutService : ITradeKnockOutService
{
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider)
{
var snowBallOption = _tradeExtendDataProvider.GetTrade_Snowball_Option(td.id);
if (snowBallOption == null)
{
return new GetKnockOutPayoffResult { IsKnockOut = false };
}
td.trade_snowball = snowBallOption;
return GetKnockOutPayoff(td, underlyingPrice, _valueDate);
}
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate)
{
GetKnockOutPayoffResult result = new GetKnockOutPayoffResult { IsKnockOut = false };
var snowBallOption = td.trade_snowball;
if (snowBallOption == null)
{
return result;
}
if (snowBallOption.PrepaymentUsed)
{
var specialSnowBallResult = new SpecialSnowballObservationHelper(td, snowBallOption).GetObservationResultForTraderSide(_valueDate, underlyingPrice, td.Notional);
if (specialSnowBallResult != null && specialSnowBallResult.ResultType == SnowballObservationResultType.KoPayoff)
{
result.IsKnockOut = true;
result.Payoff = specialSnowBallResult.PaymentAmount;
}
return result;
}
var request = new OptionTradeParamRequest(valuedateBLL.SysRiskFreeRate())
{
ParamOverride = p => p.notional = td.Notional
};
var optionTrade = QdpTradeBuilder.GetSnowballOptionTrade(td, snowBallOption, request);
var snowball = (SimpleSnowball)optionTrade.Instrument;
var isCall = ConsGlobal.CallPut.IsCall(td.CallPut);
if (snowball.KOObsDates.Select(x => x.DateTime).Contains(_valueDate))
{
(var koSettleDate, var koBarrier) = GetSnowBallKoSettleInfo(_valueDate, td, snowBallOption, snowball);
// 发生敲出事件(看涨 - 向上敲出支付票息,看跌 - 向下敲出支付票息)
if (isCall ? underlyingPrice >= koBarrier : underlyingPrice <= koBarrier)
{
result.IsKnockOut = true;
if (snowball.UseOptionPayoffAtKO)
{
double paymentAmount = 0;
var koOptionCashflows = snowball.GetKOPayoff(new Date(_valueDate), underlyingPrice);
paymentAmount = TradeHelper.GetAmountByPaymentAmount(koOptionCashflows[0].PaymentAmount, td.PrincipalSum(), td.BuySell);
result.Payoff = paymentAmount;
}
else
{
var CouponPayment = snowball.CouponPayment(_valueDate, includeStartDate: snowBallOption.CouponIncludeStartDate == true && snowBallOption.CouponDayCount != "Monthly");
var couponPayment = TradeHelper.GetAmountByPaymentAmount(CouponPayment, td.PrincipalSum(), td.BuySell);
if (snowBallOption.AnnualizedPremiumRate.HasValue && snowBallOption.AnnualizedPremiumRate != 0)
{
var tradePrice = (td.StockEqvNotional * td.ParticipationRate * snowBallOption.AnnualizedPremiumRate * snowball.CouponDayCount.CalcDayCountFraction(snowball.StartDate, new Date(_valueDate))) ?? 0;
if (tradePrice != 0)
{
couponPayment += (td.BuySell == "买入" ? -1 : 1) * tradePrice;
}
}
result.Payoff = couponPayment;
}
}
}
return result;
}
//获取雪球期权敲出时要准备的信息
public (DateTime koSettleDate, double koBarrier) GetSnowBallKoSettleInfo(DateTime valueDate, OtcTradeBase otcTrade, trade_snowball tradeSnowball, SimpleSnowball snowball)
{
double koBarrier;
var koSettleDate = valueDate;
var datesStr = tradeSnowball.KOObservationSettleDates;
var KOObsSettleDates = string.IsNullOrWhiteSpace(datesStr) ? null : datesStr.Split(new char[] { ',', ';', '', '' }, StringSplitOptions.RemoveEmptyEntries).Select(x => DateTime.Parse(x)).ToArray();
if (snowball.CustomizedKOBarriers != null && snowball.CustomizedKOBarriers.Length > 0)
{
var index = snowball.KOObsDates.Select(x => x.DateTime).ToList().IndexOf(valueDate);
koBarrier = snowball.CustomizedKOBarriers[index];
if (KOObsSettleDates != null && KOObsSettleDates.Length > index)
{
koSettleDate = KOObsSettleDates[index];
}
}
else
{
koBarrier = tradeSnowball.KOBarrier;
if (KOObsSettleDates != null && KOObsSettleDates.Any())
{
koSettleDate = KOObsSettleDates[0];
}
}
if (tradeSnowball.KORebateType == RebateTypeEnum.AtEnd)
{
koSettleDate = otcTrade.ExerciseDate.Value;
}
else if (koSettleDate < valueDate)
{
koSettleDate = valueDate;
}
if (otcTrade.IsMoneynessOptionData)
{
koBarrier *= otcTrade.SpotPrice ?? 1.0;
}
return (koSettleDate, koBarrier);
}
}
}