Files
2024-05-09 14:06:26 +08:00

197 lines
7.4 KiB
C#

using YLErp.Abstract;
namespace YLErp.Modules.TradeRiskCalcModule.TaskRunner
{
/// <summary>
/// 交易数据源
/// </summary>
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);
}
/// <summary>
/// 获取所有未结算过的场外交易
/// </summary>
public IEnumerable<trade> GetOtcTrades()
{
return _otcTradeTraceUpdater.GetDatas();
}
/// <summary>
/// 获取所有未结算过的对冲交易
/// </summary>
public IEnumerable<ExchangeTrade> GetExchangeTrades()
{
return _exchangeTradeTraceUpdater.GetDatas();
}
/// <summary>
/// 获取所有数据跟踪更新器
/// </summary>
public IEnumerable<IDataUpdater> GetDataUpdaters()
{
return new IDataUpdater[] { _otcTradeTraceUpdater, _exchangeTradeTraceUpdater };
}
class OtcTradeTraceUpdater : IDataUpdater
{
int _maxId = 0;
readonly DateTime _valueDate;
readonly DateTime _lastSettleDate;
readonly Dictionary<int, trade> _tradeDic;
public OtcTradeTraceUpdater(DateTime valueDate, DateTime lastSettleDate)
{
_valueDate = valueDate;
_lastSettleDate = lastSettleDate;
_tradeDic = new Dictionary<int, trade>(100);
}
public string TableName => nameof(trade);
public void UpdateData(IEnumerable<string> 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<trade> GetDatas()
{
return _tradeDic.Values.Select(n => n.Clone()).ToArray();
}
}
class ExchangeTradeTraceUpdater : IDataUpdater
{
int _maxId = 0;
readonly DateTime _valueDate;
readonly DateTime _lastSettleDate;
readonly Dictionary<int, ExchangeTrade> _tradeDic;
public ExchangeTradeTraceUpdater(DateTime valueDate, DateTime lastSettleDate)
{
_valueDate = valueDate;
_lastSettleDate = lastSettleDate;
_tradeDic = new Dictionary<int, ExchangeTrade>(300);
}
public string TableName => nameof(ExchangeTrade);
public void UpdateData(IEnumerable<string> 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<ExchangeTrade> GetDatas()
{
return _tradeDic.Values.Select(n => n.Clone()).ToArray();
}
}
}
}