Files
zszq-trs/YLErpWeb/Controllers/OtcTradeControllerBase.cs
T
2024-05-09 14:06:26 +08:00

253 lines
12 KiB
C#

using Qdp.Pricing.Library.Options.Products.Asian;
using YLErp.DBModels.Helpers;
using YLErp.Enums;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.SalesModule;
using YLErp.Modules.TagModule;
using YLErp.Modules.TradeDalModule;
using YLErp.Modules.TradeModule;
namespace YLErp.Web.Controllers
{
public abstract class OtcTradeControllerBase : BaseController
{
public virtual ActionResult TradeView(string enid, bool isFromPositionReport = false, bool isOnlyCloseButton = false, string operationStatus = "")
{
ViewBag.BinaryCalculation = valuedateBLL.BinaryCalculation;
var intid = DecryptInt(enid);
var tradeObj = yldb.trade.Find(intid);
if (tradeObj == null)
{
return ShowError("没有找到交易数据");
}
tradeBLL.SetFieldsByTradeType(tradeObj);
TradeViewModel model;
//如果是结构化主交易则转成第一个子交易显示
if (tradeObj.TradeType == "结构化交易" && tradeObj.IsGroup == 0)
{
tradeObj = yldb.trade.FirstOrDefault(c => c.ParentTradeId == tradeObj.id);
}
var hasTradeProcess = HasTradeProcess();
tradeObj.MetaDic = new TradeMetaService(CurUser).GetTradeMeta(tradeObj.id);
if (tradeObj.MetaDic.ContainsKey("ActualExerciseDate") && DateTime.TryParse(tradeObj.MetaDic["ActualExerciseDate"],out DateTime newActualExerciseDate))
{
tradeObj.ActualExerciseDate = newActualExerciseDate;
}
model = new TradeViewModel(tradeObj)
{
IsFromPositionReport = isFromPositionReport,
BinaryCalculation = valuedateBLL.BinaryCalculation,
IsOnlyCloseButton = isOnlyCloseButton,
OperationStatus = operationStatus
};
if (model.Trade.trade_autocall != null && model.Trade.TradeType == "凤凰期权")
{
var koInfo = TradeObservationHelper.GetAutocallKOObservationAndCoupon(model.Trade.trade_autocall.KOObservationDates, model.Trade.trade_autocall.CouponBarrier);
model.Trade.trade_autocall.CouponObservation = koInfo.Item1;
model.Trade.trade_autocall.KOObservationDates = string.IsNullOrWhiteSpace(koInfo.Item2) ? null : koInfo.Item2;
}
//获取结构化交易伙伴交易
if (tradeObj.ParentTradeId > 0 && tradeObj.IsGroup == 0)
{
model.SubTrades = yldb.trade.AsNoTracking().Where(n => n.ParentTradeId == tradeObj.ParentTradeId)
.Select(t => new OtcTradeDto { id = t.id, BuySell = t.BuySell }).ToArray();
}
//获取交易现金数据
var tradeWithSettlement = new TradeDalService(CurUser).GetTradeWithSettlementTradeCash(tradeObj);
//获取交易销售提成数据
model.SalesCommission = new SalesCommissionDataService(CurUser).GetSalesCommissionInfoDtos(intid);
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1")
{
foreach (var item in model.SalesCommission)
{//为了迁就前端逻辑,前端展示时只取第一个;
item.Commission = item.Commission * model.SalesCommission.Count();
}
}
model.ClientCashInCashOutList = yldb.ClientCashInCashOut.Where(c => c.TradeId == intid && c.ValidState != ConsGlobal.InValid).ToList();
model.unWindTradeCashList = tradeWithSettlement.UnwindTradeCashList;
model.unwindChildrenTradeCashList = tradeWithSettlement.UnwindChildrenTradeCashList;
model.maturityTradeCash = tradeWithSettlement.MaturityTradeCash;
model.swapTradeCashList = tradeWithSettlement.SwapTradeCashList;
model.couponTradeCashList = tradeWithSettlement.CouponTradeCashList;
model.tradeMarginTemplates = new TradeQueryService(CurUser).SearchTradeMarginTemplateList(intid);
model.canEditMaturityDate = tradeObj.CanEditMaturityDate() && model.maturityTradeCash != null && CurUser.交易管理_到期修改;
//需要审批或者复核的交易都会显示行权审核提交按钮
model.IsShowReCheckClose = ((valuedateBLL.SystemDate.CloseReCheck == 1) ||
(valuedateBLL.SystemDate.CloseReApprove == 1 && hasTradeProcess)) && tradeObj.TradeStatus != ConsTrade.平仓待复核;
model.CanEdit = tradeObj.CanEdit() && !isFromPositionReport && CurUser.交易管理_交易编辑;
using (var tagService = new TagService(CurUser))
{
model.Tags = tagService.GetTagByTradeId(intid);
}
using (var tagService = new TagService(CurUser))
{
ViewBag.TagList = tagService.GetTagListByType(TagTypeEnum.Trade);
}
if (tradeObj.TradeType == "远期")
{
if (!string.IsNullOrWhiteSpace(tradeObj.OptionType))
{
tradeObj.OptionType = (tradeObj.OptionType == "看涨") ? "多头" : "空头";
}
if (!string.IsNullOrWhiteSpace(tradeObj.BasisUnderlyingCode))
{
ViewBag.Underlying2Name = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeObj.BasisUnderlyingCode)?.UnderlyingName;
}
if (model.Trade.Comments!=null && model.Trade.Comments.Contains("累计期权"))
{
model.Trade.AccumulatorOptionId = yldb.trade.FirstOrDefault(l => l.TradeNumber == model.Trade.Comments.Replace("累计期权:", ""))?.EncryptId;
}
return View("~/Views/ForwardTrade/TradeView.cshtml", model);
}
if (model.maturityTradeCash != null)
{
//对于历史过期交易到期的数据做一下处理;
//最新的到期交易,ValueDate不会大于ExerciseDate;
//敲出的交易,ValueDate会小于ExerciseDate。
model.maturityTradeCash.ValueDate = model.maturityTradeCash.ValueDate > tradeObj.ExerciseDate.Value ? tradeObj.ExerciseDate.Value : model.maturityTradeCash.ValueDate;
}
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeObj.UnderlyingCode);
if (um != null)
{
model.Trade.UnderlyingInstrumentType = um?.UnderlyingInstrumentType;
model.Trade.QuoteUnitSingle = ConsGlobal.InstrumentType.Stock.Equals(um?.UnderlyingInstrumentType) ? "元/股" : ("元/" + um.QuoteUnitString);
model.Trade.QuoteUnit = um.QuoteUnit;
//方顿 JD TradeUnit 录的是 千克 数量是用 吨 计算的
model.Trade.TradeUnit = um.QuoteUnit == "500千克" ? "吨" : um.TradeUnit;
model.Trade.CountRatio = um.CountRatio;
model.Trade.TradeAmount = model.Trade.Notional / um.CountRatio;
var v = DataCacheProvider.GetVarietyDataSource().GetData(um.UnderlyingTypeId);
model.Trade.QuoteCurrency = v != null ? v.QuoteCurrency : "";
}
SetTradeExtendForView(model);
if (model.CanEdit && tradeObj.ParentTradeId > 0)
{
var subTrades = yldb.trade.AsNoTracking().Where(n => n.ParentTradeId == tradeObj.ParentTradeId && n.id != tradeObj.id).ToArray();
model.CanEdit &= subTrades.All(t => t.CanEdit());
}
double exchangeRate = 0;
if (PS.Config.Company == Configuration.CompanyEnum.中粮 && !string.IsNullOrEmpty(model.Trade.QuoteCurrency) && !"CNY".Equals(model.Trade.QuoteCurrency)
&& model.Trade.OriginalStockEqvNotionalV2 != null && model.Trade.MetaDic.ContainsKey("ExchangeRate")
&& double.TryParse(model.Trade.MetaDic["ExchangeRate"], out exchangeRate))
{
model.OriginalStockEqvNotionalV2MultipleExchangeRate = ((double)model.Trade.OriginalStockEqvNotionalV2 * exchangeRate).OtcFormat(OtcFormatFlag.StockEqvNotional);
}
if (model.Trade.trade_accumulator_option != null && model.Trade.TradeType == "累计期权" && model.autoCallObsercationList.Where(l => !string.IsNullOrWhiteSpace(l.ConvTradeNumber)).Any())
{
model.autoCallObsercationList.Where(l => !string.IsNullOrWhiteSpace(l.ConvTradeNumber)).ToList().ForEach(o => o.ConvForwardTradeId = yldb.trade.FirstOrDefault(l => l.TradeNumber == o.ConvTradeNumber)?.EncryptId);
}
return View("~/Views/Trade/TradeView.cshtml", model);
}
//交易数据扩展
private void SetTradeExtendForView(TradeViewModel model)
{
var tradeObj = model.Trade;
switch (tradeObj.TradeType)
{
case "凤凰期权":
case "累计期权":
case "区间累积期权":
{
model.autoCallObsercationList = yldb.autocall_observation.Where(x => x.TradeId == tradeObj.id)
.OrderBy(n => n.EndDate).ToList();
break;
}
case "雪球期权":
{
try
{
model.autoCallObsercationList = new TradeSnowballService(CurUser).GetObservations(tradeObj.id, valuedateBLL.ValueDate);
if (model.autoCallObsercationList != null)
{
var tc = yldb.trade_cash.Where(c => c.TradeId == tradeObj.id && c.Action == ClientCashInCashOut.系统操作_票息 && !c.IsDeleted).FirstOrDefault();
model.autoCallObsercationList.ForEach(x =>
{
if (tc != null)
{
//tc的Amount包含了年化权利金,PaymentAmount代表的是票息,从detail获取
var detail = yldb.trade_cash_detail.Where(y => y.TradeCashId == tc.id && y.Action == ClientCashInCashOut.系统操作_票息).FirstOrDefault();
if (detail != null)
{
x.PaymentAmount = detail.Amount.Value;
}
else
{
x.PaymentAmount = TradeHelper.GetAmountByPaymentAmount(x.PaymentAmount, tradeObj.PrincipalSum(), tradeObj.BuySell);
}
}
else
{
x.PaymentAmount = TradeHelper.GetAmountByPaymentAmount(x.PaymentAmount, tradeObj.PrincipalSum(), tradeObj.BuySell);
}
});
}
}
catch (Exception ex)
{
ViewBag.Error = ex.Message;
}
break;
}
}
//Final Price赋值
if (tradeObj.TradeStatus != ConsTrade.确认成交 || tradeObj.ExerciseDate == null)
{
return;
}
if (tradeObj.TradeType != "现金流交易")
{
model.ClosePrice = EodPriceQueryService.GetClosePrice(tradeObj.ExerciseDate.Value, tradeObj.UnderlyingCode);
tradeObj.FinalPrice = model.ClosePrice;
}
if (tradeObj.TradeType == "亚式期权" && tradeObj.trade_asian_option != null
&& tradeObj.trade_asian_option.StrikeType != "Floating"
&& tradeObj.trade_asian_option.AveragingPeriodStartDate < valuedateBLL.ValueDate)
{
var QdpTrade = TradeCalcHelper.GetQdpTrade(tradeObj);
if (QdpTrade.Instrument is AsianOption asianOpt && asianOpt.Fixings?.Count > 0)
{
tradeObj.FinalPrice = asianOpt.FinalPrice();
}
}
}
protected bool HasTradeProcess()
{
return yldb.approvalprocess.Where(t => t.processType == "TradeProcess").Any();
}
}
}