Files
zszq-trs/YLErpDAL/Modules/TradeModule/KnockOutModule/AccumulatorTradeKnockOutService.cs
T
2024-05-09 14:06:26 +08:00

113 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YLErp.Abstract;
using YLErp.DBModels;
using YLErp.Modules.TradeModule.AccumulatorOptionModule;
using YLErp.Modules.TradeModule.KnockOutModule.Dto;
namespace YLErp.Modules.TradeModule.KnockOutModule
{
/// <summary>
/// 累计期权敲出计算服务
/// </summary>
public class AccumulatorTradeKnockOutService : ITradeKnockOutService
{
/// <summary>
/// 获取敲出payoff
/// </summary>
/// <param name="td"></param>
/// <param name="underlyingPrice"></param>
/// <param name="_valueDate"></param>
/// <param name="_tradeExtendDataProvider"></param>
/// <returns></returns>
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider)
{
var accumulatorOption = _tradeExtendDataProvider.GetTrade_Accumulator_Option(td.id);
if (accumulatorOption == null)
{
return new GetKnockOutPayoffResult { IsKnockOut = false };
}
td.trade_accumulator_option = accumulatorOption;
return GetKnockOutPayoff(td, underlyingPrice, _valueDate);
}
/// <summary>
/// 获取敲出payoff
/// </summary>
/// <param name="td"></param>
/// <param name="underlyingPrice"></param>
/// <param name="_valueDate"></param>
/// <param name="accumulatorOption"></param>
/// <returns></returns>
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate)
{
GetKnockOutPayoffResult result = new GetKnockOutPayoffResult { IsKnockOut = false };
var accumulatorOption = td.trade_accumulator_option;
if (accumulatorOption == null)
{
return result;
}
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
var notional = accumulatorOption.AccumuTradeAmount * underlying.CountRatio;
var changeData = GetChangeDataOfSepecialDay(td.id, _valueDate);
CheckResult checkResult = null;
if (changeData != null)
{
//关键点:还原换月设置到交易时不要更新当前传入的trade和tradeAcc,因为这两个数据涉及到数据库更新
var tdClone = new trade();
YLAutoMapper.Map<trade, trade>(td, tdClone);
var tdAccClone = accumulatorOption.Clone();
tdClone.trade_accumulator_option = accumulatorOption;
TradeAccumulatorHelper.RestoreAccumulatorChangeData(tdClone, tdAccClone, changeData);
checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(tdClone, tdAccClone, _valueDate, underlyingPrice, notional);
}
else
{
checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(td, accumulatorOption, _valueDate, underlyingPrice, notional);
}
if (checkResult != null && "敲出".Equals(checkResult.SettlementMode) && accumulatorOption.EarlyTerminate)
{
result.IsKnockOut = true;
result.Payoff = 0;
}
return result;
}
/// <summary>
/// 获取累计期权换月设置
/// </summary>
/// <param name="tradeId"></param>
/// <param name="valueDate"></param>
/// <returns></returns>
private TradeAccumulatorChangeData GetChangeDataOfSepecialDay(int tradeId, DateTime valueDate)
{
using(var db = DbContextFactory.GetYLDbContext())
{
var query = from a in db.TradeAction.AsNoTracking()
where a.IsValid && a.TradeId == tradeId && a.ValueDate <= valueDate && a.ActionType == TradeActionType.AccumulatorChange
orderby a.ValueDate descending
select a.ActionData;
var actionData = query.FirstOrDefault();
if (string.IsNullOrEmpty(actionData))
{
return null;
}
return JsonHelper.Deserialize<TradeAccumulatorChangeData>(actionData);
}
}
}
}