Files
zszq-trs/YLErpDAL/Modules/EodModule/SettlementModule/EodDividenService.cs
T
2024-05-09 14:06:26 +08:00

221 lines
8.8 KiB
C#

using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.DBModels.Helpers;
using YLErp.Helpers;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.TradeModule;
using YLErp.Modules.TradeModule.DealModule;
using YLErp.QdpModule;
namespace YLErp.Modules.EodModule.SettlementModule
{
/// <summary>
/// 日终结算除权除息
/// </summary>
public class EodDividenService : EodSettleServiceBase
{
public const string Step = "除权除息";
readonly DateTime _bodDate;
public EodDividenService(EodSettlementContextBase context) : base(context)
{
_bodDate = QdpCalendarHelper.GetNonHoliday(SettleDate.AddDays(1));
}
//------------------------------------------------------
// 备份次日初持仓数据
// 将settleDate未了结的交易,进行除权除息
// 将场内部分结果保存到bod_trade_position表和trade_position表
// 将场外部分结果保存到trade和bodTrade表
// 次日开仓场内持仓数据从bod_trade_position表开始
// 次日开仓场外交易数据从trade表开始
//------------------------------------------------------
/// <summary>
/// 场内交易除权除息处理
/// </summary>
public void Execute(IEnumerable<EodTradePosition> eodPositionList)
{
if (eodPositionList is null || !eodPositionList.Any())
{
return;
}
var exchangePositionList = eodPositionList.Where(O => ConsTrade.TradeTypesForHedge.Contains(O.TradeType)|| ConsTrade.BondTypeList.Contains(O.TradeType)).ToList();
var bodTradePositions = new DividendService(OptUser).Execute(_context.SettleDate, exchangePositionList);
foreach (var item in bodTradePositions)
{
item.ValueDate = _bodDate;
}
using (var db = DbContextFactory.GetYLDbContext())
{
db.BodTradePosition.AddRange(bodTradePositions);
if (_context.IsCurrentDay)
{
var tpList = ConvertToTradePosition(bodTradePositions);
db.TradePosition.AddRange(tpList);
db.BulkDelete<TradePosition>("1=1");
}
BodTradePosition t;
db.BulkDelete<BodTradePosition>($"{nameof(t.ValueDate)}='{_bodDate:yyyy-MM-dd}'");
db.SaveChanges(_context.CancellationToken);
}
}
/// <summary>
/// 场外交易除权除息处理
/// </summary>
public void Execute(IEnumerable<trade> trades)
{
if (trades is null || !trades.Any())
{
return;
}
var bodTrades = new DividendService(OptUser).Execute(SettleDate, trades, out var useSaveTrades, out var useSaveUnderlyings);
foreach (var item in bodTrades)
{
item.ValueDate = _bodDate;
}
bod_trade t;
using (var db = DbContextFactory.GetYLDbContext())
{
db.bod_Trade.AddRange(bodTrades);
//更新underlying数据
if (useSaveUnderlyings.Any())
{
var service = new DbRecordChangesService<UnderlyingChanges>(UserInfo, db);
List<UnderlyingChanges> ucList = new List<UnderlyingChanges>();
var ids = useSaveUnderlyings.Select(O => O.id);
var dbUm = db.underlying_manager.Where(O => ids.Contains(O.id)).ToArray();
foreach (var item in useSaveUnderlyings)
{
var um = dbUm.FirstOrDefault(O => O.id == item.id);
if (um == null)
{
continue;
}
var uc = new UnderlyingChanges
{
ChangeType = ConsInfoChangeType.Dividend,
RecordId = um.id,
FieldName = nameof(underlying_manager.SubData),
FieldValue = um.SubData ?? "",
NewValue = item.SubData ?? "",
OptDate = SettleDate,
Update = DateTime.Now
};
ucList.Add(uc);
um.SubData = item.SubData;
}
service.Save(ucList, false);
}
//更新trade数据
if (useSaveTrades.Any())
{
var ids = useSaveTrades.Select(O => O.id).ToList();
var tradeList = db.trade.Where(O => ids.Contains(O.id)).ToList();
new TradeExtendService(UserInfo, db).SetTradeExtend(tradeList, tracking: true);
foreach (var item in useSaveTrades)
{
var td = tradeList.FirstOrDefault(O => O.id == item.id);
if (td == null || td.DividendDate >= item.DividendDate
|| td.OriginalNotional >= item.OriginalNotional
|| Math.Abs((td.OriginalNotional - item.OriginalNotional) ?? 0) < 1e-5)
{
continue;
}
//var changes = TradeChangeUtil.GetAllChanges(td, item);
//var changsStr = TradeChangeUtil.SerializeChanges(changes, out var auditFlag);
TradeHelper2.ReduceTradeExt(td);
TradeHelper2.ReduceTradeExt(item);
var changsStr = DataChangeHelper.GetDataChanges(td, item).ToJson();
db.TradeAuditLog.Add(new TradeAuditLog
{
TradeId = td.id,
Changes = changsStr,
DataType = "C01",
OptId = UserId,
OptName = UserName,
OptDate = OptDate,
OptType = "除权除息",
AuditFlag = TradeAuditFlag.operation //| auditFlag
});
var changeList = DividendService.GetDividendChanges(td, item);
new DbRecordChangesService<TradeChanges>(OptUser, db).Save(changeList, false);
DividendService.SetDividendTradeData(td, item);
}
}
if (_context.ClienIds!=null&& _context.ClienIds.Any())
{
string strClientWhere=string.Join(",", _context.ClienIds);
db.BulkDelete<bod_trade>($"{nameof(t.ValueDate)}='{_bodDate:yyyy-MM-dd}' and ClientId in ({strClientWhere})");
}
else
{
db.BulkDelete<bod_trade>($"{nameof(t.ValueDate)}='{_bodDate:yyyy-MM-dd}'");
}
db.SaveChanges(_context.CancellationToken);
}
}
private IEnumerable<TradePosition> ConvertToTradePosition(IEnumerable<BodTradePosition> positions)
{
var tpList = new List<TradePosition>();
foreach (var item in positions)
{
DateTime maturityDate;
if (item.TradeType == "股票")
{
maturityDate = DateTime.Today.AddYears(10);
}
else if (item.TradeType == "场内期权")
{
ExchangeOptionDataProvider.TryGetMaturityDate(item.ExchangeOptionCode, out var date);
maturityDate = date;
}
else if (!UnderlyingDataProvider.TryGetMaturityDate(item.UnderlyingCode, out maturityDate))
{
maturityDate = DateTime.Today.AddMonths(1);
}
tpList.Add(new TradePosition
{
BookId = item.BookId,
TradeType = item.TradeType,
TradeType1 = TradeHelper.GetTradeType1(item.TradeType),
UnderlyingId = item.UnderlyingId,
UnderlyingCode = item.UnderlyingCode,
PositionType = item.PositionType == "long" ? PositionTypeFlag.Long : PositionTypeFlag.Short,
Position = item.Amount,
PositionCost = item.Cost,
MaturityDate = maturityDate,
InstrumentCode = item.ExchangeOptionCode,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
});
}
return tpList;
}
}
}