195 lines
7.4 KiB
C#
195 lines
7.4 KiB
C#
using YLErp.Configuration;
|
|
using YLErp.Modules.DataProviderModule;
|
|
|
|
namespace YLErp.Modules.EodModule.SettlementModule
|
|
{
|
|
public class EodSettlementContextV2 : EodSettlementContextBase
|
|
{
|
|
List<trade> _otcTrades;
|
|
TradeCashDataProvider _tradeCashProvider;
|
|
|
|
//节假日不需要处理的交易
|
|
IEnumerable<trade> _holidayTrades;
|
|
HashSet<int> _holidayTradeIds;
|
|
EodCurrencyProvider _currencyProvider;
|
|
IEnumerable<string> _currencyCodes;
|
|
|
|
public EodSettlementContextV2(EodSettlementRequest request, SettlementConfig settlementConfig, CancellationToken cancellationToken)
|
|
: base(request, cancellationToken)
|
|
{
|
|
SettlementConfig = settlementConfig ?? throw new ArgumentNullException(nameof(settlementConfig));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 结算配置
|
|
/// </summary>
|
|
public SettlementConfig SettlementConfig { get; }
|
|
|
|
/// <summary>
|
|
/// 衍生品交易
|
|
/// </summary>
|
|
public List<trade> OtcTrades
|
|
{
|
|
get
|
|
{
|
|
if (_otcTrades == null)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (_otcTrades == null)
|
|
{
|
|
_otcTrades = InitOtcTrades();
|
|
}
|
|
}
|
|
}
|
|
return _otcTrades;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 节假日不需要处理的交易
|
|
/// </summary>
|
|
public IEnumerable<trade> HolidayTrades
|
|
{
|
|
get
|
|
{
|
|
if (_holidayTrades == null)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (_holidayTrades == null)
|
|
{
|
|
_holidayTrades = OtcTrades.Where(n =>
|
|
{
|
|
var un = DataCacheProvider.GetUnderlyingDataSource().GetData(n.UnderlyingCode);
|
|
if (string.IsNullOrEmpty(un?.MarketCode))
|
|
{
|
|
return false;
|
|
}
|
|
return ExchangeStatus.IsHoliday(un.MarketCode);
|
|
}).ToArray();
|
|
}
|
|
}
|
|
}
|
|
return _holidayTrades;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化缓存(重置缓存)
|
|
/// </summary>
|
|
public List<trade> InitOtcTrades(bool isGuoJunNeedBesideSwapTrade = false)
|
|
{
|
|
var list = new EodSettleDataQueryService(UserInfo)
|
|
.GetOtcTrades(SettleDate, PredicateBuilder.GetOtcTradePredicate(isGuoJunNeedBesideSwapTrade), out _tradeCashProvider);
|
|
|
|
var hisDataProvider = new TradeHisDataProvider(SettleDate).Initialize();
|
|
var underlyingIds = list.Where(O => O.DividendRate == null).Select(O => O.UnderlyingId);
|
|
var umDividendDict =
|
|
DbContextFactory.GetYLDbContext().UnderlyingDividend
|
|
.Where(O =>
|
|
underlyingIds.Contains(O.UnderlyingId) &&
|
|
O.ValueDate <= SettleDate).ToList()
|
|
.GroupBy(O => O.UnderlyingId)
|
|
.ToDictionary(K =>
|
|
K.Key,
|
|
V =>
|
|
V.OrderByDescending(O => O.ValueDate).FirstOrDefault().DividendRate);
|
|
|
|
var recordlist = DbContextFactory.GetYLDbContext().dividendrate_record.Where(x => SettleDate >= x.ValueDate).ToList();
|
|
|
|
foreach (var item in list)
|
|
{
|
|
var noRiskRate = hisDataProvider.GetNoRiskRate(item.id);
|
|
var dividendRate = hisDataProvider.GetDividendRate(item.id);
|
|
|
|
//国元固收默认从全局配置里取分红率,如果TradeHisData里有分红率,则根据生效时间取最优
|
|
if (recordlist != null && recordlist.Any())
|
|
{
|
|
var record = recordlist.Where(x => x.UnderlyingCode.Split(',').Any(code => code == item.UnderlyingCode) && x.TradeType.Contains(item.TradeType) && (x.OptionType == item.OptionType || x.OptionType == "全部")).OrderByDescending(x => x.OptDate).OrderByDescending(x => x.ValueDate);
|
|
if (record.Any())
|
|
{
|
|
dividendRate = record.FirstOrDefault()?.DividendRate;
|
|
}
|
|
}
|
|
|
|
//如果修改过无风险利率或分红率,且和eodTrade中不匹配,则移除该交易来自EodTrade的标记;
|
|
if (((noRiskRate ?? 0) > 0 && noRiskRate.GetValueOrDefault() != item.NoRiskRate.GetValueOrDefault()) || (dividendRate.HasValue &&
|
|
dividendRate.GetValueOrDefault() != item.DividendRate.GetValueOrDefault()))
|
|
{
|
|
item.MetaDic.Remove("from_eod_trade");
|
|
}
|
|
item.NoRiskRate = noRiskRate ?? item.NoRiskRate ?? BLL.valuedateBLL.RiskFreeRate;
|
|
item.DividendRate = dividendRate ?? item.DividendRate;
|
|
if (item.DividendRate == null)
|
|
{
|
|
item.DividendRate =
|
|
umDividendDict.TryGetValue(item.UnderlyingId, out var value) ?
|
|
value :
|
|
DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.DividendRate ?? item.NoRiskRate;
|
|
}
|
|
}
|
|
|
|
_otcTrades = list;
|
|
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 交易资金流水数据提供
|
|
/// </summary>
|
|
public ITradeCashDataProvider TradeCashProvider => _tradeCashProvider ?? (_tradeCashProvider = new TradeCashDataProvider());
|
|
|
|
/// <summary>
|
|
/// 是否当前结算日期时交易所为节假日的交易
|
|
/// </summary>
|
|
public bool IsHolidayTrade(int tradeId)
|
|
{
|
|
if (_holidayTradeIds == null)
|
|
{
|
|
_holidayTradeIds = HolidayTrades.Select(n => n.id).ToHashSet();
|
|
}
|
|
|
|
return _holidayTradeIds.Contains(tradeId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取日终汇率提供对象
|
|
/// </summary>
|
|
public EodCurrencyProvider EodCurrencyProvider
|
|
{
|
|
get
|
|
{
|
|
if (_currencyProvider == null)
|
|
{
|
|
_currencyProvider = new EodCurrencyProvider(SettleDate, seekPreDay: false);
|
|
}
|
|
return _currencyProvider;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 多币种代码(所有代码都大写)
|
|
/// </summary>
|
|
public IEnumerable<string> CurrencyCodes
|
|
{
|
|
get
|
|
{
|
|
if (_currencyCodes == null)
|
|
{
|
|
_currencyCodes = DbContextFactory.GetYLDbContext().currency
|
|
.Where(n => n.StartDate == null || n.StartDate.Value <= SettleDate)
|
|
.Select(n => n.CurrencyCode).AsEnumerable()
|
|
.Select(n => n.ToUpperInvariant()).ToArray();
|
|
|
|
if (_currencyCodes == null || !_currencyCodes.Any())
|
|
{
|
|
_currencyCodes = new string[] { string.Empty };
|
|
}
|
|
}
|
|
return _currencyCodes;
|
|
}
|
|
}
|
|
}
|
|
}
|