237 lines
7.2 KiB
C#
237 lines
7.2 KiB
C#
using YLErp.Abstract.DataProviders;
|
|
using YLErp.Modules.DataProviderModule;
|
|
|
|
namespace YLErp.Modules.EodModule.SettlementModule
|
|
{
|
|
/// <summary>
|
|
/// 这是一个多线程运行环境下的收盘上下文类
|
|
/// </summary>
|
|
public abstract class EodSettlementContextBase
|
|
{
|
|
EodPriceProvider _eodPriceProvider;
|
|
EodPriceProvider _preEodPriceProvider;
|
|
ExchangeStatus _exchangeStatus;
|
|
|
|
protected EodSettlementContextBase(EodSettlementRequest request, CancellationToken cancellationToken)
|
|
{
|
|
Request = request ?? throw new ArgumentNullException(nameof(request));
|
|
|
|
CancellationToken = cancellationToken;
|
|
|
|
if (request.SettleDate.Year < 2000)
|
|
{
|
|
throw new ArgumentException("request参数错误:SettleDate");
|
|
}
|
|
|
|
if (!request.IsSettleOtcTrades && !request.IsSettleExchangeTrades)
|
|
{
|
|
throw new ArgumentException("request参数错误");
|
|
}
|
|
|
|
StartDate = request.SettleDate.AddYears(-3);
|
|
|
|
PreSettleDate = BLL.valuedateBLL.GetNonHolidayDefore(SettleDate.AddDays(-1));
|
|
|
|
SystemValue = BLL.valuedateBLL.SystemDate;
|
|
|
|
PredicateBuilder = new EodQueryPredicateBuilder(request);
|
|
}
|
|
|
|
public ExchangeStatus ExchangeStatus => _exchangeStatus ?? (_exchangeStatus = new ExchangeStatus(SettleDate, PreSettleDate));
|
|
|
|
/// <summary>
|
|
/// 任务终止令牌
|
|
/// </summary>
|
|
public CancellationToken CancellationToken { get; }
|
|
|
|
/// <summary>
|
|
/// 结算请求参数
|
|
/// </summary>
|
|
public EodSettlementRequest Request { get; }
|
|
|
|
/// <summary>
|
|
/// 请求用户信息
|
|
/// </summary>
|
|
public OptUserInfo UserInfo => Request.UserInfo;
|
|
|
|
/// <summary>
|
|
/// 结算日
|
|
/// </summary>
|
|
public DateTime SettleDate => Request.SettleDate;
|
|
|
|
/// <summary>
|
|
/// 需要收盘得客户
|
|
/// </summary>
|
|
public IEnumerable<int> ClienIds => Request.ClientIds;
|
|
/// <summary>
|
|
/// 结算日
|
|
/// </summary>
|
|
public string SettleDateStr => Request.SettleDate.ToString(ConsGlobal.DateFormat);
|
|
|
|
/// <summary>
|
|
/// 获取上个结算日(结算第一步就需要检查这个日期是否等于日历数据中的前一工作日)
|
|
/// </summary>
|
|
public DateTime PreSettleDate { get; }
|
|
|
|
/// <summary>
|
|
/// 获取上个结算日(结算第一步就需要检查这个日期是否等于日历数据中的前一工作日)
|
|
/// </summary>
|
|
public string PreSettleDateStr => PreSettleDate.ToString(ConsGlobal.DateFormat);
|
|
|
|
/// <summary>
|
|
/// 交易起始关注日
|
|
/// </summary>
|
|
public DateTime StartDate { get; }
|
|
|
|
/// <summary>
|
|
/// 系统参数
|
|
/// </summary>
|
|
public valuedate SystemValue { get; }
|
|
|
|
/// <summary>
|
|
/// 查询条件构造器
|
|
/// </summary>
|
|
public EodQueryPredicateBuilder PredicateBuilder { get; }
|
|
|
|
/// <summary>
|
|
/// 是否当前交易日
|
|
/// </summary>
|
|
public bool IsCurrentDay => SettleDate == SystemValue.ValueDate;
|
|
|
|
/// <summary>
|
|
/// 获取日终价格提供对象
|
|
/// </summary>
|
|
public EodPriceProvider GetEodPriceProvider()
|
|
{
|
|
if (_eodPriceProvider == null)
|
|
{
|
|
_eodPriceProvider = new EodPriceProvider(SettleDate, isDiviendPrice: false);
|
|
if (!Request.IsPartialSettlement)
|
|
{
|
|
_eodPriceProvider.Initialize();
|
|
}
|
|
}
|
|
|
|
return _eodPriceProvider;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 收盘日上一交易日日终价格提供
|
|
/// </summary>
|
|
public EodPriceProvider GetPreEodPriceProvider()
|
|
{
|
|
if (_preEodPriceProvider == null)
|
|
{
|
|
_preEodPriceProvider = new EodPriceProvider(PreSettleDate);
|
|
_preEodPriceProvider.SetPreValueDate(PreSettleDate);
|
|
if (!Request.IsPartialSettlement)
|
|
{
|
|
_preEodPriceProvider.Initialize();
|
|
}
|
|
}
|
|
|
|
return _preEodPriceProvider;
|
|
}
|
|
|
|
#region----运行信息处理----
|
|
|
|
/// <summary>
|
|
/// 记录日志
|
|
/// </summary>
|
|
public void LogInfo(string message)
|
|
{
|
|
LogFactory.GetLogger("日终结算").Info(message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 记录日志
|
|
/// </summary>
|
|
public void LogError(string message, Exception ex = null)
|
|
{
|
|
LogFactory.GetLogger("日终结算").Error(message, ex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 激发错误异常
|
|
/// </summary>
|
|
public void RaiseError(string action, string error, Exception ex = null)
|
|
{
|
|
if (error == null)
|
|
{
|
|
error = "发生错误";
|
|
}
|
|
|
|
throw new EodSettleException($"[{action}]{error}", ex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查结算任务是否被取消
|
|
/// </summary>
|
|
public void CheckCanceled()
|
|
{
|
|
CancellationToken.ThrowIfCancellationRequested();
|
|
}
|
|
|
|
#endregion
|
|
|
|
public override string ToString()
|
|
{
|
|
return SettleDateStr;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 日终结算错误
|
|
/// </summary>
|
|
public class EodSettleException : Exception
|
|
{
|
|
public EodSettleException(string message, Exception innerException)
|
|
: base(message, innerException)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 交易所状态
|
|
/// </summary>
|
|
public class ExchangeStatus
|
|
{
|
|
readonly DateTime _preDate;
|
|
readonly Dictionary<string, (bool isholidy, DateTime exPreDate)> _dic;
|
|
|
|
public ExchangeStatus(DateTime valueDate, DateTime preDate)
|
|
{
|
|
_preDate = preDate;
|
|
_dic = new Dictionary<string, (bool, DateTime)>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
foreach (var m in DataCacheProvider.GetMarketDataSource().AsQueryable())
|
|
{
|
|
if (!string.IsNullOrEmpty(m.ExchangeNo))
|
|
{
|
|
var calendar = m.CalendarName.TrimToNull() ?? ConsGlobal.DefaultCalendar;
|
|
var isholidy = QdpModule.QdpCalendarHelper.IsHoliday(valueDate, calendar);
|
|
var exPreDate = QdpModule.QdpCalendarHelper.GetNonHolidayDefore(_preDate, calendar);
|
|
|
|
_dic[m.ExchangeNo] = (isholidy, exPreDate);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 交易所是否节假日
|
|
/// </summary>
|
|
public bool IsHoliday(string exchangeNo)
|
|
{
|
|
return !string.IsNullOrEmpty(exchangeNo) && _dic.TryGetValue(exchangeNo, out var state) && state.isholidy;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 交易所的上一个交易日
|
|
/// </summary>
|
|
public DateTime GetPreDate(string exchangeNo)
|
|
{
|
|
return !string.IsNullOrEmpty(exchangeNo) && _dic.TryGetValue(exchangeNo, out var state) ? state.exPreDate : _preDate;
|
|
}
|
|
}
|
|
}
|