Files
zszq-trs/Tools/YLTestTool/Modules/TradeRiskCalcModule/TradeRiskCalcTestContext.cs
T
2024-05-09 14:06:26 +08:00

258 lines
9.1 KiB
C#

using System.Linq.Expressions;
using YLErp.Abstract;
using YLErp.Abstract.DataProviders;
using YLErp.Commons;
using YLErp.DBModels;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.CalculationModule.Abstract;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.EodModule;
using YLErp.Modules.TradeRiskCalcModule.Abstract;
namespace YLErp.Modules.TradeRiskCalcModule
{
class TradeRiskCalcTestContextBase
{
public DateTime ValueDate { get; }
public bool IsEodSettle { get; }
public bool UseClosePrice { get; }
public TraceWrap Trace { get; }
protected TradeRiskCalcTestContextBase(TradeRiskCalcTestRequest request)
{
if (request is null)
{
throw new ArgumentNullException(nameof(request));
}
ValueDate = request.ValueDate;
IsEodSettle = request.IsEodSettle;
UseClosePrice = request.UseClosePrice;
Trace = new TraceWrap("实时风险调试");
}
}
class TradeRiskCalcTestContext : TradeRiskCalcTestContextBase, ITradeRiskCalcContext
{
readonly TradeRiskCalcTestRequest2 _request2;
public TradeRiskCalcTestContext(TradeRiskCalcTestRequest request, TradeRiskCalcTestRequest2 request2) : base(request)
{
_request2 = request2 ?? throw new ArgumentNullException(nameof(request));
VolType = request.VolType;
Trace.WriteLine("当前交易日:" + ValueDate);
PreValueDate = QdpModule.QdpCalendarHelper.GetNonHolidayDefore(request.ValueDate.AddDays(-1));
PreSettleDate = BLL.Eod.EodOperationBase.GetLastSettlementDate(ValueDate, true);
Trace.WriteLine("上一交易日:" + PreSettleDate);
OptionCalcDataProvider = new OptionCalcDataProvider(this);
YdEodPriceProvider = new EodPriceProvider(PreSettleDate);
YdTradeHisDataProvider = new TradeHisDataProvider(PreSettleDate);
YdEodPositionDataProvider = new YdEodPositionDataProvider().Initialize(_request2, PreSettleDate, OptionCalcDataProvider.UnderlyingDataProvider);
}
public string VolType { get; }
public DateTime PreValueDate { get; }
public DateTime PreSettleDate { get; }
public IOptionCalcDataProvider OptionCalcDataProvider { get; }
public IEodPriceProvider YdEodPriceProvider { get; }
public ITradeHisDataProvider YdTradeHisDataProvider { get; }
public bool HasError { get; private set; }
public void AddError(string error)
{
HasError = true;
Trace.WriteLine("[ERROR]发生错误:" + error);
}
IPriceProvider _ExchangeOptionPriceProvider;
public IHedgePnlCalcContext CreateHedgePnlCalcContext(IOtcTradeValueCalcContext optionValueCaclContext)
{
if (_ExchangeOptionPriceProvider == null)
{
if (IsEodSettle)
{
_ExchangeOptionPriceProvider = new EodExchangeOptionPriceProvider(ValueDate, UseClosePrice);
}
else
{
_ExchangeOptionPriceProvider = new ExchangeOptionPriceProvider();
}
}
return new HedgePnlCalcContext(optionValueCaclContext, new ExchangeTradeCommissionCalc(), _ExchangeOptionPriceProvider);
}
OptionCalcDataProvider _OptionCalcDataProvider;
public IOtcTradeValueCalcContext CreateOptionValueCalcContext(double sysRiskFreeRate)
{
if (_OptionCalcDataProvider == null)
{
_OptionCalcDataProvider = new OptionCalcDataProvider(this);
}
return new OptionValueCalcContext(VolType, IsEodSettle, ValueDate, sysRiskFreeRate, _OptionCalcDataProvider)
{
Trace = Trace,
CalcScenario = Enums.CalcScenarioEnum.RealtimeRisk
};
}
public IEnumerable<string> GetErrors()
{
throw new NotImplementedException();
}
public IEnumerable<trade_cash> GetTrade_Cashes(IEnumerable<int> tradeIds)
{
using (var db = DbContextFactory.GetYLDbContext())
{
//在使用时会判断ValidState(猜测是为新增待确认的交易)
return db.trade_cash.Where(t => tradeIds.Contains(t.TradeId) && !t.IsDeleted).ToList();
}
}
public ITradeRiskEodPositionDataProvider YdEodPositionDataProvider { get; }
}
class YdEodPositionDataProvider : ITradeRiskEodPositionDataProvider
{
readonly Dictionary<int, EodTradePositionAndRisk> _positionVolOtcTradeDic;
readonly Dictionary<int, EodTradePositionAndRisk> _hedgeVolOtcTradeDic;
readonly List<EodTradePosition> _exchangeTradeList;
public YdEodPositionDataProvider()
{
_positionVolOtcTradeDic = new Dictionary<int, EodTradePositionAndRisk>();
_hedgeVolOtcTradeDic = new Dictionary<int, EodTradePositionAndRisk>();
_exchangeTradeList = new List<EodTradePosition>();
}
private Expression<Func<T, bool>> CreatePredicate<T>(TradeRiskCalcTestRequest2 _request2) where T : EodTradePosition
{
var predicate = PredicateBuilder.True<T>();
if (_request2.TradeId > 0)
{
predicate = predicate.And(n => n.TradeId == _request2.TradeId);
}
else
{
if (_request2.ClientId > 0)
{
predicate = predicate.And(n => n.ClientId == _request2.ClientId);
}
if (_request2.UnderlyingCodes != null && _request2.UnderlyingCodes.Any())
{
predicate = predicate.And(n => _request2.UnderlyingCodes.Contains(n.UnderlyingCode, StringComparer.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(_request2.TradeType))
{
predicate = predicate.And(n => _request2.TradeType.Equals(n.TradeType, StringComparison.OrdinalIgnoreCase));
}
if (_request2.AssetBookId > 0)
{
predicate = predicate.And(n => n.BookId == _request2.AssetBookId);
}
}
return predicate;
}
public YdEodPositionDataProvider Initialize(TradeRiskCalcTestRequest2 request, DateTime positionDate, IUnderlyingDataProvider underlyingDataProvider)
{
if (underlyingDataProvider is null)
{
throw new ArgumentNullException(nameof(underlyingDataProvider));
}
var where = CreatePredicate<eod_trade_position>(request);
_exchangeTradeList.Capacity = 500;
var service = new EodSettlementService(OptUserInfo.SystemUser);
var eodPositions = service.GetEodTradePosition<eod_trade_position, eod_trade_risk>(positionDate, where);
foreach (var item in eodPositions)
{
if (item.Position.TradeId > 0)
{
_positionVolOtcTradeDic[item.Position.TradeId] = item;
}
else if (item.Position.TradeType == "商品期货")
{
var un = underlyingDataProvider.GetUnderlying(item.Position.UnderlyingCode);
if (un == null || un.MaturityDate.HasValue && DateTime.Compare(un.MaturityDate.Value, positionDate) > 0)
{
_exchangeTradeList.Add(item.Position);
}
}
else
{
_exchangeTradeList.Add(item.Position);
}
}
_exchangeTradeList.TrimExcess();
var where2 = CreatePredicate<eod_trade_position_hedgevol>(request).And(x => x.TradeId > 0);
//对冲波动率计算出来的日终持仓
var eodPositions2 = service.GetEodTradePosition<eod_trade_position_hedgevol, eod_trade_risk_hedgevol>(positionDate, where2);
foreach (var item in eodPositions2)
{
if (item.Position.TradeId > 0)
{
_hedgeVolOtcTradeDic[item.Position.TradeId] = item;
}
}
return this;
}
/// <summary>
/// 根据交易ID和波动率类型获取场外交易
/// </summary>
/// <param name="tradeId"></param>
/// <param name="volType">对冲|持仓</param>
/// <returns></returns>
public EodTradePositionAndRisk GetOtcTradePositionData(int tradeId, string volType)
{
if (volType == "对冲")
{
return _hedgeVolOtcTradeDic.TryGetValue(tradeId, out var item) ? item : null;
}
else
{
return _positionVolOtcTradeDic.TryGetValue(tradeId, out var item) ? item : null;
}
}
public IEnumerable<EodTradePosition> GetExchangeTradePositionList(string volType) => _exchangeTradeList;
}
}