using System.Linq.Expressions; using YLErp.BLL; using YLErp.Modules.DataProviderModule; using YLErp.QdpModule; namespace YLErp.Modules.EodModule { /// /// 日终结算服务 /// public class EodSettlementService : YLBaseService { public EodSettlementService(YLBaseService baseService) : base(baseService) { } public EodSettlementService(OptUserInfo userInfo) : base(userInfo) { } public EodSettlementService(OptUserInfo userInfo, YLContext dbContext) : base(userInfo, dbContext) { } /// /// 获取日终持仓数据 /// public IEnumerable GetEodTradePosition(DateTime settleDate, Expression> predicate = null) where T : EodTradePosition { var bodDate = QdpCalendarHelper.GetNonHoliday(settleDate.AddDays(1)); if (predicate == null) { predicate = PredicateBuilder.Create(n => n.ValueDate == settleDate); } else { predicate = PredicateBuilder.Create(n => n.ValueDate == settleDate).And(predicate); } var query = from eod in DbContext.Set().Where(predicate) join bod in DbContext.BodTradePosition.Where(n => n.ValueDate == bodDate) on new { eod.BookId, eod.TradeType, eod.PositionType, eod.UnderlyingCode, ExchangeOptionCode = eod.ExchangeOptionCode ?? string.Empty } equals new { bod.BookId, bod.TradeType, bod.PositionType, bod.UnderlyingCode, ExchangeOptionCode = bod.ExchangeOptionCode ?? string.Empty } into t_bod from bod in t_bod.DefaultIfEmpty() join dividend in DbContext.ex_dividend_info.Where(O => O.ExDividendDate == settleDate && O.ValidStatus) on eod.UnderlyingCode equals dividend.UnderlyingCode into t_dividend from dividend in t_dividend.DefaultIfEmpty() select new { eod, bod = bod == null ? null : new { bod.Amount, bod.Cost, //bod.AveragePrice }, dividend }; var datas = query.ToArray(); var diviService = new TradeModule.DealModule.DividendService(OptUser); var eodPriceProvider = new EodPriceProvider(settleDate); return datas.Select(data => { var eod = data.eod; var bod = data.bod; if (data.dividend != null) { if (data.eod.TradeType == "股票") { var SettlePrice = eodPriceProvider.GetPrice(data.eod.UnderlyingCode, SettlementTypeEnum.ClosePrice); SettlePrice = diviService.GetPrice(SettlePrice, data.dividend); var amount = diviService.GetPositionAmount(data.eod.Amount, data.dividend); eod.Pv = eod.Pv > 0 ? Math.Abs(amount * SettlePrice) : -Math.Abs(amount * SettlePrice); } } if (bod != null) { eod.Amount = bod.Amount; //eod.AveragePrice = bod.AveragePrice; eod.Cost = bod.Cost; } return eod; }).ToArray(); } /// /// 获取日终持仓数据 /// public IEnumerable GetEodTradePosition(DateTime settleDate, Expression> predicate = null) where TPos : EodTradePosition where TRisk : EodTradeRisk { var bodDate = QdpCalendarHelper.GetNonHoliday(settleDate.AddDays(1)); if (predicate == null) { predicate = PredicateBuilder.Create(n => n.ValueDate == settleDate); } else { predicate = PredicateBuilder.Create(n => n.ValueDate == settleDate).And(predicate); } var query = from eod in DbContext.Set().AsNoTracking().Where(predicate) join bod in DbContext.BodTradePosition.Where(n => n.ValueDate == bodDate) on new { eod.BookId, eod.TradeType, eod.PositionType, eod.UnderlyingCode, ExchangeOptionCode = eod.ExchangeOptionCode ?? string.Empty } equals new { bod.BookId, bod.TradeType, bod.PositionType, bod.UnderlyingCode, ExchangeOptionCode = bod.ExchangeOptionCode ?? string.Empty } into t_bod from bod in t_bod.DefaultIfEmpty() join dividend in DbContext.ex_dividend_info.AsNoTracking().Where(O => O.ExDividendDate == settleDate && O.ValidStatus) on eod.UnderlyingCode equals dividend.UnderlyingCode into t_dividend from dividend in t_dividend.DefaultIfEmpty() join risk in DbContext.Set().AsNoTracking().Where(n => n.ValueDate == settleDate && n.TradeId > 0) on new { eod.ValueDate, eod.TradeId } equals new { risk.ValueDate, risk.TradeId } into risk_t from risk in risk_t.DefaultIfEmpty() select new { eod, bod = bod == null ? null : new { bod.Amount, bod.Cost, //bod.AveragePrice }, dividend, risk }; var datas = query.ToArray(); var diviService = new TradeModule.DealModule.DividendService(OptUser); var eodPriceProvider = new EodPriceProvider(settleDate); return datas.Select(data => { var pos = data.eod; var bod = data.bod; if (data.dividend != null) { if (data.eod.TradeType == "股票") { var settlePrice = eodPriceProvider.GetPrice(data.eod.UnderlyingCode, SettlementTypeEnum.ClosePrice); settlePrice = diviService.GetPrice(settlePrice, data.dividend); var amount = diviService.GetPositionAmount(data.eod.Amount, data.dividend); pos.Pv = pos.Pv > 0 ? Math.Abs(amount * settlePrice) : -Math.Abs(amount * settlePrice); } } if (bod != null) { pos.Amount = bod.Amount; pos.Cost = bod.Cost; } return new EodTradePositionAndRisk(pos, data.risk); }).ToArray(); } } }