213 lines
12 KiB
C#
213 lines
12 KiB
C#
using Qdp.Pricing.Base.Enums;
|
|
using YLErp.QdpModule;
|
|
|
|
namespace YLErp.Modules.TradeModule.OrderModule
|
|
{
|
|
/// <summary>
|
|
/// 扩展存储
|
|
/// </summary>
|
|
class TradeSaveExtend : YLBaseService
|
|
{
|
|
private readonly bool isAddNew;
|
|
|
|
public TradeSaveExtend(YLBaseService baseService, bool isAddNew)
|
|
: base(baseService)
|
|
{
|
|
this.isAddNew = isAddNew;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存并写入数据库
|
|
/// </summary>
|
|
public int Save(trade baseTrade, trade dbTrade, bool useSaveChange = true)
|
|
{
|
|
switch (baseTrade.TradeType == "结构化交易" ? baseTrade.StructureType : baseTrade.TradeType)
|
|
{
|
|
case "香草期权":
|
|
case "合成价差期权":
|
|
return 0;
|
|
case "亚式期权":
|
|
dbTrade.trade_asian_option = InnerSaveExtend(baseTrade, baseTrade.trade_asian_option);
|
|
break;
|
|
case "彩虹期权":
|
|
dbTrade.trade_rainbow_option = InnerSaveExtend(baseTrade, baseTrade.trade_rainbow_option);
|
|
break;
|
|
case "障碍期权":
|
|
dbTrade.trade_barrier_option = InnerSaveExtend(baseTrade, baseTrade.trade_barrier_option);
|
|
break;
|
|
case "二元期权":
|
|
dbTrade.trade_binary_option = InnerSaveExtend(baseTrade, baseTrade.trade_binary_option);
|
|
break;
|
|
case "价差期权":
|
|
dbTrade.trade_spread_option = InnerSaveExtend(baseTrade, baseTrade.trade_spread_option);
|
|
break;
|
|
case "双鲨期权":
|
|
dbTrade.trade_double_sharkfin_option = InnerSaveExtend(baseTrade, baseTrade.trade_double_sharkfin_option);
|
|
break;
|
|
case "凤凰期权":
|
|
if (string.IsNullOrEmpty(baseTrade.trade_autocall.KOObservationDates))
|
|
{
|
|
if (dbTrade.trade_autocall==null)
|
|
{
|
|
dbTrade.trade_autocall = new trade_autocall();
|
|
}
|
|
var autocallmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true);
|
|
dbTrade.trade_autocall.KOObservationDates = $"{string.Join(",", autocallmonthlyDates.Select(O => O.OtcFormatDate()))};" +
|
|
$"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.KOBarrier.OtcFormatFlex(2)))};" +
|
|
$"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.Coupon.OtcFormatFlex(2)))}";
|
|
baseTrade.trade_autocall.KOObservationDates = dbTrade.trade_autocall.KOObservationDates;
|
|
}
|
|
dbTrade.trade_autocall = InnerSaveExtend(baseTrade, baseTrade.trade_autocall);
|
|
break;
|
|
case "雪球期权":
|
|
if (string.IsNullOrEmpty(baseTrade.trade_snowball.KOObservationDates))
|
|
{
|
|
if (dbTrade.trade_snowball == null)
|
|
{
|
|
dbTrade.trade_snowball = new trade_snowball();
|
|
}
|
|
var snowballmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true);
|
|
|
|
dbTrade.trade_snowball.KOObservationDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))};" +
|
|
$"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KOBarrier.OtcFormatFlex(2)))};" +
|
|
$"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KORebate.OtcFormatFlex(2)))}";
|
|
if (dbTrade.trade_snowball.KOPayoffType == KOPayoffTypeEnum.Rebate)
|
|
{
|
|
baseTrade.trade_snowball.KOObservationSettleDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))}";
|
|
}
|
|
baseTrade.trade_snowball.KOObservationDates = dbTrade.trade_snowball.KOObservationDates;
|
|
}
|
|
dbTrade.trade_snowball = InnerSaveExtend(baseTrade, baseTrade.trade_snowball);
|
|
break;
|
|
case "区间累积期权":
|
|
dbTrade.trade_rangeaccrual = InnerSaveExtend(baseTrade, baseTrade.trade_rangeaccrual);
|
|
break;
|
|
case "气囊结构":
|
|
dbTrade.trade_airbag = InnerSaveExtend(baseTrade, baseTrade.trade_airbag);
|
|
break;
|
|
case "收益增强结构":
|
|
dbTrade.trade_underlying_enhance = InnerSaveExtend(baseTrade, baseTrade.trade_underlying_enhance);
|
|
break;
|
|
case "远期":
|
|
dbTrade.trade_forward = InnerSaveExtend(baseTrade, baseTrade.trade_forward);
|
|
break;
|
|
case "收益互换":
|
|
if (baseTrade.trade_swap.IsGetFloatingProfit)
|
|
{
|
|
var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.GetUnderlyingCode);
|
|
var CountRatio = underlyingManager?.CountRatio ?? 1;
|
|
baseTrade.trade_swap.GetNotional = baseTrade.trade_swap.GetTradeAmount * CountRatio;
|
|
|
|
dbTrade.OriginalNotional = baseTrade.trade_swap.GetNotional;
|
|
dbTrade.Notional = baseTrade.trade_swap.GetNotional ?? 0;
|
|
dbTrade.TradeAmount = baseTrade.trade_swap.GetTradeAmount ?? 0;
|
|
dbTrade.SpotPrice = baseTrade.trade_swap.GetSpotPrice;
|
|
}
|
|
if (baseTrade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.PayUnderlyingCode);
|
|
var CountRatio = underlyingManager?.CountRatio ?? 1;
|
|
baseTrade.trade_swap.PayNotional = baseTrade.trade_swap.PayTradeAmount * CountRatio;
|
|
|
|
dbTrade.OriginalNotional = baseTrade.trade_swap.PayNotional;
|
|
dbTrade.Notional = baseTrade.trade_swap.PayNotional ?? 0;
|
|
dbTrade.TradeAmount = baseTrade.trade_swap.PayTradeAmount ?? 0;
|
|
dbTrade.SpotPrice = baseTrade.trade_swap.PaySpotPrice;
|
|
}
|
|
DbContext.SaveChanges();
|
|
dbTrade.trade_swap = InnerSaveExtend(baseTrade, baseTrade.trade_swap);
|
|
dbTrade.get_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.get_trade_swap_details, true);
|
|
dbTrade.pay_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.pay_trade_swap_details, false);
|
|
if (baseTrade.ParentTradeId > 0)
|
|
{
|
|
var detail = DbContext.trade_swap_detail.FirstOrDefault(x => x.TradeId == baseTrade.ParentTradeId && x.ChildTradeId == baseTrade.id);
|
|
if (detail != null)
|
|
{
|
|
detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort;
|
|
detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional;
|
|
detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode;
|
|
detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice;
|
|
detail.OriginalNotional = detail.Notional;
|
|
}
|
|
else
|
|
{
|
|
detail = new trade_swap_detail()
|
|
{
|
|
IsForGet = baseTrade.trade_swap.IsGetFloatingProfit
|
|
};
|
|
detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort;
|
|
detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional;
|
|
detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode;
|
|
detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice;
|
|
detail.OriginalNotional = detail.Notional;
|
|
detail.TradeId = baseTrade.ParentTradeId;
|
|
detail.ChildTradeId = baseTrade.id;
|
|
DbContext.trade_swap_detail.Add(detail);
|
|
}
|
|
DbContext.SaveChanges();
|
|
}
|
|
break;
|
|
case "现金流交易":
|
|
dbTrade.trade_cashflow = InnerSaveExtend(baseTrade, baseTrade.trade_cashflow);
|
|
break;
|
|
case "自定义交易":
|
|
dbTrade.trade_custom = InnerSaveExtend(baseTrade, baseTrade.trade_custom);
|
|
break;
|
|
case "累计期权":
|
|
dbTrade.trade_accumulator_option = InnerSaveExtend(baseTrade, baseTrade.trade_accumulator_option);
|
|
break;
|
|
case "Risky期权":
|
|
dbTrade.trade_risky_option = InnerSaveExtend(baseTrade, baseTrade.trade_risky_option);
|
|
break;
|
|
default: return 0;
|
|
}
|
|
|
|
return useSaveChange ? DbContext.SaveChanges() : 0;
|
|
}
|
|
|
|
private List<trade_swap_detail> InnerSaveTradeSwapDetail(trade baseTrade, List<trade_swap_detail> tradeSwapDetails, bool isForGet)
|
|
{
|
|
if (tradeSwapDetails != null && tradeSwapDetails.Any())
|
|
{
|
|
var tradeSwapDetailsExist = DbContext.trade_swap_detail.Where(x => x.TradeId == baseTrade.id && x.IsForGet == isForGet);
|
|
DbContext.trade_swap_detail.RemoveRange(tradeSwapDetailsExist);
|
|
tradeSwapDetails.ForEach(x =>
|
|
{
|
|
x.ExerciseDate = baseTrade.ExerciseDate;
|
|
x.IsForGet = isForGet;
|
|
x.OriginalNotional = x.Notional;
|
|
x.SwapTimeAndRate = isForGet ? baseTrade.trade_swap.PaySwapTimeAndRate : baseTrade.trade_swap.GetSwapTimeAndRate;
|
|
x.TradeId = baseTrade.id;
|
|
SetDBModelOpt(x);
|
|
});
|
|
DbContext.trade_swap_detail.AddRange(tradeSwapDetails);
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
return tradeSwapDetails;
|
|
}
|
|
|
|
//保存扩展数据
|
|
private T InnerSaveExtend<T>(trade baseTrade, T extend) where T : TradeExtendBase
|
|
{
|
|
SetDBModelOpt(extend);
|
|
|
|
extend.TradeId = baseTrade.id;
|
|
|
|
var exist = isAddNew ? null : DbContext.Set<T>().FirstOrDefault(n => n.TradeId == baseTrade.id);
|
|
|
|
if (exist == null)
|
|
{
|
|
extend.id = 0;
|
|
DbContext.Set<T>().Add(extend);
|
|
}
|
|
else
|
|
{
|
|
extend.id = exist.id;
|
|
UpdateEntity(exist, extend);
|
|
}
|
|
return extend;
|
|
}
|
|
}
|
|
}
|