using YLErp.Abstract; namespace YLErp.Modules.TradeRiskCalcModule.TaskRunner { /// /// 交易数据源 /// public class TradeDataSource : ITradeDataSource { readonly OtcTradeTraceUpdater _otcTradeTraceUpdater; readonly ExchangeTradeTraceUpdater _exchangeTradeTraceUpdater; public TradeDataSource(DateTime valueDate, DateTime lastSettleDate) { _otcTradeTraceUpdater = new OtcTradeTraceUpdater(valueDate, lastSettleDate); _exchangeTradeTraceUpdater = new ExchangeTradeTraceUpdater(valueDate, lastSettleDate); } /// /// 获取所有未结算过的场外交易 /// public IEnumerable GetOtcTrades() { return _otcTradeTraceUpdater.GetDatas(); } /// /// 获取所有未结算过的对冲交易 /// public IEnumerable GetExchangeTrades() { return _exchangeTradeTraceUpdater.GetDatas(); } /// /// 获取所有数据跟踪更新器 /// public IEnumerable GetDataUpdaters() { return new IDataUpdater[] { _otcTradeTraceUpdater, _exchangeTradeTraceUpdater }; } class OtcTradeTraceUpdater : IDataUpdater { int _maxId = 0; readonly DateTime _valueDate; readonly DateTime _lastSettleDate; readonly Dictionary _tradeDic; public OtcTradeTraceUpdater(DateTime valueDate, DateTime lastSettleDate) { _valueDate = valueDate; _lastSettleDate = lastSettleDate; _tradeDic = new Dictionary(100); } public string TableName => nameof(trade); public void UpdateData(IEnumerable updateKeyIds) { var updateIdSet = DataConvert.ConvertToInt32Set(updateKeyIds); var db = DbContextFactory.GetYLDbContext(); var minId = _maxId; var maxId = db.trade.Max(n => (int?)n.id) ?? 0; if (maxId < minId) { minId = 0; } if (maxId == minId && !updateIdSet.Any(n => n > 0)) { return; } //构建Linq查询语句 var startDate = _valueDate.AddYears(-3); var suspensUmCodes = db.underlying_manager.Where(um => um.UnderlyingStatus == underlying_manager.Status_Suspension).Select(n => n.UnderlyingCode).ToArray(); var otcTradeQuery = from trad in db.trade.AsNoTracking() where ((trad.id > minId && trad.id <= maxId) || updateIdSet.Contains(trad.id)) && trad.TradeDate > startDate && trad.TradeType != "结构化交易" && !ConsTrade.TradeTypesForHedge.Contains(trad.TradeType) && trad.ValidState != "InValid" && trad.TradeStatus != ConsTrade.已拒绝 && trad.TradeDate <= _valueDate && (!ConsTrade.TradeCompleteStatus.Contains(trad.TradeStatus) || trad.TradeDate == _valueDate || trad.UnWindDate == _valueDate) //行权日过滤条件,行权日大于当前交易日,或者停牌的活着的期权交易 && (trad.ExerciseDate == null || trad.ExerciseDate >= _valueDate || (suspensUmCodes.Contains(trad.UnderlyingCode) && ConsTrade.NeedMarginTradeStatusList.Contains(trad.TradeStatus)) ) select trad; //从数据库中获取数据 var otcTradeData = otcTradeQuery.ToArray(); //更新奇异期权数据源 Events.EventBus.Publish(new OtcTradeUpdateEvent { TradeIds = updateIdSet }); //选取符合条件的数据 foreach (var data in otcTradeData) { updateIdSet.Remove(data.id); _tradeDic[data.id] = data; } //取不到数据的直接从本地字典中删除 updateIdSet.Remove(0); foreach (var id in updateIdSet) { _tradeDic.Remove(id); } _maxId = maxId; } public IEnumerable GetDatas() { return _tradeDic.Values.Select(n => n.Clone()).ToArray(); } } class ExchangeTradeTraceUpdater : IDataUpdater { int _maxId = 0; readonly DateTime _valueDate; readonly DateTime _lastSettleDate; readonly Dictionary _tradeDic; public ExchangeTradeTraceUpdater(DateTime valueDate, DateTime lastSettleDate) { _valueDate = valueDate; _lastSettleDate = lastSettleDate; _tradeDic = new Dictionary(300); } public string TableName => nameof(ExchangeTrade); public void UpdateData(IEnumerable updateKeyIds) { var updateIdSet = DataConvert.ConvertToInt32Set(updateKeyIds); var db = DbContextFactory.GetYLDbContext(); var minId = _maxId; var maxId = db.ExchangeTrade.Max(n => (int?)n.id) ?? 0; if (maxId < minId) { minId = 0; } if (maxId == minId && !updateIdSet.Any(n => n > 0)) { return; } //构建Linq查询语句 var hedgeTradeQuery = from trad in db.ExchangeTrade.AsNoTracking() where trad.TradeDate > _lastSettleDate && trad.TradeDate <= _valueDate && ((trad.id > minId && trad.id <= maxId) || updateIdSet.Contains(trad.id)) && (trad.MaturityDate >= _valueDate || trad.MaturityDate == null) && trad.IsValid select trad; //从数据库中获取数据 var hedginTradeData = hedgeTradeQuery.ToArray(); //选取符合条件的数据 foreach (var data in hedginTradeData) { updateIdSet.Remove(data.id); _tradeDic[data.id] = data; } //取不到数据的直接从本地字典中删除 updateIdSet.Remove(0); foreach (var id in updateIdSet) { _tradeDic.Remove(id); } //设置当前最大ID _maxId = maxId; } public IEnumerable GetDatas() { return _tradeDic.Values.Select(n => n.Clone()).ToArray(); } } } }