从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Qdp.Foundation.Implementations;
|
||||
using Qdp.Pricing.Library.Options.Products.Autocall.Snowball;
|
||||
using YLErp.Modules.CalculationModule;
|
||||
using YLErp.Modules.TradeModule.ExoticOptionModule;
|
||||
|
||||
namespace YLErp.Modules.TradeModule
|
||||
{
|
||||
public class TradeSnowballService : YLBaseService
|
||||
{
|
||||
public TradeSnowballService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
}
|
||||
|
||||
public TradeSnowballService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
}
|
||||
|
||||
public List<autocall_observation> GetObservations(int tradeId, DateTime valueDate)
|
||||
{
|
||||
var trade = DbContext.trade.FirstOrDefault(t => t.id == tradeId);
|
||||
var tradeSnowball = DbContext.trade_snowball.FirstOrDefault(t => t.TradeId == tradeId);
|
||||
if (trade == null || tradeSnowball == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果是敲出转期权,则不支付票息
|
||||
if (tradeSnowball.KOPayoffType != KOPayoffTypeEnum.Rebate)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (trade.TradeStatus == ConsTrade.已到期 || trade.TradeStatus == ConsTrade.已执行 || trade.TradeStatus.Contains("待确认"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var optionTrade = QdpTradeBuilder.GetSnowballOptionTrade(trade, tradeSnowball);
|
||||
|
||||
if (optionTrade == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var snowball = (SimpleSnowball)optionTrade.Instrument;
|
||||
|
||||
var observationEndDate =
|
||||
tradeSnowball.KnockInOutStatus == ConsTrade.KnockState.KnockedOut ?
|
||||
tradeSnowball.KnockInOutDate.Value :
|
||||
valueDate;
|
||||
var qdpEndDate = new Date(observationEndDate);
|
||||
qdpEndDate = snowball.KOObsDates.Where(d => d <= qdpEndDate).Max();
|
||||
|
||||
var observation = snowball.GetEffectiveObservation(qdpEndDate, tradeSnowball.CouponIncludeStartDate ?? false);
|
||||
|
||||
if (tradeSnowball.PrepaymentUsed)
|
||||
{
|
||||
var payoff = new SpecialSnowballObservationHelper(trade, tradeSnowball).GetEffectiveObservation(qdpEndDate, optionTrade.Notional);
|
||||
|
||||
observation = payoff == null ? null : new Qdp.Pricing.Library.Options.Products.Autocall.Phoenix.ObservationPayment
|
||||
{
|
||||
CouponRate = payoff.CouponRate,
|
||||
EndDate = payoff.CouponEndDate,
|
||||
PaymentAmount = payoff.CouponPaymentAmount,
|
||||
PaymentDate = qdpEndDate,
|
||||
StartDate = payoff.CouponStartDate,
|
||||
Notional = Math.Abs(optionTrade.Notional * (trade.SpotPrice ?? 0))
|
||||
};
|
||||
}
|
||||
if (observation == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tradeCashCoupon = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == tradeId && t.Action == "系统操作-票息" && t.ValidState != "InValid" && !t.IsDeleted);
|
||||
var tradeCashDetial = tradeCashCoupon != null ? DbContext.trade_cash_detail.FirstOrDefault(x => x.TradeCashId == tradeCashCoupon.id && x.Action == "系统操作-期权费") : null;
|
||||
return new List<autocall_observation>()
|
||||
{
|
||||
new autocall_observation {
|
||||
StartDate = observation.StartDate.DateTime,
|
||||
EndDate = observation.EndDate.DateTime,
|
||||
CouponRate = observation.CouponRate,
|
||||
StockEqvNotional = Math.Abs(observation.Notional),
|
||||
PaymentAmount = observation.PaymentAmount,
|
||||
AnnualizedPremiumRate = tradeSnowball.AnnualizedPremiumRate,
|
||||
AnnualizedTradePrice = tradeCashDetial?.Amount ?? 0,
|
||||
PaymentDate =
|
||||
tradeSnowball.KnockInOutStatus == ConsTrade.KnockState.KnockedOut ?
|
||||
tradeCashCoupon?.ValueDate ?? observationEndDate:
|
||||
observation.PaymentDate.DateTime
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public double GetKOOptionPayoff(int tradeId, DateTime valueDate, double price)
|
||||
{
|
||||
var trade = DbContext.trade.AsNoTracking().FirstOrDefault(t => t.id == tradeId);
|
||||
var tradeSnowball = DbContext.trade_snowball.AsNoTracking().FirstOrDefault(t => t.TradeId == tradeId);
|
||||
return GetKOOptionPayoff(trade, tradeSnowball, valueDate, price);
|
||||
}
|
||||
|
||||
public double GetKOOptionPayoff(OtcTradeBase trade, trade_snowball tradeSnowball, DateTime valueDate, double price)
|
||||
{
|
||||
if (trade == null || tradeSnowball == null)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (tradeSnowball.KOPayoffType == KOPayoffTypeEnum.Rebate)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
var optionTrade = QdpTradeBuilder.GetSnowballOptionTrade(trade, tradeSnowball);
|
||||
var snowball = (SimpleSnowball)optionTrade.Instrument;
|
||||
var payoffs = snowball.GetKOPayoff(new Date(valueDate), price);
|
||||
if (payoffs != null && payoffs.Length > 0)
|
||||
{
|
||||
return payoffs[0].PaymentAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user