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

535 lines
24 KiB
C#

using Org.BouncyCastle.Ocsp;
using Qdp.Foundation.Utilities;
using YLErp.Commons;
using YLErp.CustomizedBizLogic;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.DBModels.Helpers;
using YLErp.Modules.ClientModule;
using YLErp.Modules.TradeModule.DealModule;
using static NPOI.HSSF.Util.HSSFColor;
namespace YLErp.Modules.TradeModule.ExoticOptionModule
{
public class TradeCashServiceEx : TradeCashService
{
public TradeCashServiceEx(YLBaseService baseService) : base(baseService)
{
}
public TradeCashServiceEx(OptUserInfo userInfo) : base(userInfo)
{
}
public trade_cash SaveGroupUnwindCash(OtcTradeBase otcTrade, DateTime valueDate, double paymentAmount, double closePrice, out bool continueTradeCashHandle)
{
var childrenTrades = DbContext.trade.Where(x => x.ParentTradeId == otcTrade.ParentTradeId && x.ValidState != "InValid");
//子交易观察调用该方法处理主交易时,当前子交易会了结,但还没存数据库,所以只需要判断其他子交易是否已了结即可
var isAllCompleted = childrenTrades.Where(x => x.id != otcTrade.id).All(x => ConsTrade.TradeCompleteStatus.Contains(x.TradeStatus));
var parentTrade = DbContext.trade.Find(otcTrade.ParentTradeId);
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(parentTrade.UnderlyingCode);
var tradeCashIds = DbContext.trade_cash.Where(x => x.TradeId == otcTrade.ParentTradeId && x.ValueDate == valueDate).Select(x => x.id);
var tradeCashGroupAction = DbContext.trade_cash_group_action.FirstOrDefault(x => tradeCashIds.Contains(x.ParentTradeCashId) && x.IsEodSettle);
var tradeCash = new trade_cash();
if (tradeCashGroupAction != null)
{
tradeCash = DbContext.trade_cash.Find(tradeCashGroupAction.ParentTradeCashId);
var action = DbContext.trade_cash_group_action.FirstOrDefault(x => x.ParentTradeCashId == tradeCashGroupAction.ParentTradeCashId && x.TradeId == otcTrade.id);
if (action != null)
{
if (!action.IsFinishedUnwindPercent)
{
tradeCash.Amount += paymentAmount;
tradeCash.OptId = UserId;
tradeCash.OptName = UserName;
tradeCash.OptDate = DateTime.Now;
if (isAllCompleted)
{
tradeCash.IsLastAction = true;
}
action.IsFinishedUnwindPercent = true;
}
else
{
continueTradeCashHandle = false;
return tradeCash;
}
}
else
{
tradeCash.Amount += paymentAmount;
tradeCash.OptId = UserId;
tradeCash.OptName = UserName;
tradeCash.OptDate = DateTime.Now;
if (isAllCompleted)
{
tradeCash.IsLastAction = true;
tradeCash.UnwindNotional = tradeCash.Notional;
tradeCash.UnwindTradeAmount = tradeCash.TradeAmount;
tradeCash.UnwindPercentRate = 1;
}
tradeCashGroupAction = new trade_cash_group_action()
{
IsEodSettle = true,
TradeId = otcTrade.id,
ParentTradeId = otcTrade.ParentTradeId,
ParentTradeCashId = tradeCash.id,
Status = "已完成",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
IsFinishedUnwindPercent = true
};
DbContext.trade_cash_group_action.Add(tradeCashGroupAction);
}
}
else
{
tradeCash = new trade_cash()
{
Action = ClientCashInCashOut.系统操作_票息,
IsLastAction = false,
TradeType = parentTrade.BuySell,
Notional = parentTrade.Notional,
TradeAmount = parentTrade.TradeAmount,
TradeId = otcTrade.ParentTradeId,
HappenedDate = valueDate,
ValueDate = valueDate,
FinalPrice = closePrice,
Status = TradeCashStatusEnum.已执行,
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now
};
tradeCash.Amount += paymentAmount;
if (isAllCompleted)
{
tradeCash.IsLastAction = true;
tradeCash.UnwindNotional = tradeCash.Notional;
tradeCash.UnwindTradeAmount = tradeCash.TradeAmount;
tradeCash.UnwindPercentRate = 1;
}
DbContext.trade_cash.Add(tradeCash);
DbContext.SaveChanges();
#region---存入ClientCashInCashOut---
var cl = ClientDataQueryService.GetClient(parentTrade.ClientId, true);
var ee = new ClientCashInCashOut
{
Direction = "应收",
Number = UniqueTimeId.GetStr(),
ClientId = cl.id,
ClientNumber = cl.Number,
ClientName = cl.Name,
HappenDate = tradeCash.ValueDate,
State = ClientCashInCashOut.已确认,
OptId = tradeCash.OptId,
OptName = tradeCash.OptName,
OptDate = tradeCash.OptDate,
CreatorId = tradeCash.OptId,
CreatorName = tradeCash.OptName,
CreateDate = tradeCash.OptDate,
TradeId = tradeCash.TradeId,
TradeCashId = tradeCash.id,
Action = tradeCash.Action,
TradeNumber = tradeCash.TradeNumber,
IsGroup = parentTrade.IsGroup
};
DbContext.ClientCashInCashOut.Add(ee);
#endregion
tradeCashGroupAction = new trade_cash_group_action()
{
IsEodSettle = true,
TradeId = otcTrade.id,
ParentTradeId = otcTrade.ParentTradeId,
ParentTradeCashId = tradeCash.id,
Status = "已完成",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
IsFinishedUnwindPercent = true
};
DbContext.trade_cash_group_action.Add(tradeCashGroupAction);
}
if (isAllCompleted)
{
parentTrade.UnWindNotional = parentTrade.Notional;
parentTrade.UnWindDate = tradeCash.ValueDate;
parentTrade.FinalPrice = tradeCash.FinalPrice;
}
parentTrade.OptId = UserId;
parentTrade.OptName = UserName;
parentTrade.OptDate = DateTime.Now;
DbContext.SaveChanges();
if (BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess())
{
if (PS.Config.SalesCommissionCalculation == "公式1")
{
//销售提成
new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tradeCash);
}
if (PS.Config.Company == Configuration.CompanyEnum.招证)
{
new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(parentTrade, tradeCash);
}
if (PS.Config.Company == Configuration.CompanyEnum.物产中大)
{
new BizLogicWCZD().GenerateWCZDNumber(DbContext, parentTrade, tradeCash.ValueDate, tradeCash.id);
}
}
if (tradeCash.IsLastAction)
{
var tradeIds = DbContext.trade_cash_group_action.Where(x => x.ParentTradeCashId == tradeCash.id).Select(x => x.TradeId).ToList();
var tradeStatusList = DbContext.trade.Where(x => tradeIds.Contains(x.id)).Select(x => x.TradeStatus).ToList();
if (tradeStatusList.Contains(ConsTrade.已执行))
{
parentTrade.TradeStatus = ConsTrade.已执行;
}
else if (tradeStatusList.Contains(ConsTrade.已到期))
{
parentTrade.TradeStatus = ConsTrade.已到期;
}
else
{
parentTrade.TradeStatus = ConsTrade.已平仓;
}
}
DbContext.SaveChanges();
continueTradeCashHandle = true;
return tradeCash;
}
public int SaveGroupCouponCash(OtcTradeBase trade, DateTime happenDate, double paymentAmount, double underlyingPrice)
{
var parentTradeCashId = 0;
var childrenTrades = DbContext.trade.Where(x => x.ParentTradeId == trade.ParentTradeId && x.ValidState != "InValid");
var parentTrade = DbContext.trade.Find(trade.ParentTradeId);
var tradeCashIds = DbContext.trade_cash.Where(x => x.TradeId == trade.ParentTradeId && x.ValueDate == happenDate).Select(x => x.id);
var tradeCashGroupAction = DbContext.trade_cash_group_action.FirstOrDefault(x => tradeCashIds.Contains(x.ParentTradeCashId) && x.IsEodSettle);
var tradeCash = new trade_cash();
if (tradeCashGroupAction != null)
{
parentTradeCashId = tradeCashGroupAction.ParentTradeCashId;
if (DbContext.trade_cash_group_action.Any(x => x.ParentTradeCashId == tradeCashGroupAction.ParentTradeCashId && x.TradeId == trade.id))
{
return parentTradeCashId;
}
else
{
tradeCash = DbContext.trade_cash.Find(tradeCashGroupAction.ParentTradeCashId);
tradeCash.Amount += paymentAmount;
tradeCash.OptId = UserId;
tradeCash.OptName = UserName;
tradeCash.OptDate = DateTime.Now;
tradeCashGroupAction = new trade_cash_group_action()
{
IsEodSettle = true,
TradeId = trade.id,
ParentTradeId = trade.ParentTradeId,
ParentTradeCashId = tradeCash.id,
Status = "已完成",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
IsFinishedUnwindPercent = false
};
DbContext.trade_cash_group_action.Add(tradeCashGroupAction);
}
}
else
{
tradeCash = new trade_cash()
{
Action = ClientCashInCashOut.系统操作_票息,
IsLastAction = false,
TradeType = parentTrade.BuySell,
Notional = parentTrade.Notional,
TradeAmount = parentTrade.TradeAmount,
Amount = paymentAmount,
TradeId = trade.ParentTradeId,
HappenedDate = happenDate,
ValueDate = happenDate,
FinalPrice = underlyingPrice,
Status = TradeCashStatusEnum.已执行,
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now
};
DbContext.trade_cash.Add(tradeCash);
DbContext.SaveChanges();
parentTradeCashId = tradeCash.id;
tradeCashGroupAction = new trade_cash_group_action()
{
IsEodSettle = true,
TradeId = trade.id,
ParentTradeId = trade.ParentTradeId,
ParentTradeCashId = tradeCash.id,
Status = "已完成",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
IsFinishedUnwindPercent = false
};
DbContext.trade_cash_group_action.Add(tradeCashGroupAction);
DbContext.SaveChanges();
#region---存入ClientCashInCashOut---
var cl = ClientDataQueryService.GetClient(parentTrade.ClientId, true);
var ee = new ClientCashInCashOut
{
Direction = "应收",
Number = UniqueTimeId.GetStr(),
ClientId = cl.id,
ClientNumber = cl.Number,
ClientName = cl.Name,
HappenDate = tradeCash.ValueDate,
State = ClientCashInCashOut.已确认,
OptId = tradeCash.OptId,
OptName = tradeCash.OptName,
OptDate = tradeCash.OptDate,
CreatorId = tradeCash.OptId,
CreatorName = tradeCash.OptName,
CreateDate = tradeCash.OptDate,
TradeId = tradeCash.TradeId,
TradeCashId = tradeCash.id,
Action = tradeCash.Action,
TradeNumber = tradeCash.TradeNumber,
IsGroup = parentTrade.IsGroup
};
DbContext.ClientCashInCashOut.Add(ee);
#endregion
}
parentTrade.OptId = UserId;
parentTrade.OptName = UserName;
parentTrade.OptDate = DateTime.Now;
DbContext.SaveChanges();
if (BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess())
{
if (PS.Config.SalesCommissionCalculation == "公式1")
{
//销售提成
new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tradeCash);
}
if (PS.Config.Company == Configuration.CompanyEnum.招证)
{
new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(parentTrade, tradeCash);
}
if (PS.Config.Company == Configuration.CompanyEnum.物产中大)
{
new BizLogicWCZD().GenerateWCZDNumber(DbContext, parentTrade, tradeCash.ValueDate, tradeCash.id);
}
}
return parentTradeCashId;
}
//如果两个票息的结算日设为同一天的情况下,用这个方法保存票息有问题
public trade_cash SaveCash(OtcTradeBase trade, string cashAction, string exerciseWay, double paymentAmount, DateTime valueDate, double underlyingPrice, DateTime happenDate, bool isKnockOut = false, bool isLastAction = false, int parentTradeId = 0, int parentTradeCashId = 0)
{
var notional = trade.Notional;
var tradeAmount = trade.TradeAmount;
// 保存trade_cash
var tc = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == trade.id && t.Action == cashAction && !t.IsDeleted && t.HappenedDate == happenDate);
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
//暂时只应用于累计期权的观察部分行权处理
trade_accumulator_option accumulator = new trade_accumulator_option();
if (trade.TradeType == "累计期权")
{
accumulator = DbContext.trade_accumulator_option.FirstOrDefault(x => x.TradeId == trade.id);
tc = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == trade.id && t.Action == "系统操作-平仓费" && t.UnwindType == "部分行权" && !t.IsDeleted && t.HappenedDate == happenDate);
if (tc == null)
{
trade.TradeAmount -= accumulator.AccumuTradeAmount;
trade.Notional = trade.TradeAmount * underlying.CountRatio;
trade.StockEqvNotional = TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor);
}
}
if (tc == null)
{
tc = new trade_cash();
DbContext.trade_cash.Add(tc);
tc.Notional = notional;
tc.TradeAmount = tradeAmount;
}
else
{
if (paymentAmount == 0)
{
//如果是最后一笔资金记录但是查出来的tc没有设置最后一笔资金标识则重新设置
if (isLastAction && !tc.IsLastAction)
{
tc.IsLastAction = true;
tc.UnwindNotional = trade.Notional;
tc.UnwindTradeAmount = trade.TradeAmount;
tc.UnwindPercentRate = trade.Notional / trade.OriginalNotional;
DbContext.SaveChanges();
}
return tc;
}
if (trade.TradeType != "累计期权")
{
tc.Notional = notional;
tc.TradeAmount = tradeAmount;
}
}
tc.ValidState = null;
tc.OptId = UserId;
tc.OptName = UserName;
tc.OptDate = DateTime.Now;
tc.ExceciseType = "现金";
tc.TradeType = trade.BuySell;
tc.CallPut = trade.CallPut;
tc.Amount = paymentAmount;
tc.TradeId = trade.id;
tc.ParentTradeId = parentTradeId;
tc.ParentTradeCashId = parentTradeCashId;
tc.HappenedDate = happenDate;
if (trade.TradeType == "累计期权" && (cashAction == "部分行权" || cashAction == "到期行权"))
{
if (cashAction == "部分行权")
{
tc.Action = ClientCashInCashOut.系统操作_平仓费;
tc.UnwindType = "部分行权";
tc.ExerciseWay = TradeCashExerciseWayEnum.提前终止行权;
}
else if (cashAction == "到期行权")
{
tc.Action = ClientCashInCashOut.系统操作_行权费;
tc.UnwindType = "到期";
tc.ExerciseWay = TradeCashExerciseWayEnum.到期行权;
}
tc.UnwindTradeAmount = accumulator.AccumuTradeAmount;
tc.UnwindNotional = accumulator.AccumuTradeAmount * underlying.CountRatio;
tc.UnwindPrice = Math.Abs(accumulator.AccumuTradeAmount != 0 ? paymentAmount / accumulator.AccumuTradeAmount : 0);
tc.UnwindPricePercentRate = Math.Abs(accumulator.AccumuTradeAmount != 0 && trade.SpotPrice != null && trade.SpotPrice != 0 ? paymentAmount / accumulator.AccumuTradeAmount / trade.SpotPrice.Value : 0);
tc.UnwindPercentRate = accumulator.AccumuTradeAmount * underlying.CountRatio / trade.OriginalNotional;
tc.NotionalPercentRate = tc.UnwindPercentRate;
}
else
{
tc.Action = cashAction;
tc.ExerciseWay = exerciseWay;
tc.UnwindPrice = Math.Abs(trade.Notional != 0 ? paymentAmount / trade.Notional : 0);
tc.UnwindPricePercentRate = Math.Abs(trade.Notional != 0 && trade.SpotPrice != null && trade.SpotPrice != 0 ? paymentAmount / trade.Notional / trade.SpotPrice.Value : 0);
tc.NotionalPercentRate = trade.Notional / trade.OriginalNotional;
}
tc.IsLastAction = isLastAction;
if (exerciseWay == "到期行权")
{
tc.UnwindType = "到期";
if (cashAction == ClientCashInCashOut.系统操作_票息 && tc.Amount == 0)
{
tc.Action = ClientCashInCashOut.系统操作_行权费;
}
}
tc.Status = TradeCashStatusEnum.已执行;
tc.ValueDate = valueDate;
tc.FinalPrice = underlyingPrice;
if (isKnockOut)
{
tc.BarrierPrice = trade.IsMoneynessOptionData && trade.SpotPrice != 0 ? (underlyingPrice / trade.SpotPrice) : underlyingPrice;
}
if (isLastAction && !(cashAction == "部分行权" && trade.TradeType == "累计期权"))
{
tc.UnwindNotional = notional;
tc.UnwindTradeAmount = tradeAmount;
tc.UnwindPercentRate = notional / trade.OriginalNotional;
}
tc.NotionalPercentRate = trade.Notional / trade.OriginalNotional;
DbContext.SaveChanges();
var tradeCashDetails = DbContext.trade_cash_detail.Where(x => x.TradeCashId == tc.id);
DbContext.trade_cash_detail.RemoveRange(tradeCashDetails);
SaveTradeCashDetail(tc);
if ((BLL.valuedateBLL.SystemDate.CloseReApprove != 1 || !HasTradeProcess()) || isKnockOut || isLastAction)
{
if (PS.Config.SalesCommissionCalculation == "公式1")
{
//销售提成
new SalesModule.SalesCommissionDetailDataService(UserInfo).CalcuSalesCommissionDetail(tc);
}
if (PS.Config.Company == Configuration.CompanyEnum.招证)
{
new BizLogicZhaoZheng().GenerateZhaoZhengDealNumber(trade, tc);
}
if (PS.Config.Company == Configuration.CompanyEnum.物产中大 && cashAction!=ClientCashInCashOut.系统操作_期权费)
{
new BizLogicWCZD().GenerateWCZDNumber(DbContext, trade, tc.ValueDate, tc.id);
}
}
// 保存ClientCashInCashOut
var client = DbContextFactory.GetClientDbContext(UserInfo).client.Where(n => n.id == trade.ClientId)
.Select(n => new { n.id, n.Number, n.Name }).FirstOrDefault();
if (client == null)
{
throw new Exception($"{trade.TradeType}'{trade.TradeNumber}'找不到客户信息,客户id:{trade.ClientId}");
}
var cashInOutRecord = DbContext.ClientCashInCashOut.FirstOrDefault(c => c.TradeCashId == tc.id);
if (cashInOutRecord == null)
{
cashInOutRecord = new ClientCashInCashOut();
cashInOutRecord.CreateDate = tc.OptDate;
cashInOutRecord.CreatorId = tc.OptId;
cashInOutRecord.CreatorName = tc.OptName;
DbContext.ClientCashInCashOut.Add(cashInOutRecord);
}
cashInOutRecord.Direction = "应收";
cashInOutRecord.Number = UniqueTimeId.GetStr();
cashInOutRecord.ClientId = client.id;
cashInOutRecord.ClientNumber = client.Number;
cashInOutRecord.ClientName = client.Name;
cashInOutRecord.Money = -tc.Amount;
cashInOutRecord.HappenDate = valueDate;
cashInOutRecord.State = ClientCashInCashOut.已确认;
cashInOutRecord.OptDate = tc.OptDate;
cashInOutRecord.OptId = tc.OptId;
cashInOutRecord.OptName = tc.OptName;
cashInOutRecord.TradeId = trade.id;
cashInOutRecord.TradeCashId = tc.id;
cashInOutRecord.Action = tc.Action;
cashInOutRecord.TradeNumber = trade.TradeNumber;
cashInOutRecord.IsGroup = trade.IsGroup;
DbContext.SaveChanges();
return tc;
}
}
}