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

2408 lines
130 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BaseOUDAL;
using Qdp.Foundation.Implementations;
using System.Data;
using System.Linq.Expressions;
using YLErp.BLL;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules.DataCacheModule;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.EodModule;
using YLErp.Modules.TradeModule.DealModule;
using YLErp.Modules.TradeModule.QueryModule;
using YLErp.Modules.TradeModule.QueryModule.Dto;
using YLErp.Modules.TradeRiskCalcModule;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeModule
{
/// <summary>
/// 当日交易(当日成交、提前终止、当日到期、明日到期)查询服务
/// </summary>
public class TodayTradeQueryService : YLBaseService
{
public TodayTradeQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
public TdTradesCountSum GetTdTradesCountSum(List<int> userAssets, List<int> userClients, OtcTradeType otcTradeType)
{
var sum = new TdTradesCountSum();
var curTradingDate = SystemValueDate;
var basePredicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid"
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2);
switch (otcTradeType)
{
case OtcTradeType.Forward:
basePredicate = basePredicate.And(t => t.TradeType == "远期");
break;
case OtcTradeType.EquitySwap:
basePredicate = basePredicate.And(t => t.TradeType == "收益互换");
break;
default:
basePredicate = basePredicate.And(t => t.TradeType != "远期" && t.TradeType != "收益互换" && t.ClientId > 0);
break;
}
var dateEnd = curTradingDate.AddDays(1);
//---------------------------------------------
// 当日到期
//---------------------------------------------
//如果前一天是假日,要显示包含假日的交易
var req = new TdTradeQueryModel
{
OtcTradeType = otcTradeType,
TabIndex = (int)TradeTabIndexEnum.今日到期,
UserAssets = userAssets,
UserClients = userClients
};
var predicate = BuildPredicate(req, curTradingDate);
sum.TdExerciseCount = DbContext.trade.Where(predicate).Count();
//---------------------------------------------
// 明日到期
//---------------------------------------------
var nextDay = QdpCalendarHelper.GetNonHoliday(curTradingDate.AddDays(1));
var excludeStatusArr = new[] { ConsTrade.已平仓, ConsTrade.已到期, ConsTrade.已执行 };
predicate = PredicateBuilder.Create<trade>(t => t.ExerciseDate == nextDay
&& !excludeStatusArr.Contains(t.TradeStatus)).And(basePredicate);
sum.TmExerciseCount = DbContext.trade.Where(predicate).Count();
//---------------------------------------------
// 当日提前终止
//---------------------------------------------
IQueryable<trade> baseTrade;
//交易员对应的簿记账户筛选或者客户经理对应的客户筛选
if (userAssets != null || userClients != null)
{
baseTrade = DbContext.trade.Where(t => userAssets.Contains(t.AssetId) || userClients.Contains(t.ClientId)).AsQueryable();
}
else
{
baseTrade = DbContext.trade.AsQueryable();
}
if (otcTradeType == OtcTradeType.Forward)
{
baseTrade = baseTrade.Where(x => x.TradeType == "远期");
var query1 = from tc in DbContext.trade_cash
join t in baseTrade on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& tc.Action == ClientCashInCashOut.系统操作_平仓费 && (t.TradeStatus == "平仓待复核" || tc.ValidState != ConsGlobal.InValid)
&& !tc.IsDeleted && tc.BarrierPrice == null
&& t.ValidState != "InValid"
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
select t.id;
sum.TdEarlyStoppedCount = query1.Count();
}
else if (otcTradeType == OtcTradeType.EquitySwap)
{
baseTrade = baseTrade.Where(x => x.TradeType == "收益互换");
var query1 = from tc in DbContext.trade_cash
join t in baseTrade on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& (tc.Action == ClientCashInCashOut.系统操作_平仓费 || tc.Action == ClientCashInCashOut.系统操作_互换) && (t.TradeStatus == "平仓待复核" || t.TradeStatus == "互换待复核" || tc.ValidState != "InValid")
&& !tc.IsDeleted && tc.BarrierPrice == null
&& t.ValidState != "InValid"
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
select t.id;
sum.TdEarlyStoppedCount = query1.Count();
}
else
{
baseTrade = DbContext.trade.Where(x => x.TradeType != "远期" && x.TradeType != "收益互换");
var query1 = from tc in DbContext.trade_cash
join t in baseTrade on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& tc.Action == ClientCashInCashOut.系统操作_平仓费 && (t.TradeStatus == "平仓待复核" || tc.ValidState != "InValid")
&& !tc.IsDeleted && tc.BarrierPrice == null
&& t.ValidState != ConsGlobal.InValid
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
select t.id;
var query2 = from tc in DbContext.trade_cash
join t in baseTrade on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& tc.Action == ClientCashInCashOut.系统操作_行权费 && (t.TradeStatus == "行权待复核" || tc.ValidState != "InValid" && t.TradeStatus == ConsTrade.已执行)
&& t.ExerciseMode == "American" && tc.ExerciseWay != "到期行权"
&& !tc.IsDeleted && tc.BarrierPrice == null //不包含敲出数据
&& t.ValidState != ConsGlobal.InValid
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
select t.id;
var dd1 = query1.Count();
var dd2 = query2.Count();
sum.TdEarlyStoppedCount = dd1 + dd2;
}
//---------------------------------------------
// 当日成交
//---------------------------------------------
predicate = PredicateBuilder.Create<trade>(t => t.TradeDate == curTradingDate).And(basePredicate);
sum.TdCreatedCount = DbContext.trade.Where(predicate).Count();
//---------------------------------------------
// 当日敲出
//---------------------------------------------
//var knockedOutPredicate = PredicateBuilder.Create<trade_barrier_option>(t => t.KnockInOutDate < dateEnd && t.KnockInOutDate >= curTradingDate && t.KnockInOutStatus == trade_barrier_option.KnockedOut);
//sum.TdKnockedOutCount = DbContext.trade_barrier_option.Where(knockedOutPredicate).Count();
var knockedOutQuery = from tc in DbContext.trade_cash
join t in DbContext.trade on tc.TradeId equals t.id
join ao in DbContext.autocall_observation on new { EndDate = tc.ValueDate, TradeId = t.id } equals new { ao.EndDate, ao.TradeId } into tempAo
from ao in tempAo.DefaultIfEmpty()
where tc.BarrierPrice != null //障碍期权敲出
&& tc.HappenedDate >= curTradingDate && tc.HappenedDate < dateEnd
&& t.ValidState != "InValid"
&& t.TradeType != "结构化交易"
&& !tc.IsDeleted
select 1;
sum.TdKnockedOutCount = knockedOutQuery.Count();
return sum;
}
//替换TradeBLL.SearchListForTradeConfirm
/// <summary>
/// 获取当日成交/当日到期/明日到期数据列表
/// </summary>
public SearchListResult<trade> GetConfirmList(TdTradeQueryModel req)
{
var valueDate = SystemValueDate;
var predicate = BuildPredicate(req, valueDate);
var tQuery = DbContext.trade.Where(predicate);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeNumber";
req.sord = "desc";
}
var sList = tQuery.ToSearchList(req);
if (sList.rows != null && sList.rows.Any())
{
//var realtimerisk = realtime_trade_riskBLL.GetAllrealtime_trade_valueModel();
//var tradeIds = sList.rows.Select(x => x.id).ToList();
//var tradeCashQuery = from tc in DbContext.trade_cash
// where tradeIds.Contains(tc.TradeId) && (tc.Action == ClientCashInCashOut.系统操作_行权费 || tc.Action == ClientCashInCashOut.系统操作_票息 || tc.Action == ClientCashInCashOut.系统操作_互换) && tc.ValidState != "InValid"
// && !tc.IsDeleted && tc.Status == TradeCashStatusEnum.已执行 && tc.BarrierPrice == null //不包含敲出数据
// select tc;
//var tradeCashDatas = tradeCashQuery.ToArray();
//未用到
//var underlyingIds = sList.rows.Select(x => x.UnderlyingId).ToList();
//var underlyings = DbContext.underlying_manager.Where(x => underlyingIds.Contains(x.id)).ToArray();
//var underlyingTypeIds = underlyings.Select(x => x.UnderlyingTypeId).Distinct();
//var varietys = DbContext.variety.Where(x => underlyingTypeIds.Contains(x.id)).ToArray();
var result = TradeRiskCalcTaskRunner.GetCalcResult("对冲");
//new TradeDalModule.TradeDalService(this).SetStructureInfo(sList.rows);
var tradeIdList = sList.rows.Select(p => p.id).Distinct().ToList();
var realtimerisk = realtime_trade_riskBLL.GetByTradeIds(tradeIdList);
if (realtimerisk == null)
{
realtimerisk = new List<realtime_trade_risk>();
}
List<trade_cash> tradeCashList = null;
var tradeCacheBatchGetService = new BatchGetTradeRelationDataService<trade_cash>();
if (tradeIdList != null && tradeIdList.Count > 0)
{
//tradeCashList = DbContext.trade_cash.AsNoTracking().Where(t => tradeIdList.Contains(t.TradeId) && t.ValidState != "Invalid" && t.BarrierPrice == null && !t.IsDeleted).ToList();
tradeCashList = tradeCacheBatchGetService.GetListByWhere(t => tradeIdList.Contains(t.TradeId) && t.ValidState != "Invalid" && t.BarrierPrice == null && !t.IsDeleted, DbContext.trade_cash);
}
if (tradeCashList == null)
{
tradeCashList = new List<trade_cash>();
}
var tradeCashDatas = tradeCashList.Where(tc => (tc.Action == ClientCashInCashOut.系统操作_行权费 || tc.Action == ClientCashInCashOut.系统操作_票息 || tc.Action == ClientCashInCashOut.系统操作_互换) && tc.Status == TradeCashStatusEnum.已执行).ToList();
if (tradeCashDatas == null)
{
tradeCashDatas = new List<trade_cash>();
}
List<trade_cash> childTradeCashList = null;
var parentTradeIds = sList.rows.Where(p => p.IsGroup == 1).Select(p => p.id).Distinct().ToList();
List<TradeQueryDto> childTradeList = null;
if (parentTradeIds != null && parentTradeIds.Count > 0)
{
childTradeList = DbContext.trade.AsNoTracking().Where(p => parentTradeIds.Contains(p.ParentTradeId) && p.ParentTradeId > 0).Select(p => new TradeQueryDto
{
id = p.id,
TradePrice = p.TradePrice,
BuySell = p.BuySell,
ParentTradeId = p.ParentTradeId,
ValidState = p.ValidState
}).ToList();
if (childTradeList != null && childTradeList.Count > 0)
{
var childTradeIds = childTradeList.Select(p => p.id).Distinct().ToList();
//childTradeCashList= DbContext.trade_cash.AsNoTracking().Where(t => childTradeIds.Contains(t.TradeId)).ToList();
var parentTradeCashIdList = tradeCashList.Where(p => parentTradeIds.Contains(p.TradeId) && p.Action != ClientCashInCashOut.系统操作_期权费).Select(p => p.id).Distinct().ToList();
if (parentTradeCashIdList != null && parentTradeCashIdList.Count > 0)
{
//childTradeCashList = DbContext.trade_cash.AsNoTracking().Where(t => parentTradeCashIdList.Contains(t.ParentTradeCashId)).ToList();
//childTradeCashList = DbContext.trade_cash.AsNoTracking().Where(t => childTradeIds.Contains(t.TradeId) && parentTradeCashIdList.Contains(t.ParentTradeCashId)).ToList();
childTradeCashList = tradeCacheBatchGetService.GetListByWhere(t => childTradeIds.Contains(t.TradeId) && parentTradeCashIdList.Contains(t.ParentTradeCashId), DbContext.trade_cash);
}
}
}
if (childTradeCashList == null)
{
childTradeCashList = new List<trade_cash>();
}
if (childTradeList == null)
{
childTradeList = new List<TradeQueryDto>();
}
var forwardTradeIds = sList.rows.Where(p => "远期".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
List<trade_forward> tradeForwardList = null;
if (forwardTradeIds != null && forwardTradeIds.Count > 0)
{
tradeForwardList = DbContext.trade_forward.AsNoTracking().Where(p => forwardTradeIds.Contains(p.TradeId)).ToList();
}
if (tradeForwardList == null)
{
tradeForwardList = new List<trade_forward>();
}
var swapTradeIds = sList.rows.Where(p => "收益互换".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
List<trade_cash_swap> tradeCashSwapList = null;
if (swapTradeIds != null && swapTradeIds.Count > 0)
{
var swapTradeCashIds = tradeCashList.Where(t => t.Action == ClientCashInCashOut.系统操作_互换).Select(d => d.id).Distinct().ToList();
if (swapTradeCashIds != null && swapTradeCashIds.Count > 0)
{
tradeCashSwapList = DbContext.trade_cash_swap.AsNoTracking().Where(p => swapTradeCashIds.Contains(p.TradeCashId)).ToList();
}
}
if (tradeCashSwapList == null)
{
tradeCashSwapList = new List<trade_cash_swap>();
}
Dictionary<int, TradeSalesCommissionInfo> keyValueSalesC = null;
using (var saleCService = new SalesModule.SalesCommissionDataService(OptUser))
{
keyValueSalesC = saleCService.GetTradeCommissionInfoByTradeIds(tradeIdList);
}
List<SyntheticUnderlying> syntheticUnderlyingList = null;
var syntheticUnderlyingCodeList = sList.rows.Where(p => "合成价差期权".Equals(p.TradeType)).Select(p => p.UnderlyingCode).Distinct().ToList();
if (syntheticUnderlyingCodeList != null && syntheticUnderlyingCodeList.Count > 0)
{
syntheticUnderlyingList = DbContext.synthetic_underlying.AsNoTracking().Where(p => syntheticUnderlyingCodeList.Contains(p.Name)).ToList();
}
if (syntheticUnderlyingList == null)
{
syntheticUnderlyingList = new List<SyntheticUnderlying>();
}
foreach (var tradeObj in sList.rows)
{
var underlying = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(tradeObj.UnderlyingCode);
if (tradeObj.TradeStatus == "已执行" || tradeObj.TradeStatus == "已到期" || tradeObj.TradeStatus == "已平仓")
{
tradeObj.TradeAmount = 0;
}
var tradeCash = tradeCashDatas.OrderByDescending(x => x.id).FirstOrDefault(d => d.TradeId == tradeObj.id);
ProcessTrade(tradeObj, tradeCash, underlying, syntheticUnderlyings: syntheticUnderlyingList);//最后一笔到期结算流水
if (tradeObj.TradeType == "远期")
{
//tradeObj.trade_forward = DbContext.trade_forward.First(x => x.TradeId == tradeObj.id);
tradeObj.trade_forward = tradeForwardList.First(x => x.TradeId == tradeObj.id);
}
//var cashTrades = DbContext.trade_cash.Where(t => t.ValidState != "Invalid" && t.TradeId == tradeObj.id && t.BarrierPrice == null && !t.IsDeleted).ToList();
var cashTrades = tradeCashList.Where(t => t.TradeId == tradeObj.id).ToList();
var cashTradesExercise = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_行权费).ToList();
var cashTradesUnwind = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_平仓费).ToList();
if (tradeObj.TradeType == "收益互换")
{
var cashTradesSwap = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_互换).ToList();
var lastTradeCashSwap = cashTradesSwap.OrderByDescending(x => x.ValueDate).FirstOrDefault();
if (lastTradeCashSwap != null)
{
//tradeObj.trade_cash.trade_cash_swap = DbContext.trade_cash_swap.FirstOrDefault(x => x.TradeCashId == lastTradeCashSwap.id);
tradeObj.trade_cash.trade_cash_swap = tradeCashSwapList.FirstOrDefault(x => x.TradeCashId == lastTradeCashSwap.id);
}
tradeObj.RealizedPnl = cashTradesSwap.Sum(x => x.Amount) - tradeObj.TradePrice * cashTradesSwap.Sum(x => x.UnwindPercentRate) * ((tradeObj.BuySell == "卖出") ? -1 : 1)
+ cashTradesUnwind.Sum(x => x.Amount) - tradeObj.TradePrice * cashTradesUnwind.Sum(x => x.UnwindPercentRate) * ((tradeObj.BuySell == "卖出") ? -1 : 1);
}
else
{
tradeObj.RealizedPnl = cashTradesExercise.Sum(x => x.Amount) - tradeObj.TradePrice * cashTradesExercise.Sum(x => x.UnwindPercentRate) * ((tradeObj.BuySell == "卖出") ? -1 : 1)
+ cashTradesUnwind.Sum(x => x.Amount) - tradeObj.TradePrice * cashTradesUnwind.Sum(x => x.UnwindPercentRate) * ((tradeObj.BuySell == "卖出") ? -1 : 1);
if (tradeObj.IsGroup == 1)
{
var cashTradeIds = cashTrades.Where(t => t.Action != ClientCashInCashOut.系统操作_期权费).Select(t => t.id).ToArray();
//var childrenCashTradesSettle = DbContext.trade_cash.Where(t => cashTradeIds.Contains(t.ParentTradeCashId)).ToList();
var childrenCashTradesSettle = childTradeCashList.Where(t => cashTradeIds.Contains(t.ParentTradeCashId)).ToList();
var childrenTradeIds = childrenCashTradesSettle.Select(x => x.TradeId).Distinct().ToArray();
//var childrenTrades = DbContext.trade.Where(t => childrenTradeIds.Contains(t.id));
var childrenTrades = childTradeList.Where(t => childrenTradeIds.Contains(t.id));
var realizedPnl = 0.0;
childrenCashTradesSettle.ForEach(x =>
{
var trade = childrenTrades.FirstOrDefault(y => y.id == x.TradeId);
realizedPnl += x.Amount - ((trade?.TradePrice * x.UnwindPercentRate * ((trade?.BuySell == "卖出") ? -1 : 1)) ?? 0);
});
tradeObj.RealizedPnl = realizedPnl;
}
}
if (result != null && result.TradeRiskList != null)
{
if (tradeObj.IsGroup == 1)
{
//var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == tradeObj.id && y.ValidState != "InValid").Select(y => y.id).ToList();
var childTradeIds = childTradeList.Where(y => y.ParentTradeId == tradeObj.id && y.ValidState != "InValid").Select(y => y.id).ToList();
var risks = result.TradeRiskList.Where(x => childTradeIds.Contains(x.TradeId));
tradeObj.DeltaInLots = risks != null && risks.Any() ? risks.Sum(x => x.DeltaInLots) : 0;
}
else
{
var risk = result.TradeRiskList.FirstOrDefault(x => x.TradeId == tradeObj.id);
tradeObj.DeltaInLots = risk != null ? risk.DeltaInLots : 0;
}
}
var realStrike = tradeObj.IsMoneynessOptionData ? (tradeObj.SpotPrice ?? 0) * (tradeObj.Strike ?? 0) : tradeObj.Strike ?? 0;
tradeObj.ValueStatus = "-";
DataCacheModule.DataCacheManager.GetUnderlyingDataSource().TryGetPrice(tradeObj.UnderlyingCode, out var price);
tradeObj.UnderlyingPrice = price;
tradeObj.UnderlyingName = underlying?.UnderlyingName;
if (tradeObj.IsOption() && price > 0)
{
if (realStrike == price)
{
tradeObj.ValueStatus = "ATM 100%";
}
else if ((realStrike < price && tradeObj.OptionType == "看涨") || (realStrike > price && tradeObj.OptionType == "看跌"))
{
tradeObj.ValueStatus = "ITM " + (realStrike / price * 100).ToString("0.00") + "%";
}
else
{
tradeObj.ValueStatus = "OTM " + (realStrike / price * 100).ToString("0.00") + "%";
}
}
var pv = realtimerisk.Where(t => t.TradeId == tradeObj.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.Pv)).ToList();
var roundedPv = realtimerisk.Where(t => t.TradeId == tradeObj.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.RoundedPv)).ToList();
if (PS.Config.IsPVRounded)
{
if (roundedPv != null && roundedPv.Count > 0)
{
tradeObj.PV = roundedPv.ToJson();
}
}
else
{
if (pv != null && pv.Count > 0)
{
tradeObj.PV = pv.ToJson();
}
}
if (tradeObj.TradeType == "合成价差期权")
{
//tradeObj.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(tradeObj.UnderlyingCode);
tradeObj.SyntheticUnderlyingTipsInfo = syntheticUnderlyingList.FirstOrDefault(d => tradeObj.UnderlyingCode.Equals(d.Name))?.UnderlyingTipsInfo;
}
//tradeObj.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(tradeObj.id);
if (keyValueSalesC.ContainsKey(tradeObj.id))
{
tradeObj.SalesCommission = keyValueSalesC[tradeObj.id];
}
else
{
tradeObj.SalesCommission = new TradeSalesCommissionInfo();
}
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && tradeObj.SalesCommission?.Commission != null)
{
tradeObj.SalesCommission.Commission = tradeObj.SalesCommission.Commission * tradeObj.SalesCommission.SalesIds.Count();
}
tradeObj.CountRatio = underlying?.CountRatio ?? 1;
tradeObj.SettlementDate = tradeObj.SettlementDate ?? tradeObj.ExerciseDate;
}
}
return sList;
}
/// <summary>
/// 获取今日敲出数据列表
/// </summary>
public SearchListResult<TdPreEndTrade2> GetKnockedOutList(TdTradeQueryModel req)
{
var valueDate = SystemValueDate;
var endDate = valueDate.AddDays(1);
var predicate = BuildPredicate(req, valueDate);
var tQuery = DbContext.trade.Where(predicate);
var query1 = from tc in DbContext.trade_cash
join t in tQuery on tc.TradeId equals t.id
join ao in DbContext.autocall_observation on new { EndDate = tc.ValueDate, TradeId = t.id } equals new { ao.EndDate, ao.TradeId } into tempAo
from ao in tempAo.DefaultIfEmpty()
where tc.BarrierPrice != null //障碍期权敲出
&& tc.HappenedDate >= valueDate && tc.HappenedDate < endDate
&& t.ValidState != "InValid" && !tc.IsDeleted
select new TdPreEndTrade2
{
id = t.id,
trade = t,
trade_cash = new TradeCashDto
{
Action = tc.Action,
Amount = tc.Amount,
UnwindTradeAmount = tc.UnwindTradeAmount,
FinalPrice = tc.FinalPrice,
UnwindPrice = tc.UnwindPrice,
Notional = tc.Notional,
UnwindNotional = tc.UnwindNotional,
TradeAmount = tc.TradeAmount,
ValidState = tc.ValidState,
ValueDate = tc.ValueDate,
UnwindPercentRate = tc.UnwindPercentRate,
UnwindPricePercentRate = tc.UnwindPricePercentRate
}
};
if (string.IsNullOrEmpty(req.sidx))
{
query1 = query1.OrderByDescending(s => s.trade.TradeDate);
}
var sList = query1.ToSearchList(req);
foreach (var item in sList.rows)
{
tradeBLL.SetFieldsByTradeType(item.trade);
item.trade.UnWindUnderlyingPrice = DbContext.trade_cash.Where(x => x.TradeId == item.trade.id && !x.IsDeleted && x.BarrierPrice != null).Select(x => x.BarrierPrice).FirstOrDefault();
if (!ConsTrade.TradeTypesForHedge.Contains(item.trade.TradeType))
{
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.UnderlyingCode);
if (underlying != null && underlying.UnderlyingInstrumentType != "Stock")
{
item.trade.TradeOriginalAmount = item.trade.OriginalNotional / underlying.CountRatio;
}
else
{
item.trade.TradeOriginalAmount = item.trade.OriginalNotional;
}
item.trade.UnderlyingName = underlying.UnderlyingName;
}
if (item.trade.TradeType == "合成价差期权")
{
item.trade.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(item.trade.UnderlyingCode);
}
item.trade.CountRatio = DataCacheManager.GetUnderlyingDataSource().GetData(item.trade.UnderlyingCode)?.CountRatio;
}
return sList;
}
//替换TradeBLL.SearchHistoryList
/// <summary>
/// 获取当日提前终止数据列表
/// </summary>
public SearchListResult<TdPreEndTrade2> GetPreEndList(TdTradeQueryModel req, List<int> userAssets, List<int> userClients, bool isShowAll)
{
var curTradingDate = SystemValueDate;
var predicate = BuildPredicate(req, curTradingDate, req.OtcTradeType == DBModels.Enums.OtcTradeType.EquitySwap ? true : false);
var tQuery = DbContext.trade.Where(predicate);
//交易员对应的簿记账户筛选或者客户经理对应的客户筛选
if (userAssets != null || userClients != null)
{
tQuery = from source in tQuery
where userAssets.Contains(source.AssetId) || userClients.Contains(source.ClientId)
select source;
}
var query1 = from tc in DbContext.trade_cash
join t in tQuery on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& (tc.Action == ClientCashInCashOut.系统操作_平仓费 || tc.Action == ClientCashInCashOut.系统操作_互换) && (t.TradeStatus == "平仓待复核" || t.TradeStatus == "互换待复核" || tc.ValidState != "InValid")
&& !tc.IsDeleted && tc.BarrierPrice == null //不包含敲出数据
select new TdPreEndTrade2
{
id = t.id,
trade = t,
trade_cash = new TradeCashDto
{
id = tc.id,
Action = tc.Action,
Amount = tc.Amount,
UnwindTradeAmount = tc.UnwindTradeAmount,
FinalPrice = tc.FinalPrice,
UnwindPrice = tc.UnwindPrice,
Notional = tc.Notional,
UnwindNotional = tc.UnwindNotional,
TradeAmount = tc.TradeAmount,
ValidState = tc.ValidState,
ValueDate = tc.ValueDate,
UnwindPercentRate = tc.UnwindPercentRate,
UnwindPricePercentRate = tc.UnwindPricePercentRate
}
};
//已平仓,部分平仓,美式期权提前行权
//predicate = predicate.And(t => t.ExerciseMode == "American");
tQuery = DbContext.trade.Where(predicate);
var query2 = from tc in DbContext.trade_cash
join t in tQuery on tc.TradeId equals t.id
where tc.ValueDate == curTradingDate
&& tc.Action == ClientCashInCashOut.系统操作_行权费 && tc.ExerciseWay != "到期行权" && (t.TradeStatus == "行权待复核" || tc.ValidState != ConsGlobal.InValid && t.TradeStatus == ConsTrade.已执行)
&& !tc.IsDeleted && tc.BarrierPrice == null //不包含敲出数据
select new TdPreEndTrade2
{
id = t.id,
trade = t,
trade_cash = new TradeCashDto
{
id = tc.id,
Action = tc.Action,
Amount = tc.Amount,
UnwindTradeAmount = tc.UnwindTradeAmount,
FinalPrice = tc.FinalPrice,
UnwindPrice = tc.UnwindPrice,
Notional = tc.Notional,
UnwindNotional = tc.UnwindNotional,
TradeAmount = tc.TradeAmount,
ValidState = tc.ValidState,
ValueDate = tc.ValueDate,
UnwindPercentRate = tc.UnwindPercentRate,
UnwindPricePercentRate = tc.UnwindPricePercentRate
}
};
var query = query1.Concat(query2);
if (string.IsNullOrEmpty(req.sidx))
{
query = query.OrderByDescending(s => s.trade.TradeNumber);
}
var sList = query.ToSearchList(req);
if (sList.rows != null && sList.rows.Any())
{
var trades = sList.rows.Select(n => n.trade);
new TradeDalModule.TradeDalService(this).SetStructureInfo(trades);
var forwardIds = trades.Where(p => "远期".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
List<trade_forward> forwardList = null;
if (forwardIds != null && forwardIds.Count > 0)
{
forwardList = DbContext.trade_forward.AsNoTracking().Where(x => forwardIds.Contains(x.TradeId)).ToList();
}
if (forwardList == null)
{
forwardList = new List<trade_forward>();
}
var tradeIdList = trades.Select(p => p.id).Distinct().ToList();
Dictionary<int, TradeSalesCommissionInfo> keyValueSalesC = null;
using (var saleCService = new SalesModule.SalesCommissionDataService(OptUser))
{
keyValueSalesC = saleCService.GetTradeCommissionInfoByTradeIds(tradeIdList);
}
var syntheticUnderlyingCodeList = trades.Where(d => "合成价差期权".Equals(d.TradeType)).Select(d => d.UnderlyingCode).Distinct().ToList();
List<SyntheticUnderlying> syntheticUnderlyingList = null;
if (syntheticUnderlyingCodeList != null && syntheticUnderlyingCodeList.Count > 0)
{
syntheticUnderlyingList = synthetic_underlyingBLL.GetListByNames(syntheticUnderlyingCodeList);
}
if (syntheticUnderlyingList == null)
{
syntheticUnderlyingList = new List<SyntheticUnderlying>();
}
List<trade_cash_detail> tradeCashDetailList = null;
var isGroupNotEqual1tradeCashIds = sList.rows.Where(d => d.trade.IsGroup != 1).Select(d => d.trade_cash.id).Distinct().ToList();
if (isGroupNotEqual1tradeCashIds != null && isGroupNotEqual1tradeCashIds.Count > 0)
{
tradeCashDetailList = DbContext.trade_cash_detail.AsNoTracking().Where(x => isGroupNotEqual1tradeCashIds.Contains(x.TradeCashId)).ToList();
}
if (tradeCashDetailList == null)
{
tradeCashDetailList = new List<trade_cash_detail>();
}
var isGroupEqual1tradeCashIds = sList.rows.Where(d => d.trade.IsGroup == 1).Select(d => d.trade_cash.id).Distinct().ToList();
List<trade_cash> childTradeCashList = null;
var parentTradeIds = sList.rows.Where(d => d.trade.IsGroup == 1).Select(d => d.id).Distinct().ToList();
if (isGroupEqual1tradeCashIds != null && isGroupEqual1tradeCashIds.Count > 0 && parentTradeIds != null && parentTradeIds.Count > 0)
{
var childTradeIds = DbContext.trade.Where(p => parentTradeIds.Contains(p.ParentTradeId) && p.ParentTradeId > 0).Select(p => p.id).Distinct().ToList();
if (childTradeIds != null && childTradeIds.Count > 0)
{
childTradeCashList = DbContext.trade_cash.AsNoTracking().Where(x => childTradeIds.Contains(x.TradeId) && isGroupEqual1tradeCashIds.Contains(x.ParentTradeCashId)).ToList();
}
}
if (childTradeCashList == null)
{
childTradeCashList = new List<trade_cash>();
}
List<int> allChildTradeIds = childTradeCashList.Select(d => d.TradeId).Distinct().ToList();
List<trade> allChildTradeList = null;
if (allChildTradeIds != null && allChildTradeIds.Count > 0)
{
allChildTradeList = DbContext.trade.AsNoTracking().Where(d => allChildTradeIds.Contains(d.id)).ToList();
}
if (allChildTradeList == null)
{
allChildTradeList = new List<trade>();
}
foreach (var item in sList.rows)
{
var underlying = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.trade.UnderlyingCode);
ProcessTrade(item.trade, null, underlying: underlying, syntheticUnderlyings: syntheticUnderlyingList);
if (item.trade.TradeType == "远期")
{
item.trade.trade_forward = forwardList.FirstOrDefault(x => x.TradeId == item.trade.id);
}
if (keyValueSalesC.ContainsKey(item.trade.id))
{
item.trade.SalesCommission = keyValueSalesC[item.trade.id];
}
else
{
item.trade.SalesCommission = new TradeSalesCommissionInfo();
}
//tradeObj.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(tradeObj.id);
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.trade.SalesCommission?.Commission != null)
{
item.trade.SalesCommission.Commission = item.trade.SalesCommission.Commission * item.trade.SalesCommission.SalesIds.Count();
}
if (item.trade.IsGroup == 1)
{
//var childTradeCashs = DbContext.trade_cash.Where(x => x.ParentTradeCashId == item.trade_cash.id).ToList();
var childTradeCashs = childTradeCashList.Where(x => x.ParentTradeCashId == item.trade_cash.id).ToList();
var childTradeIds = childTradeCashs.Select(x => x.TradeId).Distinct().ToList();
//var childTrades = DbContext.trade.Where(x => childTradeIds.Contains(x.id)).ToList();
var childTrades = allChildTradeList.Where(x => childTradeIds.Contains(x.id)).ToList();
var tcTradePrice = 0.0;
childTradeCashs.ForEach(x =>
{
var trade = childTrades.FirstOrDefault(y => y.id == x.TradeId);
tcTradePrice += (x.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
});
item.WinLoss = -(item.trade_cash.Amount + tcTradePrice);
}
else
{
//var tradeCashDetail = DbContext.trade_cash_detail.Where(x => x.TradeCashId == item.trade_cash.id);
var tradeCashDetail = tradeCashDetailList.Where(x => x.TradeCashId == item.trade_cash.id);
var amount = tradeCashDetail.Any() ? tradeCashDetail.Sum(x => x.Amount ?? 0) : item.trade_cash.Amount;
item.WinLoss = -(amount + (item.trade.TradePrice ?? 0) * (item.trade_cash.UnwindPercentRate ?? 0) * ((item.trade.BuySell == "卖出" || item.trade.TradeType == "远期") ? 1 : -1));
}
item.trade.CountRatio = underlying?.CountRatio ?? 1;
item.trade.UnderlyingName = underlying?.UnderlyingName;
}
}
return sList;
}
public List<TdPreEndTrade2> GetPreEndGroupChildren(int TcId)
{
var tQuery = DbContext.trade.AsNoTracking();
var query = from tc in DbContext.trade_cash.AsNoTracking().Where(x => x.ValidState != "InValid" && x.ParentTradeCashId == TcId)
join t in tQuery on tc.TradeId equals t.id
select new TdPreEndTrade2
{
id = t.id,
trade = t,
trade_cash = new TradeCashDto
{
id = tc.id,
Action = tc.Action,
Amount = tc.Amount,
UnwindTradeAmount = tc.UnwindTradeAmount,
FinalPrice = tc.FinalPrice,
UnwindPrice = tc.UnwindPrice,
Notional = tc.Notional,
UnwindNotional = tc.UnwindNotional,
TradeAmount = tc.TradeAmount,
ValidState = tc.ValidState,
ValueDate = tc.ValueDate,
UnwindPercentRate = tc.UnwindPercentRate,
UnwindPricePercentRate = tc.UnwindPricePercentRate
}
};
var sList = query.ToList();
var trades = sList.Select(n => n.trade);
new TradeDalModule.TradeDalService(this).SetStructureInfo(trades);
foreach (var tradeObj in trades)
{
ProcessTrade(tradeObj, null);
if (tradeObj.TradeType == "远期")
{
tradeObj.trade_forward = DbContext.trade_forward.First(x => x.TradeId == tradeObj.id);
}
tradeObj.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(tradeObj.id);
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && tradeObj.SalesCommission?.Commission != null)
{
tradeObj.SalesCommission.Commission = tradeObj.SalesCommission.Commission * tradeObj.SalesCommission.SalesIds.Count();
}
}
return sList;
}
/// <summary>
/// 交易观察状态列表
/// 障碍期权,双鲨期权,凤凰期权,雪球期权分tab展示
/// </summary>
public SearchListResult<trade> GetObservationStatusTradeList(TdTradeQueryModel req)
{
var valueDate = SystemValueDate;
var predicate = BuildObservationStatusPredicate(req, valueDate);
var tQuery = DbContext.trade.Where(predicate);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeNumber";
req.sord = "desc";
}
var sList = tQuery.ToSearchList(req);
if (sList.rows != null && sList.rows.Any())
{
var tradeIds = sList.rows.Select(t => t.id).ToList();
//处理障碍期权类型 需要关联表 在内存中处理
var trade_barrier_option = DbContext.trade_barrier_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理双鲨期权
var trade_double_sharkfin_option = DbContext.trade_double_sharkfin_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理凤凰期权
var trade_autocall = DbContext.trade_autocall.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理雪球期权
var trade_snowball = DbContext.trade_snowball.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理二元期权
var trade_binary_option = DbContext.trade_binary_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理累计期权
var trade_accumulator_option = DbContext.trade_accumulator_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
foreach (var trade in sList.rows)
{
if (trade.TradeType == "障碍期权")
{
var barrier = trade_barrier_option.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_barrier_option = barrier == null
? new trade_barrier_option()
: trade_barrier_option.FirstOrDefault(t => t.TradeId == trade.id);
if (string.IsNullOrEmpty(trade.trade_barrier_option.ObservationDates))
{
trade.trade_barrier_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_barrier_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_barrier_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_barrier_option.LatestObservationDate = null;
}
}
}
else if (trade.TradeType == "双鲨期权")
{
var doubleSharkFin = trade_double_sharkfin_option.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_double_sharkfin_option = doubleSharkFin == null
? new trade_double_sharkfin_option()
: trade_double_sharkfin_option.FirstOrDefault(t => t.TradeId == trade.id);
if (string.IsNullOrEmpty(trade.trade_double_sharkfin_option.ObservationDates))
{
trade.trade_double_sharkfin_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_double_sharkfin_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_double_sharkfin_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_double_sharkfin_option.LatestObservationDate = null;
}
}
}
else if (trade.TradeType == "凤凰期权")
{
var autocall = trade_autocall.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_autocall = autocall == null
? new trade_autocall()
: trade_autocall.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_autocall.HappenedObservations = new TradeAutocallBLL(this).QueryHappenedObservations(trade.id, DateTime.MaxValue);
if (string.IsNullOrEmpty(trade.trade_autocall.ObservationDates))
{
trade.trade_autocall.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_autocall.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_autocall.LatestObservationDate = latestObservationDate.DateTime;
}
}
if (string.IsNullOrEmpty(trade.trade_autocall.KOObservationDates))
{
trade.trade_autocall.LatestKOObservationDate = valueDate;
trade.trade_autocall.LatestKOBarrier = trade.trade_autocall.KOBarrier;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_autocall.KOObservationDates);
var koObservationDates = customizedResults.Item1;
var customizedKOBarriers = customizedResults.Item2;
var latestKOObservationDate = koObservationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestKOObservationDate != null)
{
trade.trade_autocall.LatestKOObservationDate = latestKOObservationDate.DateTime;
if (customizedKOBarriers == null || !customizedKOBarriers.Any())
{
trade.trade_autocall.LatestKOBarrier = trade.trade_autocall.KOBarrier;
}
else
{
trade.trade_autocall.LatestKOBarrier = customizedKOBarriers[GetDateIndex(koObservationDates, latestKOObservationDate)];
}
}
}
}
else if (trade.TradeType == "雪球期权")
{
var snowball = trade_snowball.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_snowball = snowball == null
? new trade_snowball()
: trade_snowball.FirstOrDefault(t => t.TradeId == trade.id);
if (string.IsNullOrEmpty(trade.trade_snowball.ObservationDates))
{
trade.trade_snowball.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_snowball.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_snowball.LatestObservationDate = latestObservationDate.DateTime;
}
}
if (string.IsNullOrEmpty(trade.trade_snowball.KOObservationDates))
{
trade.trade_snowball.LatestKOObservationDate = valueDate;
trade.trade_snowball.LatestKOBarrier = trade.trade_snowball.KOBarrier;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_snowball.KOObservationDates);
var koObservationDates = customizedResults.Item1;
var customizedKOBarriers = customizedResults.Item2;
var latestKOObservationDate = koObservationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestKOObservationDate != null)
{
trade.trade_snowball.LatestKOObservationDate = latestKOObservationDate.DateTime;
if (customizedKOBarriers == null || !customizedKOBarriers.Any())
{
trade.trade_snowball.LatestKOBarrier = trade.trade_snowball.KOBarrier;
}
else
{
trade.trade_snowball.LatestKOBarrier = customizedKOBarriers[GetDateIndex(koObservationDates, latestKOObservationDate)];
}
}
}
}
else if (trade.TradeType == "二元期权")
{
var binary = trade_binary_option.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_binary_option = binary == null
? new trade_binary_option()
: trade_binary_option.FirstOrDefault(t => t.TradeId == trade.id);
if (string.IsNullOrEmpty(trade.trade_binary_option.ObservationDates))
{
trade.trade_binary_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_binary_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_binary_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_binary_option.LatestObservationDate = null;
}
}
}
else if (trade.TradeType == "累计期权")
{
var accumulator = trade_accumulator_option.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_accumulator_option = accumulator == null ? new trade_accumulator_option() : accumulator;
if (string.IsNullOrEmpty(trade.trade_accumulator_option.KOObservationDates))
{
trade.trade_accumulator_option.LatestObservationDate = valueDate;
trade.trade_accumulator_option.LatestKOBarrier = trade.trade_accumulator_option.KOBarrier;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_accumulator_option.KOObservationDates);
var observationDates = customizedResults.Item1;
var latestKOBarrier = customizedResults.Item2;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_accumulator_option.LatestObservationDate = latestObservationDate.DateTime;
if (latestKOBarrier == null || !latestKOBarrier.Any())
{
trade.trade_accumulator_option.LatestKOBarrier = trade.trade_accumulator_option.KOBarrier;
}
else
{
trade.trade_accumulator_option.LatestKOBarrier = latestKOBarrier[GetDateIndex(observationDates, latestObservationDate)];
}
}
}
}
DataCacheModule.DataCacheManager.GetUnderlyingDataSource().TryGetPrice(trade.UnderlyingCode, out var price);
trade.UnderlyingPrice = price;
}
}
return sList;
}
public SearchListResult<TdObservationTrade> GetObservationEventTradeList(TdTradeQueryModel req)
{
var valueDate = req.ValueDate ?? SystemValueDate;
EodPriceProvider priceProvider = null;
var predicate = BuildObservationEventPredicte(req, valueDate);
var tQuery = DbContext.trade.Where(predicate);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "trade.TradeNumber";
req.sord = "desc";
}
var observationStatus = req.ObservationStatus;
if (observationStatus == null)
{
observationStatus = new List<string>() { "已敲入", "已敲出", "观察中" };
}
var querylist = tQuery.ToList();
var knockOutList = new List<TdObservationTrade>();
var knockInList = new List<TdObservationTrade>();
var couponList = new List<TdObservationTrade>();
var customList = new List<TdObservationTrade>();
if (querylist != null && querylist.Any())
{
var tradeIds = querylist.Select(t => t.id).ToList();
Dictionary<int, manually_trade_observation_price> manuallyTradeObservationPrices = null;
if (valueDate < SystemValueDate)
{
priceProvider = new EodPriceProvider(valueDate);
manuallyTradeObservationPrices = DbContext.manually_trade_observation_price
.Where(x => tradeIds.Contains(x.TradeId) && x.ValueDate == valueDate).ToDictionary(n => n.TradeId);
}
if (req.TabIndex == 3 || req.TabIndex == 99)
{
var trade_custom = DbContext.trade_custom.Where(t => tradeIds.Contains(t.TradeId)).ToList();
foreach (var trade in querylist)
{
var custom = trade_custom.FirstOrDefault(t => t.TradeId == trade.id);
trade.trade_custom = custom == null
? new trade_custom()
: trade_custom.FirstOrDefault(t => t.TradeId == trade.id);
var tempTrade = new TdObservationTrade();
if (string.IsNullOrEmpty(trade.trade_custom.ObservationDates))
{
continue;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_custom.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_custom.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_custom.LatestObservationDate = null;
}
}
tempTrade.trade = trade.Clone();
if (trade.trade_custom.LatestObservationDate == valueDate)
{
tempTrade.Type += 8;
customList.Add(tempTrade);
}
else
{
continue;
}
var price = 0.0;
double? SettlementAmount = null;
if (valueDate >= SystemValueDate)
{
DataCacheManager.GetUnderlyingDataSource().TryGetPrice(trade.UnderlyingCode, out price);
}
else
{
if (manuallyTradeObservationPrices.TryGetValue(trade.id, out var manuallyTradeObservationPrice))
{
price = manuallyTradeObservationPrice.Price ?? 0;
SettlementAmount = manuallyTradeObservationPrice.SettlementAmount;
}
else if (!priceProvider.TryGetEodPrice(trade.UnderlyingCode, out var eodPrice))
{
throw new Exception($"[{trade.TradeType}:{trade.TradeNumber},标的:{trade.UnderlyingCode}]未找到结算价");
}
else
{
price = eodPrice.GetPrice(trade.SettlementType);
}
}
if (tempTrade.trade != null)
{
tempTrade.trade.UnderlyingPrice = price;
}
}
}
if (req.TabIndex != 3)
{
//处理障碍期权类型 需要关联表 在内存中处理
var trade_barrier_option = DbContext.trade_barrier_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理双鲨期权
var trade_double_sharkfin_option = DbContext.trade_double_sharkfin_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理凤凰期权
var trade_autocall = DbContext.trade_autocall.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理雪球期权
var trade_snowball = DbContext.trade_snowball.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//处理二元期权
var trade_binary_option = DbContext.trade_binary_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//气囊结构
var trade_airbag = DbContext.trade_airbag.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//区间累积
var trade_rangeaccrual = DbContext.trade_rangeaccrual.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//累计期权
var trade_accumulator = DbContext.trade_accumulator_option.Where(t => tradeIds.Contains(t.TradeId)).ToList();
//是否新增观察事件 -- knockOutListknockInListcouponListcustomList
bool isAdd = false;
foreach (var trade in querylist)
{
var tempTrade = new TdObservationTrade();
var tempTrade1 = new TdObservationTrade();
switch (trade.TradeType)
{
case "障碍期权":
{
var barrier = trade_barrier_option.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_barrier_option();
trade.trade_barrier_option = barrier;
if (string.IsNullOrEmpty(trade.trade_barrier_option.ObservationDates))
{
trade.trade_barrier_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_barrier_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_barrier_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_barrier_option.LatestObservationDate = null;
}
}
if (observationStatus.Contains(trade.trade_barrier_option.KnockInOutStatusCn))
{
tempTrade.trade = trade.Clone();
tempTrade.ObservationStatus = trade.trade_barrier_option.KnockInOutStatusCn;
tempTrade.konckInOutDate = trade.trade_barrier_option.KnockInOutDate;
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_barrier_option.BarrierPrice * trade.SpotPrice : trade.trade_barrier_option.BarrierPrice;
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_barrier_option.UpperBarrierPrice * trade.SpotPrice : trade.trade_barrier_option.UpperBarrierPrice;
if (trade.trade_barrier_option.LatestObservationDate == valueDate)
{
if (trade.trade_barrier_option.BarrierType.Contains("敲入"))
{
tempTrade.Type += 1;
knockInList.Add(tempTrade);
isAdd = true;
}
if (trade.trade_barrier_option.BarrierType.Contains("敲出"))
{
tempTrade.Type += 2;
knockOutList.Add(tempTrade);
isAdd = true;
}
if (tempTrade.ObservationStatus != "已敲入" && (tempTrade.ObservationStatus == "观察中" || tempTrade.konckInOutDate == valueDate || trade.ExerciseDate == valueDate))
{
tempTrade.Type += 4;
couponList.Add(tempTrade);
isAdd = true;
}
}
}
}
break;
case "双鲨期权":
{
var doubleSharkFin = trade_double_sharkfin_option.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_double_sharkfin_option();
trade.trade_double_sharkfin_option = doubleSharkFin;
if (string.IsNullOrEmpty(trade.trade_double_sharkfin_option.ObservationDates))
{
trade.trade_double_sharkfin_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_double_sharkfin_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_double_sharkfin_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_double_sharkfin_option.LatestObservationDate = null;
}
}
if (observationStatus.Contains(trade.trade_double_sharkfin_option.KnockInOutStatusCn))
{
tempTrade.trade = trade.Clone();
tempTrade.ObservationStatus = trade.trade_double_sharkfin_option.KnockInOutStatusCn;
tempTrade.konckInOutDate = trade.trade_double_sharkfin_option.KnockInOutDate;
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_double_sharkfin_option.BarrierLow * trade.SpotPrice : trade.trade_double_sharkfin_option.BarrierLow;
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_double_sharkfin_option.BarrierHigh * trade.SpotPrice : trade.trade_double_sharkfin_option.BarrierHigh;
if (trade.trade_double_sharkfin_option.LatestObservationDate == valueDate)
{
tempTrade.Type += 2;
knockOutList.Add(tempTrade);
if (tempTrade.ObservationStatus == "观察中" || tempTrade.konckInOutDate == valueDate)
{
tempTrade.Type += 4;
couponList.Add(tempTrade);
}
isAdd = true;
}
}
}
break;
case "凤凰期权":
{
var autocall = trade_autocall.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_autocall();
trade.trade_autocall = autocall;
trade.trade_autocall.HappenedObservations = new TradeAutocallBLL(this).QueryHappenedObservations(trade.id, DateTime.MaxValue);
if (string.IsNullOrEmpty(trade.trade_autocall.ObservationDates))
{
trade.trade_autocall.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_autocall.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_autocall.LatestObservationDate = latestObservationDate.DateTime;
}
}
if (string.IsNullOrEmpty(trade.trade_autocall.KOObservationDates))
{
trade.trade_autocall.LatestKOObservationDate = valueDate;
trade.trade_autocall.LatestKOBarrier = trade.trade_autocall.KOBarrier;
}
else
{
var ko = TradeObservationHelper.GetAutocallKOObservationAndCoupon(trade.trade_autocall.KOObservationDates, trade.trade_autocall.CouponBarrier);
if (req.TabIndex == 2)
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(ko.Item1);
var CouponsObservationDates = customizedResults.Item1;
var CouponsKOBarriers = customizedResults.Item2;
var latestKOObservationDate = CouponsObservationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestKOObservationDate != null)
{
trade.trade_autocall.LatestKOObservationDate = latestKOObservationDate.DateTime;
if (CouponsKOBarriers == null || !CouponsKOBarriers.Any())
{
trade.trade_autocall.LatestKOBarrier = trade.trade_autocall.KOBarrier;
}
else
{
trade.trade_autocall.LatestKOBarrier = CouponsKOBarriers[GetDateIndex(CouponsObservationDates, latestKOObservationDate)];
}
}
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfoV3(ko.Item2);
var koObservationDates = customizedResults.Item1;
var customizedKOBarriers = customizedResults.Item2;
var latestKOObservationDate = koObservationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestKOObservationDate != null)
{
trade.trade_autocall.LatestKOObservationDate = latestKOObservationDate.DateTime;
if (customizedKOBarriers == null || !customizedKOBarriers.Any())
{
trade.trade_autocall.LatestKOBarrier = trade.trade_autocall.KOBarrier;
}
else
{
trade.trade_autocall.LatestKOBarrier = customizedKOBarriers[GetDateIndex(koObservationDates, latestKOObservationDate)];
}
}
}
}
if (observationStatus.Contains(trade.trade_autocall.KnockInOutStatusCn))
{
tempTrade.trade = trade.Clone();
var barrier1 = (trade.IsMoneynessOption == "是" ? trade.trade_autocall.KIBarrier * trade.SpotPrice : trade.trade_autocall.KIBarrier) ?? 0;
var barrier2 = (trade.IsMoneynessOption == "是" ? trade.trade_autocall.KOBarrier * trade.SpotPrice : trade.trade_autocall.KOBarrier) ?? 0;
if (trade.trade_autocall.LatestObservationDate == valueDate)
{
tempTrade.ObservationStatus = trade.trade_autocall.KnockInOutStatusCn;
tempTrade.konckInOutDate = trade.trade_autocall.KnockInOutDate;
tempTrade.BarrierLow = trade.OptionType == "看涨" ? Math.Min(barrier1, barrier2) : Math.Max(barrier1, barrier2);
tempTrade.BarrierHigh = trade.OptionType == "看涨" ? Math.Max(barrier1, barrier2) : Math.Min(barrier1, barrier2);
tempTrade.Type += 1;
knockInList.Add(tempTrade);
isAdd = true;
}
if (trade.trade_autocall.LatestKOObservationDate == valueDate)
{
tempTrade1.trade = trade.Clone();
tempTrade1.ObservationStatus = trade.trade_autocall.KnockInOutStatusCn;
tempTrade1.konckInOutDate = trade.trade_autocall.KnockInOutDate;
tempTrade1.BarrierLow = trade.OptionType == "看涨" ? Math.Min(barrier1, barrier2) : Math.Max(barrier1, barrier2);
tempTrade1.BarrierHigh = trade.OptionType == "看涨" ? Math.Max(barrier1, barrier2) : Math.Min(barrier1, barrier2);
tempTrade.Type += 2;
knockOutList.Add(tempTrade1);
if (tempTrade1.ObservationStatus != "已敲出" || tempTrade1.konckInOutDate == valueDate)
{
tempTrade.Type += 4;
couponList.Add(tempTrade1);
}
tempTrade1.Type = tempTrade.Type;
isAdd = true;
}
}
}
break;
case "雪球期权":
{
var snowball = trade_snowball.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_snowball();
trade.trade_snowball = snowball;
if (string.IsNullOrEmpty(trade.trade_snowball.ObservationDates))
{
trade.trade_snowball.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_snowball.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_snowball.LatestObservationDate = latestObservationDate.DateTime;
}
}
if (string.IsNullOrEmpty(trade.trade_snowball.KOObservationDates))
{
trade.trade_snowball.LatestKOObservationDate = valueDate;
trade.trade_snowball.LatestKOBarrier = trade.trade_snowball.KOBarrier;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_snowball.KOObservationDates);
var koObservationDates = customizedResults.Item1;
var customizedKOBarriers = customizedResults.Item2;
var latestKOObservationDate = koObservationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestKOObservationDate != null)
{
trade.trade_snowball.LatestKOObservationDate = latestKOObservationDate.DateTime;
if (customizedKOBarriers == null || !customizedKOBarriers.Any())
{
trade.trade_snowball.LatestKOBarrier = trade.trade_snowball.KOBarrier;
}
else
{
trade.trade_snowball.LatestKOBarrier = customizedKOBarriers[GetDateIndex(koObservationDates, latestKOObservationDate)];
}
}
}
if (observationStatus.Contains(trade.trade_snowball.KnockInOutStatusCn))
{
tempTrade.trade = trade.Clone();
if (trade.trade_snowball.LatestObservationDate == valueDate && trade.trade_snowball.KIPayoffType != KIPayoffTypeEnum.None)
{
tempTrade.ObservationStatus = trade.trade_snowball.KnockInOutStatusCn;
tempTrade.konckInOutDate = trade.trade_snowball.KnockInOutDate;
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_snowball.KIBarrier * trade.SpotPrice : trade.trade_snowball.KIBarrier;
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_snowball.KOBarrier * trade.SpotPrice : trade.trade_snowball.KOBarrier;
tempTrade.Type += 1;
knockInList.Add(tempTrade);
isAdd = true;
}
if (trade.trade_snowball.LatestKOObservationDate == valueDate)
{
tempTrade1.trade = trade.Clone();
tempTrade1.ObservationStatus = trade.trade_snowball.KnockInOutStatusCn;
tempTrade1.konckInOutDate = trade.trade_snowball.KnockInOutDate;
if (ConsGlobal.CallPut.IsCall(trade.OptionType)) //向下敲入向上敲出
{
tempTrade1.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_snowball.LatestKOBarrier * trade.SpotPrice : trade.trade_snowball.LatestKOBarrier;
tempTrade1.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_snowball.KIBarrier * trade.SpotPrice : trade.trade_snowball.KIBarrier;
}
else //向上敲入向下敲出
{
tempTrade1.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_snowball.LatestKOBarrier * trade.SpotPrice : trade.trade_snowball.LatestKOBarrier;
tempTrade1.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_snowball.KIBarrier * trade.SpotPrice : trade.trade_snowball.KIBarrier;
}
tempTrade.Type += 2;
knockOutList.Add(tempTrade1);
if (tempTrade1.ObservationStatus == "观察中" || tempTrade1.konckInOutDate == valueDate)
{
tempTrade.Type += 4;
couponList.Add(tempTrade1);
}
tempTrade1.Type = tempTrade.Type;
isAdd = true;
}
}
}
break;
case "二元期权":
{
var binary = trade_binary_option.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_binary_option();
trade.trade_binary_option = binary;
if (trade.ExerciseModeCn == "欧式")
{
break;
}
if (string.IsNullOrEmpty(trade.trade_binary_option.ObservationDates))
{
trade.trade_binary_option.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_binary_option.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_binary_option.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_binary_option.LatestObservationDate = null;
}
}
tempTrade.trade = trade.Clone();
if (trade.trade_binary_option.LatestObservationDate == valueDate)
{
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.Strike * trade.SpotPrice : trade.Strike;
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.trade_binary_option.UpperBarrier * trade.SpotPrice : trade.trade_binary_option.UpperBarrier;
tempTrade.Type += 2;
knockOutList.Add(tempTrade);
tempTrade.Type += 4;
couponList.Add(tempTrade);
isAdd = true;
}
}
break;
case "气囊结构":
{
var airbag = trade_airbag.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_airbag();
trade.trade_airbag = airbag;
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.trade_airbag.Barrier * trade.SpotPrice : trade.trade_airbag.Barrier;
tempTrade.trade = trade.Clone();
tempTrade.Type = 4;
couponList.Add(tempTrade);
isAdd = true;
//没有观察日,只计算敲入敲出
}
break;
case "区间累积期权":
{
var rangeaccrual = trade_rangeaccrual.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_rangeaccrual();
trade.trade_rangeaccrual = rangeaccrual;
if (string.IsNullOrEmpty(trade.trade_rangeaccrual.ObservationDates))
{
trade.trade_rangeaccrual.LatestObservationDate = valueDate;
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_rangeaccrual.ObservationDates);
var observationDates = customizedResults.Item1;
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
trade.trade_rangeaccrual.LatestObservationDate = latestObservationDate.DateTime;
}
else
{
trade.trade_rangeaccrual.LatestObservationDate = null;
}
}
tempTrade.trade = trade.Clone();
if (trade.trade_rangeaccrual.LatestObservationDate == valueDate)
{
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.Strike * trade.SpotPrice : trade.Strike;
tempTrade.Type += 4;
couponList.Add(tempTrade);
isAdd = true;
}
}
break;
case "累计期权":
{
var accumulator = trade_accumulator.FirstOrDefault(t => t.TradeId == trade.id) ?? new trade_accumulator_option();
trade.trade_accumulator_option = accumulator;
DateTime? LatestObservationDate = valueDate;
if (!string.IsNullOrEmpty(accumulator.KOObservationDates))
{
var observationDates = QdpHelper.ParseObservationDate(accumulator.KOObservationDates);
var latestObservationDate = observationDates.Where(x => x.DateTime >= valueDate).OrderBy(x => x.DateTime).FirstOrDefault();
if (latestObservationDate != null)
{
LatestObservationDate = latestObservationDate.DateTime;
}
else
{
LatestObservationDate = null;
}
}
if (accumulator.KnockOutDate.HasValue)
{
tempTrade.trade = trade.Clone();
tempTrade.ObservationStatus = "敲出";
tempTrade.konckInOutDate = accumulator.KnockOutDate;
if (ConsGlobal.CallPut.IsCall(trade.OptionType))
{
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? trade.Strike * trade.SpotPrice : trade.Strike;
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? accumulator.KOBarrier * trade.SpotPrice : accumulator.KOBarrier;
}
else
{
tempTrade.BarrierHigh = trade.IsMoneynessOption == "是" ? trade.Strike * trade.SpotPrice : trade.Strike;
tempTrade.BarrierLow = trade.IsMoneynessOption == "是" ? accumulator.KOBarrier * trade.SpotPrice : accumulator.KOBarrier;
}
if (LatestObservationDate == valueDate)
{
tempTrade.Type += 2;
knockOutList.Add(tempTrade);
isAdd = true;
if (accumulator.PayoffType == "固定")
{
tempTrade.Type += 4;
couponList.Add(tempTrade);
}
}
}
}
break;
}
if (!isAdd)
{
continue;
}
var price = 0.0;
double? SettlementAmount = null;
if (valueDate >= SystemValueDate)
{
DataCacheManager.GetUnderlyingDataSource().TryGetPrice(trade.UnderlyingCode, out price);
}
else
{
if (manuallyTradeObservationPrices.TryGetValue(trade.id, out var manuallyTradeObservationPrice))
{
price = manuallyTradeObservationPrice.Price ?? 0;
SettlementAmount = manuallyTradeObservationPrice.SettlementAmount;
}
else if (!priceProvider.TryGetEodPrice(trade.UnderlyingCode, out var eodPrice))
{
throw new Exception($"[{trade.TradeType}:{trade.TradeNumber},标的:{trade.UnderlyingCode}]未找到结算价");
}
else
{
price = eodPrice.GetPrice(trade.SettlementType);
}
}
if (tempTrade.trade != null)
{
tempTrade.trade.UnderlyingPrice = price;
}
if (tempTrade1.trade != null)
{
tempTrade1.trade.UnderlyingPrice = price;
}
tempTrade.CouponPaidStatus = CheckCouponPaid(valueDate, trade, price, SettlementAmount);
tempTrade1.CouponPaidStatus = tempTrade.CouponPaidStatus;
}
}
}
var sList = new SearchListResult<TdObservationTrade>();
switch (req.TabIndex)
{
case 0:
sList = knockOutList.AsQueryable().ToSearchList(req);
break;
case 1:
sList = knockInList.AsQueryable().ToSearchList(req);
break;
case 2:
sList = couponList.AsQueryable().ToSearchList(req);
break;
case 3:
sList = customList.AsQueryable().ToSearchList(req);
break;
case 99:
couponList.AddRange(knockInList);
couponList.AddRange(knockOutList);
couponList.AddRange(customList);
sList = couponList.Distinct().AsQueryable().ToSearchList(req);
break;
default:
break;
}
return sList;
}
public SearchListResult<trade> GetDelaySettlementTradeQuery(TdTradeQueryModel req)
{
var valueDate = req.ValueDate ?? SystemValueDate;
var predicate = BuildObservationEventPredicte(req, valueDate);
var tQuery = DbContext.trade.Where(predicate);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeNumber";
req.sord = "desc";
}
var sList = tQuery.ToSearchList(req);
var sysuser = new ErpBaseContext().SystemUsers.Select(x => new { x.Id, x.Name }).ToList();
foreach (var item in sList.rows)
{
item.SettlementFlagOptName = sysuser?.FirstOrDefault(x => x.Id == item.SettlementFlagOptId)?.Name;
}
return sList;
}
/// <summary>
///
/// </summary>
/// <param name="valueDate"></param>
/// <param name="tradeId"></param>
/// <returns>1:已付票息 0:不付票息 2:将付票息</returns>
public int CheckCouponPaid(DateTime? valueDate, trade td, double price, double? SettlementAmount)
{
var hasPaid = DbContext.autocall_observation.Any(o => o.EndDate == valueDate && o.TradeId == td.id);
if (hasPaid || ConsTrade.TradeCompleteStatus.Contains(td.TradeStatus))
{
return 1;
}
else
{
var ret = new CheckTradeObservateStatusService(OptUser).CheckTradeObservateStatus(td, valueDate.Value, new double[3] { price, price, price }, SettlementAmount);
if (ret.Value)
{
return 2;
}
}
return 0;
}
private int GetDateIndex(Date[] source, Date value)
{
var index = 0;
foreach (var item in source)
{
if (item.DateTime == value.DateTime)
{
return index;
}
index++;
}
return -1;
}
public void ProcessTrade(trade tradeObj, trade_cash tradeCash, underlying_manager underlying = null, List<SyntheticUnderlying> syntheticUnderlyings = null)
{
if (tradeObj.TradeType == "合成价差期权")
{
if (syntheticUnderlyings != null)
{
tradeObj.SyntheticUnderlyingTipsInfo = syntheticUnderlyings.FirstOrDefault(d => d.Name.Equals(tradeObj.UnderlyingCode))?.UnderlyingTipsInfo;
}
else
{
tradeObj.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(tradeObj.UnderlyingCode);
}
}
tradeObj.FinalPrice = tradeCash?.FinalPrice;
if (!ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType))
{
if (underlying == null)
{
underlying = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(tradeObj.UnderlyingId);
}
if (underlying != null && underlying.UnderlyingInstrumentType != "Stock")
{
tradeObj.TradeOriginalAmount = tradeObj.OriginalNotional / underlying.CountRatio;
}
else
{
underlying = new underlying_manager();
tradeObj.TradeOriginalAmount = tradeObj.OriginalNotional;
}
tradeObj.UnderlyingName = underlying.UnderlyingName;
}
tradeObj.trade_cash = tradeCash;
}
public Dictionary<string, object> getDailyEvents(DateTime? date, List<int> userAssets, List<int> userClients)
{
try
{
if (date == null)
{
date = SystemValueDate;
}
var ret = new Dictionary<string, object>();
//到期
var settleTradeQuery = DbContext.trade.Where(o => o.ExerciseDate == date && o.ValidState != "InValid" && o.TradeType != "远期" && o.TradeType != "收益互换" && o.TradeType != "现金流交易");
var settleCashTradeQuery = DbContext.trade.Where(o => o.ExerciseDate == date && o.ValidState != "InValid" && o.TradeType == "现金流交易");
var settleForwardQuery = DbContext.trade.Where(o => o.ExerciseDate == date && o.ValidState != "InValid" && o.TradeType == "远期");
var settleExchangeQuery = DbContext.trade.Where(o => o.ExerciseDate == date && o.ValidState != "InValid" && o.TradeType == "收益互换");
if (settleTradeQuery.Any())
{
if (settleTradeQuery.Any(o => ConsTrade.PositionTradeStatusList.Contains(o.TradeStatus)))
{
ret.Add("到期期权", false);
}
else
{
ret.Add("到期期权", true);
}
}
if (settleCashTradeQuery.Any())
{
if (settleCashTradeQuery.Any(o => ConsTrade.PositionTradeStatusList.Contains(o.TradeStatus)))
{
ret.Add("到期现金流", false);
}
else
{
ret.Add("到期现金流", true);
}
}
if (settleForwardQuery.Any())
{
if (settleForwardQuery.Any(o => ConsTrade.PositionTradeStatusList.Contains(o.TradeStatus)))
{
ret.Add("到期远期", false);
}
else
{
ret.Add("到期远期", true);
}
}
if (settleExchangeQuery.Any())
{
if (settleExchangeQuery.Any(o => ConsTrade.PositionTradeStatusList.Contains(o.TradeStatus)))
{
ret.Add("到期互换", false);
}
else
{
ret.Add("到期互换", true);
}
}
//观察日
var req = new TdTradeQueryModel()
{
TabIndex = 99,
ValueDate = date,
UserAssets = userAssets,
UserClients = userClients
};
var observationEvents = GetObservationEventTradeList(req);
if (observationEvents != null && observationEvents.rows.Count() > 0)
{
var Types = observationEvents.rows.Select(o => o.Type).Distinct();
var HasDone = date < SystemValueDate;
if (Types.Any(o => o % 4 != 0))
{
ret.Add("敲入敲出", HasDone);
}
if (Types.Any(o => o % 8 != 0 && o >= 4))
{
HasDone = observationEvents.rows.Where(o => o.Type >= 4).Any(o => o.CouponPaidStatus == 1);
ret.Add("票息", HasDone);
}
if (Types.Any(o => o >= 8))
{
HasDone = observationEvents.rows.Where(o => o.Type >= 4).Where(o => o.trade.TradeType == "自定义交易").All(o => ConsTrade.TradeCompleteStatus.Contains(o.trade.TradeStatus));
ret.Add("自定义交易", HasDone);
}
}
//除权除息
var dividendReq = new DividendTradeReq()
{
DividendDate = date.Value
};
var dividendList = new DividendService(OptUser).QueryDividendTrade(dividendReq);
if (dividendList != null && dividendList.Count() > 0)
{
ret.Add("除权除息", dividendList.All(o => o.DividendStatus));
}
//互换
var swapTradeQuery = DbContext.trade.Where(o => o.TradeType == "收益互换" && o.ValidState != "InValid" && o.TradeDate <= date && o.ExerciseDate >= date);
var swapTradeIds = swapTradeQuery.Select(o => o.id).ToList();
var swapTrades = DbContext.swap_position.Where(t => swapTradeIds.Contains(t.SwapTradeId)&&t.InterestDirection>0&&t.IsInitial&&!t.Invalid).ToList();
var hasNeedObserveSwapTrade = false;
foreach (var item in swapTradeQuery)
{
var interests = swapTrades.Where(x => x.SwapTradeId == item.id).ToList();
if (interests.Any(s=>s.SwapIntervalList.Any(x=>x.Date==date)))
{
hasNeedObserveSwapTrade = true;
break;
}
}
if (hasNeedObserveSwapTrade)
{
if (date >= SystemValueDate)
{
ret.Add("收益互换", false);
}
else
{
ret.Add("收益互换", true);
}
}
//目前只有互换有延期结算
var settledelayQuery = DbContext.trade.Where(t => !ConsTrade.UnConfirmTradeStatusList.Contains(t.TradeStatus) && t.ValidState != "InValid"
&& t.ExerciseDate <= date && t.SettlementFlag == 1
&& (!(t.UnWindDate < date && ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus))));
if (settledelayQuery.Any())
{
ret.Add("延期互换", true);
}
ret.Add("日期", date);
return ret;
}
catch (Exception)
{
throw;
}
}
/// <summary>
///
/// </summary>
/// <param name="req">筛选条件</param>
/// <param name="curTradingDate">当前交易日</param>
private Expression<Func<trade, bool>> BuildPredicate(TdTradeQueryModel req, DateTime curTradingDate, bool showChildrenGroupTrade = false)
{
var predicate = PredicateBuilder.True<trade>();
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId));
}
switch (req.OtcTradeType)
{
case OtcTradeType.Forward:
predicate = predicate.And(t => t.TradeType == "远期");
break;
case OtcTradeType.EquitySwap:
predicate = predicate.And(t => t.TradeType == "收益互换");
break;
default:
predicate = predicate.And(t => t.TradeType != "远期" && t.TradeType != "收益互换");
break;
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
predicate = predicate.And(t => t.TradeNumber.Contains(req.TradeNumber));
}
if (req.TradeTypes != null && req.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
var types = req.TradeTypes.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => types.Contains(t.TradeType) || types.Contains(t.StructureType));
}
//获取当日到期日数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日到期)
{
//如果前一天是假日,要显示包含假日的交易
var preday = QdpCalendarHelper.GetNonHolidayDefore(curTradingDate.AddDays(-1));
var dateEnd = curTradingDate.AddDays(1);
//存在当日到期的黑箱组合子交易对应的主交易id
var parentTradeIds = DbContext.trade.Where(x => x.IsGroup == 2 && x.ExerciseDate > preday && x.ExerciseDate < dateEnd).Select(x => x.ParentTradeId).ToArray();
predicate = predicate.And(t => t.ExerciseDate > preday && t.ExerciseDate < dateEnd || (parentTradeIds.Contains(t.id) && (t.StructureType.Contains("累计") || t.StructureType.Contains("累购") || t.StructureType.Contains("累沽"))));
var q = from tradeCash in DbContext.trade_cash
where tradeCash.ValueDate > preday && tradeCash.ValueDate < dateEnd && tradeCash.ExerciseWay == TradeCashExerciseWayEnum.到期行权
&& (tradeCash.Action == ClientCashInCashOut.系统操作_行权费 || tradeCash.Action == ClientCashInCashOut.系统操作_票息 || tradeCash.Action == ClientCashInCashOut.系统操作_互换)
&& tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
select tradeCash;
predicate = predicate.And(t => ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus) || q.Any(n => n.TradeId == t.id) || q.Any(n => n.ParentTradeId == t.id));
}
//获取明日到期日数据
else if (req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
var nextDay = QdpCalendarHelper.GetNonHoliday(curTradingDate.AddDays(1));
predicate = predicate.And(t => t.ExerciseDate == nextDay);
}
else if (req.ExerciseDateStart != null || req.ExerciseDateEnd != null)
{
var dateStart = req.ExerciseDateStart ?? DateTime.MinValue;
var dateEnd = req.ExerciseDateEnd ?? new DateTime(2099, 1, 1);
if (req.OtcTradeType == OtcTradeType.EquitySwap)
{
predicate = predicate.And(t => t.ExerciseDate >= dateStart && t.ExerciseDate <= dateEnd);
}
else
{
predicate = predicate.And(t => string.IsNullOrEmpty(t.ExerciseMode) || t.ExerciseDate == null ||
(t.ExerciseMode == "European" && t.ExerciseDate >= dateStart && t.ExerciseDate <= dateEnd)
|| (t.ExerciseMode == "American" && ((t.StartDate >= dateStart && t.StartDate <= dateEnd) || (t.StartDate < dateStart && t.ExerciseDate >= dateStart)))
);
}
}
//明日到期过滤已平仓,已到期,已执行数据
if (req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
var excludeStatusArr = new[] { ConsTrade.已平仓, ConsTrade.已到期, ConsTrade.已执行 };
predicate = predicate.And(t => !excludeStatusArr.Contains(t.TradeStatus));
}
if (req.TabIndex == (int)TradeTabIndexEnum.今日收益结算)
{
predicate = predicate.And(t => t.ExerciseDate > curTradingDate);
var q = from tradeCash in DbContext.trade_cash
where tradeCash.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权
&& (tradeCash.Action == ClientCashInCashOut.系统操作_行权费 || tradeCash.Action == ClientCashInCashOut.系统操作_票息 || tradeCash.Action == ClientCashInCashOut.系统操作_互换)
&& tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted && tradeCash.ValueDate == curTradingDate
select tradeCash;
predicate = predicate.And(t => q.Any(n => n.TradeId == t.id) || q.Any(n => n.ParentTradeId == t.id));
}
//获取当日成交的数据
//当日成交包括操作日期和交易日为当前系统日期的数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日成交)
{
var dateEnd = curTradingDate.AddDays(1);
predicate = predicate.And(t => t.TradeDate >= curTradingDate && t.TradeDate < dateEnd);
}
else
{
if (req.TradeDateStart != null)
{
predicate = predicate.And(t => t.TradeDate >= req.TradeDateStart.Value);
}
if (req.TradeDateEnd != null)
{
predicate = predicate.And(t => t.TradeDate <= req.TradeDateEnd.Value);
}
}
if (req.TabIndex == (int)TradeTabIndexEnum.今日敲出)
{
//敲出列表看子交易
predicate = predicate.And(t => !ConsTrade.TradeTypesForHedge.Contains(t.TradeType) && t.ValidState != "InValid" && t.TradeType != "结构化交易");
}
else
{
predicate = predicate.And(t => !ConsTrade.TradeTypesForHedge.Contains(t.TradeType)
&& t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && (t.IsGroup != 2 || t.TradeType == "收益互换" && showChildrenGroupTrade));
}
if (req.UnderlyingIds != null && req.UnderlyingIds.Any(n => n > 0))
{
predicate = predicate.And(t => req.UnderlyingIds.Contains(t.UnderlyingId));
}
if (req.VarietyId > 0)
{
var q = DbContext.underlying_manager.Where(n => n.UnderlyingTypeId == req.VarietyId);
predicate = predicate.And(t => q.Any(n => n.id == t.UnderlyingId));
}
if (req.TradeStatus != null && req.TradeStatus.Any(n => !string.IsNullOrEmpty(n)))
{
var statuses = req.TradeStatus.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => statuses.Contains(t.TradeStatus));
}
if (req.TradeTypes != null && req.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
var types = req.TradeTypes.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => types.Contains(t.TradeType) || types.Contains(t.StructureType));
}
if (!string.IsNullOrEmpty(req.ExerciseMode))
{
predicate = predicate.And(t => t.ExerciseMode == req.ExerciseMode);
}
if (!string.IsNullOrEmpty(req.BuySell))
{
predicate = predicate.And(t => t.BuySell == req.BuySell);
}
if (!string.IsNullOrEmpty(req.OptionType))
{
predicate = predicate.And(t => t.OptionType == req.OptionType);
}
if (req.AssetIds != null && req.AssetIds.Any())
{
predicate = predicate.And(t => req.AssetIds.Contains(t.AssetId));
}
if (req.ClientIds != null && req.ClientIds.Any())
{
predicate = predicate.And(t => req.ClientIds.Contains(t.ClientId));
}
if (req.TraderIds != null && req.TraderIds.Any())
{
predicate = predicate.And(t => req.TraderIds.Contains(t.TraderId));
}
return predicate;
}
/// <summary>
///
/// </summary>
/// <param name="req">筛选条件</param>
/// <param name="curTradingDate">当前交易日</param>
private Expression<Func<trade, bool>> BuildObservationStatusPredicate(TdTradeQueryModel req, DateTime curTradingDate)
{
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid");
if (req.UserAssets != null && req.UserClients != null)
{
Expression<Func<trade, bool>> pre2 = null;
if (req.UserAssets != null)
{
pre2 = PredicateBuilder.Create<trade>(t => req.UserAssets.Contains(t.AssetId));
}
if (req.UserClients != null)
{
var pre3 = PredicateBuilder.Create<trade>(t => req.UserClients.Contains(t.ClientId));
pre2 = pre2 == null ? pre3 : pre2.Or(pre3);
}
predicate = predicate.And(pre2);
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
predicate = predicate.And(t => t.TradeNumber.Contains(req.TradeNumber));
}
if (req.TabIndex == (int)ObservationStatusTradeEnum.Barrier)
{
predicate = predicate.And(t => t.TradeType == "障碍期权");
}
else if (req.TabIndex == (int)ObservationStatusTradeEnum.DoubleShark)
{
predicate = predicate.And(t => t.TradeType == "双鲨期权");
}
else if (req.TabIndex == (int)ObservationStatusTradeEnum.AutoCall)
{
predicate = predicate.And(t => t.TradeType == "凤凰期权");
}
else if (req.TabIndex == (int)ObservationStatusTradeEnum.SnowBall)
{
predicate = predicate.And(t => t.TradeType == "雪球期权");
}
else if (req.TabIndex == (int)ObservationStatusTradeEnum.Binary)
{
predicate = predicate.And(t => t.TradeType == "二元期权");
}
else if (req.TabIndex == (int)ObservationStatusTradeEnum.Accumulator)
{
predicate = predicate.And(t => t.TradeType == "累计期权");
}
predicate = predicate.And(t => t.TradeDate <= curTradingDate);
if (req.AssetIds != null && req.AssetIds.Any())
{
predicate = predicate.And(t => req.AssetIds.Contains(t.AssetId));
}
if (req.ClientIds != null && req.ClientIds.Any(n => n > 0))
{
predicate = predicate.And(t => req.ClientIds.Contains(t.ClientId));
}
if (req.UnderlyingIds != null && req.UnderlyingIds.Any(n => n > 0))
{
predicate = predicate.And(t => req.UnderlyingIds.Contains(t.UnderlyingId));
}
predicate = predicate.And(t => ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus));
if (req.TradeStatus != null && req.TradeStatus.Any(n => !string.IsNullOrEmpty(n)))
{
var statuses = req.TradeStatus.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => statuses.Contains(t.TradeStatus));
}
if (req.TradeDateStart != null)
{
predicate = predicate.And(t => t.TradeDate >= req.TradeDateStart.Value);
}
if (req.TradeDateEnd != null)
{
predicate = predicate.And(t => t.TradeDate <= req.TradeDateEnd.Value);
}
if (req.ExerciseDateStart != null)
{
predicate = predicate.And(t => t.ExerciseDate >= req.ExerciseDateStart.Value);
}
else
{
predicate = predicate.And(t => t.ExerciseDate >= curTradingDate);
}
if (req.ExerciseDateEnd != null)
{
predicate = predicate.And(t => t.ExerciseDate <= req.ExerciseDateEnd.Value);
}
return predicate;
}
private Expression<Func<trade, bool>> BuildObservationEventPredicte(TdTradeQueryModel req, DateTime curTradingDate)
{
if (req.TradeTypes == null || req.TradeTypes.All(n => string.IsNullOrEmpty(n)))
{
switch (req.TabIndex)
{
case 0:
case 1:
req.TradeTypes = ConsTrade.HasBarrierPriceOptions;
break;
case 2:
req.TradeTypes = ConsTrade.HasCouponOptions;
break;
case 3:
req.TradeTypes = new List<string>() { "自定义交易" };
break;
case 99:
req.TradeTypes = ConsTrade.HasCouponOptions.Concat(new List<string>() { "自定义交易" });
break;
default: break;
}
}
var predicate = PredicateBuilder.True<trade>();
if (req.TabIndex == 11)
{
predicate = predicate.And(t => !ConsTrade.UnConfirmTradeStatusList.Contains(t.TradeStatus) && t.ValidState != "InValid"
&& t.ExerciseDate <= curTradingDate && t.SettlementFlag == 1
&& (!(t.UnWindDate < curTradingDate && ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus))));
}
else
{
predicate = predicate.And(t => !ConsTrade.UnConfirmTradeStatusList.Contains(t.TradeStatus) && t.ValidState != "InValid"
&& t.TradeDate <= curTradingDate && t.ExerciseDate >= curTradingDate
&& (t.UnWindDate == null || t.UnWindDate >= curTradingDate || ConsTrade.LiveTradeStatusList.Contains(t.TradeStatus)));
}
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(t => req.UserAssets.Contains(t.AssetId) || req.UserClients.Contains(t.ClientId));
}
if (req.UnderlyingIds != null && req.UnderlyingIds.Any(n => n > 0))
{
predicate = predicate.And(t => req.UnderlyingIds.Contains(t.UnderlyingId));
}
if (req.TradeStatus != null && req.TradeStatus.Any(n => !string.IsNullOrEmpty(n)))
{
var statuses = req.TradeStatus.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => statuses.Contains(t.TradeStatus));
}
if (req.TradeTypes != null && req.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
var types = req.TradeTypes.Where(n => !string.IsNullOrEmpty(n)).ToArray();
predicate = predicate.And(t => types.Contains(t.TradeType) || types.Contains(t.StructureType));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
predicate = predicate.And(t => t.BuySell == req.BuySell);
}
if (req.TradeDateStart != null)
{
predicate = predicate.And(t => t.TradeDate >= req.TradeDateStart.Value);
}
if (req.TradeDateEnd != null)
{
predicate = predicate.And(t => t.TradeDate <= req.TradeDateEnd.Value);
}
if (req.ExerciseDateStart != null)
{
predicate = predicate.And(t => t.ExerciseDate >= req.ExerciseDateStart.Value);
}
if (req.ExerciseDateEnd != null)
{
predicate = predicate.And(t => t.ExerciseDate <= req.ExerciseDateEnd.Value);
}
if (req.AssetIds != null && req.AssetIds.Any())
{
predicate = predicate.And(t => req.AssetIds.Contains(t.AssetId));
}
if (req.ClientIds != null && req.ClientIds.Any())
{
predicate = predicate.And(t => req.ClientIds.Contains(t.ClientId));
}
return predicate;
}
}
/// <summary>
/// 当日场外期权数量统计
/// </summary>
public class TdTradesCountSum
{
/// <summary>
/// 当日到期交易数量
/// </summary>
public int TdExerciseCount { get; set; }
/// <summary>
/// 明日到期交易数量
/// </summary>
public int TmExerciseCount { get; set; }
/// <summary>
/// 当日提前终止交易数量
/// </summary>
public int TdEarlyStoppedCount { get; set; }
/// <summary>
/// 当日成交交易数量
/// </summary>
public int TdCreatedCount { get; set; }
/// <summary>
/// 当日敲出交易数量
/// </summary>
public int TdKnockedOutCount { get; set; }
}
public class TdPreEndTrade
{
public trade trade { get; set; }
public TradeCashDto trade_cash { get; set; }
/// <summary>
/// 实现盈亏
/// </summary>
public double? WinLoss
{
get
{
return -(trade_cash.Amount - (trade.TradePrice ?? 0) * (trade_cash.UnwindPercentRate ?? 0) * ((trade.BuySell == "卖出") ? -1 : 1));
}
}
}
public class TdPreEndTrade2
{
public int id { get; set; }
public trade trade { get; set; }
public TradeCashDto trade_cash { get; set; }
public trade_cash_swap trade_cash_swap { get; set; }
private double? winloss;
/// <summary>
/// 实现盈亏(客户角度观察)
/// </summary>
public double? WinLoss
{
get
{
if (winloss != null)
{
return winloss;
}
if (trade.TradeType == "远期")
{
return -(trade_cash.Amount + (trade.TradePrice ?? 0) * (trade_cash.UnwindPercentRate ?? 0));
}
return -(trade_cash.Amount - (trade.TradePrice ?? 0) * (trade_cash.UnwindPercentRate ?? 0) * ((trade.BuySell == "卖出") ? -1 : 1));
}
set
{
winloss = value;
}
}
}
public class TdObservationTrade
{
public int id { get { return trade.id; } }
public string EncryptId { get { return trade.EncryptId; } }
public trade trade { get; set; }
//ObservationStatus konckOutDate konckInDate CouponDate BarrierLow BarrierHigh
public string ObservationStatus { get; set; }
public DateTime? konckInOutDate { get; set; }
public double? BarrierLow { get; set; }
public double? BarrierHigh { get; set; }
public int Type { get; set; }
/// <summary>
/// 0:默认;1:已付票息2:将付票息
/// </summary>
public int CouponPaidStatus { get; set; }
}
}