489 lines
23 KiB
C#
489 lines
23 KiB
C#
using YLErp.BLL;
|
|
using YLErp.BLL.Eod;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.DBModels.Helpers;
|
|
using YLErp.Model;
|
|
using YLErp.Modules.CalculationModule;
|
|
using YLErp.Modules.DataProviderModule;
|
|
using YLErp.Modules.TradeModule.DealModule;
|
|
|
|
namespace YLErp.Modules.TradeDalModule
|
|
{
|
|
/// <summary>
|
|
/// 交易操作服务
|
|
/// </summary>
|
|
public class TradeDalService : YLBaseService
|
|
{
|
|
public TradeDalService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
|
|
}
|
|
|
|
public TradeDalService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
public void SetStructureInfo(IEnumerable<TradeLinq> trades)
|
|
{
|
|
IEnumerable<trade> lists = trades.Select(O => new trade
|
|
{
|
|
TradeType = O.TradeType,
|
|
id = O.id,
|
|
}).ToArray();
|
|
SetStructureInfo(lists);
|
|
foreach (var item in lists)
|
|
{
|
|
if (item.id <= 0) { continue; }
|
|
var t = trades.First(O => O.id == item.id);
|
|
t.SubTrades = item.SubTrades;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取结构化交易信息
|
|
/// </summary>
|
|
public void SetStructureInfo(IEnumerable<trade> trades)
|
|
{
|
|
trades = trades.Where(n => n.TradeType == "结构化交易").ToArray();
|
|
|
|
if (!trades.Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var tradeids = trades.Select(r => r.id).ToList();
|
|
var subTradeDic = new Dictionary<int, string>();
|
|
var subGrps = DbContext.trade.Where(n => tradeids.Contains(n.ParentTradeId)).Select(n => new OtcTradeDto
|
|
{
|
|
Strike = n.Strike,
|
|
BuySell = n.BuySell,
|
|
IsMoneynessOption = n.IsMoneynessOption,
|
|
ParentTradeId = n.ParentTradeId
|
|
|
|
}).ToArray().GroupBy(n => n.ParentTradeId).ToArray();
|
|
|
|
foreach (var grp in subGrps)
|
|
{
|
|
var trad = trades.First(n => n.id == grp.Key);
|
|
trad.SubTrades = grp.Select(O => new trade
|
|
{
|
|
Strike = O.Strike,
|
|
BuySell = O.BuySell,
|
|
IsMoneynessOption = O.IsMoneynessOption,
|
|
ParentTradeId = O.ParentTradeId
|
|
}).ToList();
|
|
}
|
|
}
|
|
|
|
|
|
public void SetStructureInfo(IEnumerable<trade> trades,List<trade> childTrades)
|
|
{
|
|
if (trades == null || childTrades == null)
|
|
{
|
|
return;
|
|
}
|
|
trades = trades.Where(n => n.TradeType == "结构化交易").ToArray();
|
|
|
|
if (!trades.Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var tradeids = trades.Select(r => r.id).ToList();
|
|
var subTradeDic = new Dictionary<int, string>();
|
|
var subGrps = childTrades.Where(n => tradeids.Contains(n.ParentTradeId)).Select(n => new OtcTradeDto
|
|
{
|
|
Strike = n.Strike,
|
|
BuySell = n.BuySell,
|
|
IsMoneynessOption = n.IsMoneynessOption,
|
|
ParentTradeId = n.ParentTradeId
|
|
|
|
}).ToArray().GroupBy(n => n.ParentTradeId).ToArray();
|
|
|
|
foreach (var grp in subGrps)
|
|
{
|
|
var trad = trades.First(n => n.id == grp.Key);
|
|
trad.SubTrades = grp.Select(O => new trade
|
|
{
|
|
Strike = O.Strike,
|
|
BuySell = O.BuySell,
|
|
IsMoneynessOption = O.IsMoneynessOption,
|
|
ParentTradeId = O.ParentTradeId
|
|
}).ToList();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置交易
|
|
/// </summary>
|
|
public void SetSubTradeList(List<trade> trades)
|
|
{
|
|
var subTradeDic = trades.Where(t => t.ParentTradeId > 0).AsEnumerable().GroupBy(t => t.ParentTradeId).ToDictionary(g => g.Key, g => g.ToList());
|
|
foreach (var trade in trades)
|
|
{
|
|
if (trade.TradeType == "结构化交易" && subTradeDic.ContainsKey(trade.id))
|
|
{
|
|
trade.SubTrades = subTradeDic[trade.id];
|
|
}
|
|
}
|
|
}
|
|
|
|
public TradeWithSettlement GetTradeWithSettlementTradeCash(trade trade)
|
|
{
|
|
var result = new TradeWithSettlement();
|
|
|
|
if (!ConsTrade.TradeTypesForHedge.Contains(trade.TradeType) && trade.TradeType != "现金流交易")
|
|
{
|
|
var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetCountRatio(trade.UnderlyingCode);
|
|
trade.TradeOriginalAmount = trade.OriginalNotional / CountRatio;
|
|
}
|
|
|
|
trade.LotsNewInfo = TradeLotsCalc.GetLots(trade.UnderlyingCode, trade.Notional);
|
|
if (!string.IsNullOrEmpty(trade.PairTrade))
|
|
{
|
|
var pairTrade = DbContext.trade.FirstOrDefault(x => x.id.ToString() == trade.PairTrade);
|
|
trade.PairTradeNumber = pairTrade == null ? "" : pairTrade.TradeNumber;
|
|
}
|
|
else
|
|
{
|
|
trade.PairTradeNumber = "";
|
|
}
|
|
|
|
if (trade.TradeType == "合成价差期权")
|
|
{
|
|
trade.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(trade.UnderlyingCode);
|
|
}
|
|
|
|
tradeBLL.SetFieldsByTradeType(trade);
|
|
|
|
//了结交易的持仓数量及份额需要为0
|
|
if (ConsTrade.TradeCompleteStatus.Contains(trade.TradeStatus))
|
|
{
|
|
trade.TradeAmount = 0;
|
|
trade.Notional = 0;
|
|
}
|
|
|
|
if (!ConsTrade.TradeTypesForHedge.Contains(trade.TradeType))
|
|
{
|
|
var tradeCashList = DbContext.trade_cash.Where(t =>
|
|
t.TradeId == trade.id && t.ValidState != ConsGlobal.InValid && !t.IsDeleted &&
|
|
(t.Action == ClientCashInCashOut.系统操作_行权费 || t.Action == ClientCashInCashOut.系统操作_平仓费 || t.Action == ClientCashInCashOut.系统操作_互换 || t.Action == ClientCashInCashOut.系统操作_票息)).OrderBy(t => t.ValueDate).ToList();
|
|
var tradeCashSwaps = DbContext.trade_cash_swap.Where(x => x.TradeId == trade.id).ToList();
|
|
|
|
tradeCashList.ForEach(tradeCash =>
|
|
{
|
|
if (trade.IsGroup == 1)
|
|
{
|
|
var winloss = 0.0;
|
|
var tradeCashs = DbContext.trade_cash.Where(x => x.ParentTradeCashId == tradeCash.id).ToList();
|
|
tradeCashs.ForEach(x =>
|
|
{
|
|
var tradeCashDetail = DbContext.trade_cash_detail.Where(y => y.TradeCashId == x.id);
|
|
var amount = tradeCashDetail.Any() ? tradeCashDetail.Sum(y => y.Amount ?? 0) : x.Amount;
|
|
var childTrade = DbContext.trade.Find(x.TradeId);
|
|
winloss += amount + (childTrade.TradePrice ?? 0) * (x.UnwindPercentRate ?? 0) * ((childTrade.BuySell == "卖出") ? 1 : -1);
|
|
});
|
|
tradeCash.WinLoss = winloss.OtcFormatMoney(grouping: false);
|
|
}
|
|
else
|
|
{
|
|
var tradeCashDetail = DbContext.trade_cash_detail.Where(x => x.TradeCashId == tradeCash.id);
|
|
var amount = tradeCashDetail.Any() ? tradeCashDetail.Sum(x => x.Amount ?? 0) : tradeCash.Amount;
|
|
tradeCash.WinLoss = (amount + (trade.TradePrice ?? 0) * (tradeCash.UnwindPercentRate ?? 0) * ((trade.BuySell == "卖出" || trade.TradeType == "远期") ? 1 : -1)).OtcFormatMoney(grouping: false);
|
|
|
|
if (PS.Config.IsGuoJun)
|
|
{
|
|
var Quoteamount = tradeCashDetail.Any() ? tradeCashDetail.Sum(y => y.QuoteAmount ?? 0) : (tradeCash.QuoteAmount ?? 0);
|
|
tradeCash.QuoteWinloss = (Quoteamount + (trade.TradePrice ?? 0) / (tradeCash.CurrencyRate ?? 1) * (tradeCash.UnwindPercentRate ?? 0) * ((trade.BuySell == "卖出") ? 1 : -1)).OtcFormatMoney(grouping: false);
|
|
}
|
|
}
|
|
|
|
tradeCash.SingleWinPrice = Math.Abs(tradeCash.Action == "系统操作-平仓费" && trade.IsUsePremiumRate == true ? TradeHelper.GetTradeSinglePriceByPremiumRate(tradeCash.UnwindPricePercentRate, trade.SpotPrice) : (tradeCash.UnwindPrice ?? 0));
|
|
tradeCash.SingleWinPriceString = trade.IsUsePremiumRate == true && tradeCash.Action == "系统操作-平仓费" ? (tradeCash.UnwindPricePercentRate ?? 0).OtcFormat(OtcFormatFlag.premiumRateP) : tradeCash.SingleWinPrice.OtcFormat(OtcFormatFlag.tradeSinglePrice);
|
|
tradeCash.SingleWinPricePercent = tradeCash.UnwindPricePercentRate ?? 0;
|
|
if (trade.TradeType == "收益互换")
|
|
{
|
|
tradeCash.trade_cash_swap = tradeCashSwaps.FirstOrDefault(x => x.TradeCashId == tradeCash.id);
|
|
}
|
|
});
|
|
var unWindTradeCashList = tradeCashList.Where(t => t.Action == ClientCashInCashOut.系统操作_平仓费 || (t.Action == ClientCashInCashOut.系统操作_行权费 && t.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权))
|
|
.OrderBy(t => t.ValueDate).ToList();
|
|
if (trade.TradeType == "累计期权")
|
|
{
|
|
//部分行权的记录展示在累计收益tab页面了,所以过滤掉
|
|
unWindTradeCashList = unWindTradeCashList.Where(x => x.UnwindType != "部分行权").ToList();
|
|
}
|
|
var swapTradeCashList = tradeCashList.Where(t => t.Action == ClientCashInCashOut.系统操作_互换)
|
|
.OrderBy(t => t.ValueDate).ToList();
|
|
var couponTradeCashList = tradeCashList.Where(t => t.Action == ClientCashInCashOut.系统操作_票息)
|
|
.OrderBy(t => t.ValueDate).ToList();
|
|
var maturityTradeCash = tradeCashList.FirstOrDefault(t => t.Action == ClientCashInCashOut.系统操作_行权费 && t.ExerciseWay != TradeCashExerciseWayEnum.提前终止行权 && t.IsLastAction);
|
|
if (maturityTradeCash != null)
|
|
{
|
|
maturityTradeCash.NotionalPercent = maturityTradeCash.UnwindPercentRate ?? 0;
|
|
}
|
|
|
|
bool ActualHasMinusValueOptions = valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? ConsTrade.HasMinusValueOptions.Contains(trade.TradeType) : !ConsTrade.HasMinusValueOptions.Contains(trade.TradeType);
|
|
unWindTradeCashList.ForEach(x =>
|
|
{
|
|
x.NotionalPercent = x.UnwindPercentRate ?? 0;
|
|
x.UnwindStockEqvNotional = (trade.OriginalStockEqvNotional ?? 0) * (x.UnwindPercentRate ?? 0);
|
|
if (x.HappenedDate != null)
|
|
{
|
|
x.ValueDate = x.HappenedDate.Value;
|
|
}
|
|
|
|
x.UnwindPrice = ActualHasMinusValueOptions || trade.TradeType == "远期" || trade.TradeType == "收益互换" ? x.UnwindPrice : x.UnwindPrice * (trade.BuySell == "买入" ? 1 : -1);
|
|
x.UnwindPricePercentRate = ActualHasMinusValueOptions || trade.TradeType == "远期" || trade.TradeType == "收益互换" ? x.UnwindPricePercentRate : x.UnwindPricePercentRate * (trade.BuySell == "买入" ? 1 : -1);
|
|
x.Amount = x.Amount * (valuedateBLL.SystemDate.UnwindAmountAngle == 1 || trade.TradeType == "远期" || trade.TradeType == "收益互换" ? 1 : EodOperationBase.GetSign(trade.BuySell));
|
|
x.QuoteAmount = x.QuoteAmount * (valuedateBLL.SystemDate.UnwindAmountAngle == 1 || trade.TradeType == "远期" || trade.TradeType == "收益互换" ? 1 : EodOperationBase.GetSign(trade.BuySell));
|
|
});
|
|
swapTradeCashList.ForEach(x =>
|
|
{
|
|
x.InitialAmount = x.Amount - (x.ExtraAmount ?? 0);
|
|
x.InitialSpotPrice = trade.SpotPrice ?? 0;
|
|
x.StockEqvNotional = (trade.OriginalStockEqvNotional ?? 0) * (x.NotionalPercentRate ?? 0);
|
|
});
|
|
result.UnwindTradeCashList = unWindTradeCashList;
|
|
if (trade.IsGroup == 1 && trade.TradeType == "收益互换" && unWindTradeCashList.Any())
|
|
{
|
|
var unwindTradeCash = unWindTradeCashList.FirstOrDefault();
|
|
var childrenTradeCashList = DbContext.trade_cash.Where(t =>
|
|
t.ParentTradeCashId == unwindTradeCash.id && t.ValidState != "InValid" && !t.IsDeleted &&
|
|
(t.Action == ClientCashInCashOut.系统操作_行权费 || t.Action == ClientCashInCashOut.系统操作_平仓费 || t.Action == ClientCashInCashOut.系统操作_互换)).OrderBy(t => t.ValueDate).ToList();
|
|
var childrenTradeCashIds = childrenTradeCashList.Select(x => x.id).ToList();
|
|
var childrenTradeCashSwaps = DbContext.trade_cash_swap.Where(x => childrenTradeCashIds.Contains(x.TradeCashId)).ToList();
|
|
var childrenTradeIds = childrenTradeCashList.Select(x => x.TradeId).ToList();
|
|
var childrenTrades = DbContext.trade.Where(x => childrenTradeIds.Contains(x.id)).ToList();
|
|
var childrenTradeSwaps = DbContext.trade_swap.Where(x => childrenTradeIds.Contains(x.TradeId)).ToList();
|
|
|
|
childrenTradeCashList.ForEach(tradeCash =>
|
|
{
|
|
var childTrade = childrenTrades.FirstOrDefault(y => y.id == tradeCash.TradeId);
|
|
var childrenTradeSwap = childrenTradeSwaps.FirstOrDefault(y => y.TradeId == tradeCash.TradeId);
|
|
tradeCash.UnderlyingCode = childTrade.UnderlyingCode;
|
|
tradeCash.CallPut = childrenTradeSwap.IsPayFloatingProfit ? childrenTradeSwap.PayLongShort : childrenTradeSwap.GetLongShort;
|
|
|
|
var tradeCashDetail = DbContext.trade_cash_detail.Where(x => x.TradeCashId == tradeCash.id);
|
|
var amount = tradeCashDetail.Any() ? tradeCashDetail.Sum(x => x.Amount ?? 0) : tradeCash.Amount;
|
|
tradeCash.WinLoss = (amount + (childTrade.TradePrice ?? 0) * (tradeCash.UnwindPercentRate ?? 0) * ((childTrade.BuySell == "卖出") ? 1 : -1)).OtcFormatMoney(grouping: false);
|
|
|
|
if (childTrade.TradeType == "收益互换")
|
|
{
|
|
tradeCash.trade_cash_swap = childrenTradeCashSwaps.FirstOrDefault(x => x.TradeCashId == tradeCash.id);
|
|
}
|
|
});
|
|
result.UnwindChildrenTradeCashList = childrenTradeCashList;
|
|
}
|
|
result.MaturityTradeCash = maturityTradeCash;
|
|
result.SwapTradeCashList = swapTradeCashList;
|
|
result.CouponTradeCashList = couponTradeCashList;
|
|
|
|
if (trade.ExerciseDate < valuedateBLL.ValueDate && trade.CanExpire())
|
|
{
|
|
if (EodPriceQueryService.TryGetEodPrice(trade.ExerciseDate.Value, trade.UnderlyingCode, out var eodPrice))
|
|
{
|
|
trade.FinalPrice = eodPrice.GetPrice(trade.SettlementType);
|
|
}
|
|
}
|
|
}
|
|
|
|
result.Trade = trade;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取交易信息
|
|
/// <para>优先从eod表中取</para>
|
|
/// </summary>
|
|
/// <param name="ids"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="useTracking">是否需要跟踪引用,用于需要对结果进行修改并保存的操作</param>
|
|
/// <returns></returns>
|
|
public List<trade> GetTradeOrEodTrade(IEnumerable<int> ids, DateTime valueDate, bool useTracking = false)
|
|
{
|
|
if (ids is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(ids));
|
|
}
|
|
|
|
var eodTradeArr = (from et in DbContext.eod_trade.AsNoTracking()
|
|
where et.ValueDate == valueDate
|
|
&& ids.Contains(et.TradeId)
|
|
select et).ToArray();
|
|
|
|
var newIds = ids.Except(eodTradeArr.Select(O => O.TradeId)).ToArray();
|
|
|
|
List<trade> tradeList = null;
|
|
if (newIds.Length < 1)
|
|
{
|
|
tradeList = new List<trade>();
|
|
}
|
|
else
|
|
{
|
|
tradeList = (useTracking ? DbContext.trade : DbContext.trade.AsNoTracking())
|
|
.Where(t => newIds.Contains(t.id) && t.ValidState != "InValid").ToList();
|
|
tradeBLL.SetFieldsByTradeType(tradeList);
|
|
foreach (var t in tradeList)
|
|
{
|
|
if (t.TradeType == "累计期权")
|
|
{
|
|
new TradeModule.OptionTradeActionRestoreService(this).RestoreTradeDataToSpecialDay(t, valueDate);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (useTracking)
|
|
{
|
|
tradeList.AddRange(TrackTrade(eodTradeArr));
|
|
}
|
|
else
|
|
{
|
|
tradeList.AddRange(eodTradeArr.Select(O => O.trade));
|
|
}
|
|
|
|
return tradeList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据tradeId或子交易Id
|
|
/// 用于生成交易确认书的,该方法会根据交易日去获取eodtrade而非valuedate
|
|
/// </summary>
|
|
public List<trade> GetTradeOrEodTradeOfTidASid(IEnumerable<int> tradeIds, DateTime valueDate, bool useTracking = false, bool withNoGroupChildrenTrades = true, bool useTradeDate = true)
|
|
{
|
|
if (tradeIds is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(tradeIds));
|
|
}
|
|
var pids = DbContext.trade.Where(c => tradeIds.Contains(c.id) && c.ParentTradeId > 0).Select(d => d.ParentTradeId).ToArray();
|
|
var idset = new HashSet<int>(tradeIds.Concat(pids).ToArray());
|
|
return GetTradeOrEodTradeOfTidAPid(idset, valueDate, useTracking, withNoGroupChildrenTrades, useTradeDate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据tradeId或ParentTradeId获取交易信息
|
|
/// <para>优先从eod表中取</para>
|
|
/// </summary>
|
|
public List<trade> GetTradeOrEodTradeOfTidAPid(IEnumerable<int> tradeIds, DateTime valueDate, bool useTracking = false, bool withNoGroupChildrenTrades = true, bool useTradeDate = false)
|
|
{
|
|
if (tradeIds is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(tradeIds));
|
|
}
|
|
|
|
var eodTradeArr = (from et in DbContext.eod_trade
|
|
where et.ValueDate == valueDate
|
|
&& (tradeIds.Contains(et.TradeId) || tradeIds.Contains(et.ParentTradeId))
|
|
select et).ToArray();
|
|
//生成确认书时,需要根据交易日获取当天的收盘数据,以防trade表会因为除权除息改变数据了
|
|
if (useTradeDate)
|
|
{
|
|
eodTradeArr = (from et in DbContext.eod_trade
|
|
join trade in DbContext.trade on new { id = et.TradeId, tradeDate = et.ValueDate } equals new { trade.id, tradeDate = trade.TradeDate ?? DateTime.Now }
|
|
where tradeIds.Contains(et.TradeId) || tradeIds.Contains(et.ParentTradeId)
|
|
select et).ToArray();
|
|
}
|
|
|
|
var eodTradeIds = eodTradeArr.Select(O => O.TradeId).ToArray();
|
|
|
|
var tradeList = (from t in useTracking ? DbContext.trade : DbContext.trade.AsNoTracking()
|
|
where !eodTradeIds.Contains(t.id) && (tradeIds.Contains(t.id) || tradeIds.Contains(t.ParentTradeId))
|
|
&& t.ValidState != "InValid"
|
|
select t).ToList();
|
|
|
|
if (withNoGroupChildrenTrades)
|
|
{
|
|
tradeList = (from t in useTracking ? DbContext.trade : DbContext.trade.AsNoTracking()
|
|
where !eodTradeIds.Contains(t.id) && (tradeIds.Contains(t.id) || tradeIds.Contains(t.ParentTradeId))
|
|
&& t.ValidState != "InValid"
|
|
&& t.IsGroup != 2
|
|
select t).ToList();
|
|
}
|
|
|
|
tradeBLL.SetFieldsByTradeType(tradeList);
|
|
if (useTracking)
|
|
{
|
|
tradeList.AddRange(TrackTrade(eodTradeArr));
|
|
}
|
|
else
|
|
{
|
|
tradeList.AddRange(eodTradeArr.Select(O => O.trade));
|
|
}
|
|
return tradeList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取结构化交易信息
|
|
/// <para>优先从eod表中取</para>
|
|
/// </summary>
|
|
/// <param name="parentIds"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <returns></returns>
|
|
public List<trade> GetStructTradeFromTradeOrEodTrade(IEnumerable<int> parentIds, DateTime valueDate, bool useTracking = false)
|
|
{
|
|
if (parentIds is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(parentIds));
|
|
}
|
|
|
|
var eodTradeArr = (from et in DbContext.eod_trade
|
|
where et.ValueDate == valueDate
|
|
&& (parentIds.Contains(et.ParentTradeId))
|
|
select et).ToArray();
|
|
List<trade> tradeList = null;
|
|
var newIds = parentIds.Except(eodTradeArr.Select(O => O.ParentTradeId)).ToArray();
|
|
if (newIds.Length < 1)
|
|
{
|
|
tradeList = new List<trade>();
|
|
}
|
|
else
|
|
{
|
|
tradeList = (from t in useTracking ? DbContext.trade : DbContext.trade.AsNoTracking()
|
|
where newIds.Contains(t.ParentTradeId)
|
|
&& t.ValidState != "InValid"
|
|
select t).ToList();
|
|
}
|
|
if (useTracking)
|
|
{
|
|
tradeList.AddRange(TrackTrade(eodTradeArr));
|
|
}
|
|
else
|
|
{
|
|
tradeList.AddRange(eodTradeArr.Select(O => O.trade));
|
|
}
|
|
return tradeList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将交易还原到某日收盘之前
|
|
/// <para>主要针对除权除息过的交易</para>
|
|
/// </summary>
|
|
/// <param name="t"></param>
|
|
/// <param name="valueDate"></param>
|
|
public void RollbackToBeforeSettle(trade t, DateTime valueDate)
|
|
{
|
|
var originTrade = GetTradeOrEodTrade(new[] { t.id }, valueDate).FirstOrDefault();
|
|
|
|
if (originTrade != null && originTrade.Notional > 0)
|
|
{
|
|
//将交易信息还原到收盘前
|
|
DividendService.SetDividendTradeData(t, originTrade);
|
|
}
|
|
}
|
|
|
|
private List<trade> TrackTrade(IEnumerable<eod_trade> eodTrades)
|
|
{
|
|
var result = new List<trade>();
|
|
var eodIds = eodTrades.Select(O => O.TradeId);
|
|
var trades = eodTrades.Select(O => O.trade);
|
|
var trackTrades = DbContext.trade.Where(O => eodIds.Contains(O.id)).ToDictionary(K => K.id, V => V);
|
|
foreach (var item in trades)
|
|
{
|
|
DividendService.SetDividendTradeData(trackTrades[item.id], item);
|
|
result.Add(trackTrades[item.id]);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|