feat(swap): 添加日志记录并修复数值计算精度问题
- 添加了静态日志记录器用于跟踪方法执行 - 在SwapPositionCompose和SwapEodCompose方法中添加详细的执行参数日志 - 为合约处理流程添加开始和结束状态日志 - 在利息腿归档逻辑中添加处理状态和参数的日志输出 - 将decimal类型的字面量从整数改为带m后缀以确保精度 - 修复了RealizedPnl计算公式,加入利息费用的影响 - 调整了名义金额计算方式,在关闭处理中排除平仓金额 - 修正了利息收入计算中的绝对值问题 - 在数据库操作前后添加详细的实体状态日志
This commit is contained in:
@@ -18,6 +18,7 @@ namespace YLErp.Modules.SwapModule
|
||||
public class SwapEodPositionService : SwapTradeBaseService
|
||||
{
|
||||
private List<int> marginTypes = new List<int>() { (int)InterestModeEnum.追加预付金, (int)InterestModeEnum.初始预付金 };
|
||||
private static readonly IYcLogger Log = LogFactory.GetLogger(typeof(SwapEodPositionService).FullName);
|
||||
public SwapEodPositionService(OptUserInfo optUser) : base(optUser)
|
||||
{
|
||||
|
||||
@@ -61,6 +62,7 @@ namespace YLErp.Modules.SwapModule
|
||||
public void SwapPositionCompose(DateTime settleDate, DateTime preSettleDate, IEnumerable<int> ClientIds)
|
||||
{
|
||||
var dateStr = settleDate.ToString("yyyy-MM-dd");
|
||||
Log.Info("SwapPositionCompose:"+"settleDate:" + settleDate+ " preSettleDate:"+ preSettleDate+ " ClientIds:"+JsonHelper.Serialize(ClientIds));
|
||||
var tradePredicate = PredicateBuilder.Create<trade>(n => n.ValidState != ConsGlobal.InValid
|
||||
&& n.TradeType == "收益互换"
|
||||
&& n.TradeDate <= settleDate
|
||||
@@ -164,6 +166,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="ClientIds"></param>
|
||||
public void SwapEodCompose(DateTime settleDate, DateTime preSettleDate, IEnumerable<int> ClientIds)
|
||||
{
|
||||
Log.Info("SwapEodCompose:" + "settleDate:" + settleDate + " preSettleDate:" + preSettleDate + " ClientIds:" + JsonHelper.Serialize(ClientIds));
|
||||
var tradePredicate = PredicateBuilder.Create<trade>(n => n.ValidState != ConsGlobal.InValid
|
||||
&& n.TradeType == "收益互换"
|
||||
&& n.TradeDate <= settleDate
|
||||
@@ -177,7 +180,9 @@ namespace YLErp.Modules.SwapModule
|
||||
var tradeQueryList = DbContext.trade.Where(tradePredicate).ToList();
|
||||
foreach (var td in tradeQueryList)
|
||||
{
|
||||
Log.Info("【框架合约汇总】处理合约ID为:[" + td.id + "]的数据,收盘时间为:[" + settleDate + "]。开始");
|
||||
SaveEodSwap(td, settleDate, preSettleDate);
|
||||
Log.Info("【框架合约汇总】处理合约ID为:[" + td.id + "]的数据,收盘时间为:[" + settleDate + "]。结束");
|
||||
}
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
@@ -207,10 +212,12 @@ namespace YLErp.Modules.SwapModule
|
||||
decimal grossPrice,
|
||||
decimal orginPv)
|
||||
{
|
||||
Log.Info("===================处理利息腿归档====================");
|
||||
var hasClose = flowEvents.Any(x => x.EventType == (int)SwapEventTypeEnum.平仓);
|
||||
var hasSwap = flowEvents.Any(x => x.EventType == (int)SwapEventTypeEnum.互换);
|
||||
foreach (var interest in interestList)
|
||||
{
|
||||
Log.Info($"InterestMode is {interest.InterestMode},HappenDate is {interest.HappenDate},settleDate is {settleDate}");
|
||||
if (interest.InterestMode == (int)InterestModeEnum.追加预付金 && interest.HappenDate > settleDate)
|
||||
{
|
||||
continue;
|
||||
@@ -223,6 +230,7 @@ namespace YLErp.Modules.SwapModule
|
||||
var dealInterest = dealInterests.FirstOrDefault(n => n.PositionId == interest.id);//当日是否做过互换或平仓
|
||||
var swapEvents = flowEvents.Where(x => (x.EventType == (int)SwapEventTypeEnum.互换 || x.EventType == (int)SwapEventTypeEnum.平仓) && x.PositionId == interest.id).ToList();
|
||||
//如果当日有互换/当日有平仓 不再重新生成或更新
|
||||
Log.Info($"insterval is {insterval},hasSwap is {hasSwap},hasClose is {hasClose}");
|
||||
if (insterval != null && !hasSwap)
|
||||
{
|
||||
if (!hasClose)//当日无平仓
|
||||
@@ -276,9 +284,22 @@ namespace YLErp.Modules.SwapModule
|
||||
DateTime preSettleDate,
|
||||
List<swap_flow_event> flowEvents)
|
||||
{
|
||||
string settleDateStr = settleDate.ToString("yyyy-MM-dd");
|
||||
string preSettleDateStr = preSettleDate.ToString("yyyy-MM-dd");
|
||||
Log.Info($"================开始处理{settleDateStr}浮动腿归档==================");
|
||||
List<eod_swap_position> list = new List<eod_swap_position>();
|
||||
Log.Info($"浮动腿归档各项参数如下:\n " +
|
||||
$"settleDate为:{settleDateStr} \n" +
|
||||
$"preSettleDate为:{preSettleDateStr} \n " +
|
||||
$"td为:{td.id} \n " +
|
||||
$"posiList为:{JsonHelper.Serialize(posiList)} \n " +
|
||||
$"realPosiList为:{JsonHelper.Serialize(realPosiList)} \n " +
|
||||
$"eodPositions为:{JsonHelper.Serialize(eodPositions)} \n " +
|
||||
$"todyEodPositions为:{JsonHelper.Serialize(todyEodPositions)} \n " +
|
||||
$"flowEvents为:{JsonHelper.Serialize(flowEvents)} \n ");
|
||||
foreach (var posi in posiList)
|
||||
{
|
||||
Log.Info($"posi为:{JsonHelper.Serialize(posi, false)}");
|
||||
var eodPosition = eodPositions.Where(x => x.PositionId == posi.id).FirstOrDefault();//上一日日终持仓信息
|
||||
var tdEodPosition = todyEodPositions.FirstOrDefault(x => x.PositionId == posi.id);//当前结算日日终持仓信息
|
||||
var unwindEvents = flowEvents.Where(x => x.PositionId == posi.id).ToList();//当前日平仓信息
|
||||
@@ -296,8 +317,10 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
eodPosi = UpdateEodPosition(posi, eodPosition, tdEodPosition, td, settleDate, preSettleDate, unwindEvents);
|
||||
}
|
||||
Log.Info($"eodPosi为:{JsonHelper.Serialize(eodPosi, false)}");
|
||||
list.Add(eodPosi);
|
||||
}
|
||||
Log.Info($"================{settleDateStr}浮动腿归档结束==================");
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -570,6 +593,7 @@ namespace YLErp.Modules.SwapModule
|
||||
DateTime valueDate,
|
||||
List<swap_flow_event> flowEvents)
|
||||
{
|
||||
Log.Info($"eodPayPosition is {JsonHelper.Serialize(eodPayPosition, false)},newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
if (eodPayPosition == null)
|
||||
{
|
||||
eodPayPosition = new eod_swap_position();
|
||||
@@ -579,7 +603,7 @@ namespace YLErp.Modules.SwapModule
|
||||
eodPayPosition.PosiMatuirityDate = td.ExerciseDate.Value;
|
||||
}
|
||||
var tradeExtend = td.trade_extend.ExtendObj;
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1m : -1m;//收取为正,支付为负
|
||||
if (marginTypes.Contains(position.InterestMode))
|
||||
{
|
||||
ratio = -ratio;
|
||||
@@ -655,7 +679,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="lastEodSwap">上一日终框架合约估值</param>
|
||||
private List<swap_flow_event> SaveAutoEodInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, eod_swap lastEodSwap, decimal posiLongNotional, decimal posiShortNational, decimal grossPrice, decimal orginPv)
|
||||
{
|
||||
|
||||
Log.Info($"eodPayPosition is {JsonHelper.Serialize(eodPayPosition, false)},newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
var tradeExtend = td.trade_extend.ExtendObj;
|
||||
decimal oriPosiNotionalValue = posiLongNotional + posiShortNational;
|
||||
decimal posiNotionalValue = oriPosiNotionalValue;
|
||||
@@ -665,7 +689,7 @@ namespace YLErp.Modules.SwapModule
|
||||
posiNotionalValue = lastEodSwap.NotionalValue;
|
||||
}
|
||||
decimal closePercent = 1;
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1m : -1m;//收取为正,支付为负
|
||||
if (marginTypes.Contains(position.InterestMode))
|
||||
{
|
||||
ratio = -ratio;
|
||||
@@ -723,6 +747,7 @@ namespace YLErp.Modules.SwapModule
|
||||
// newEodPayPosition.TdCloseInterestFee = newEodPayPosition.TdInterestFee;
|
||||
//持仓内容-利息腿-损益统计(本方视角)
|
||||
newEodPayPosition.TdInterestIncome = TdInterestAmount;
|
||||
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee},TdCloseInterestFee is {newEodPayPosition.TdCloseInterestFee}");
|
||||
newEodPayPosition.InterestIncomeSum = 0;
|
||||
newEodPayPosition.InterestFeeSum = eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee;
|
||||
newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum;
|
||||
@@ -732,7 +757,7 @@ namespace YLErp.Modules.SwapModule
|
||||
//累计已实现
|
||||
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio;
|
||||
newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee;
|
||||
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate
|
||||
, seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell);
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
@@ -740,6 +765,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
DbContext.eod_swap_position.Add(newEodPayPosition);
|
||||
}
|
||||
Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
return interests;
|
||||
}
|
||||
|
||||
@@ -758,11 +784,11 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="unwintotal">平仓主信息</param>
|
||||
private List<swap_flow_event> SaveAutoEodWithCloseInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, decimal posiLongNotional, decimal posiShortNational, List<swap_flow_event> flowEvents, decimal closeNational, bool autoSwap, decimal grossPrice, decimal orginPv)
|
||||
{
|
||||
|
||||
Log.Info($"eodPayPosition is {JsonHelper.Serialize(eodPayPosition, false)},newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
var tradeExtend = td.trade_extend.ExtendObj;
|
||||
decimal oriPosiNotionalValue = posiLongNotional + posiShortNational + closeNational;
|
||||
decimal posiNotionalValue = oriPosiNotionalValue;
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负
|
||||
decimal posiNotionalValue = posiLongNotional + posiShortNational;
|
||||
decimal ratio = position.InterestDirection == (int)SwapDirectionEnum.收取 ? 1m : -1m;//收取为正,支付为负
|
||||
if (marginTypes.Contains(position.InterestMode))
|
||||
{
|
||||
ratio = -ratio;
|
||||
@@ -837,13 +863,17 @@ namespace YLErp.Modules.SwapModule
|
||||
newEodPayPosition.TdInterestFee = flowEvents.Sum(s => s.InterestFee);
|
||||
newEodPayPosition.TdCloseInterestFee = newEodPayPosition.TdInterestFee;
|
||||
newEodPayPosition.TdCloseInterest = flowEvents.Sum(s => s.InterestClosePnL);
|
||||
Log.Info($"InterestIncomeSum is {eodPayPosition.InterestIncomeSum},TdInterestIncome is {newEodPayPosition.TdInterestIncome}" +
|
||||
$",TdCloseInterest is {newEodPayPosition.TdCloseInterest}");
|
||||
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee}" +
|
||||
$",TdCloseInterestFee is {newEodPayPosition.TdCloseInterestFee}");
|
||||
if (closePercent == 1)
|
||||
{
|
||||
newEodPayPosition.InterestIncomeSum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
newEodPayPosition.InterestIncomeSum = eodPayPosition.InterestIncomeSum + TdInterestAmount - Math.Abs(newEodPayPosition.TdCloseInterest);
|
||||
newEodPayPosition.InterestIncomeSum = eodPayPosition.InterestIncomeSum + TdInterestAmount - newEodPayPosition.TdCloseInterest;
|
||||
}
|
||||
//持仓内容-利息腿-损益统计(本方视角)
|
||||
newEodPayPosition.TdInterestIncome = TdInterestAmount * (1 - closePercent);
|
||||
@@ -852,13 +882,18 @@ namespace YLErp.Modules.SwapModule
|
||||
//持仓价值
|
||||
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum * ratio + newEodPayPosition.PosiProfitSum;
|
||||
|
||||
Log.Info($"InterestIncomeSum is {eodPayPosition.InterestIncomeSum},TdInterestIncome is {newEodPayPosition.TdInterestIncome}" +
|
||||
$",TdCloseInterest is {newEodPayPosition.TdCloseInterest}");
|
||||
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee}" +
|
||||
$",TdCloseInterestFee is {newEodPayPosition.TdCloseInterestFee}");
|
||||
//累计已实现
|
||||
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio ;
|
||||
newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee;;
|
||||
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate
|
||||
, seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell);
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
Log.Info($"即将插入数据库的 newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
if (newEodPayPosition.id == 0)
|
||||
{
|
||||
DbContext.eod_swap_position.Add(newEodPayPosition);
|
||||
@@ -876,6 +911,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="td">互换交易主干</param>
|
||||
private void SaveEodInterestPositionCopy(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, DateTime valueDate, trade td, swap_position position, eod_swap lastEodSwap, bool needPrice, decimal posiLongNational, decimal posiShortNational, decimal grossPrice, decimal orginPv)
|
||||
{
|
||||
Log.Info($"eodPayPosition is {JsonHelper.Serialize(eodPayPosition, false)},newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
List<IntervalModel> intervals = position.SwapIntervalList;
|
||||
var tradeExtend = td.trade_extend.ExtendObj;
|
||||
if (eodPayPosition == null)
|
||||
@@ -931,7 +967,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
closePercent = 1;
|
||||
}
|
||||
decimal ratio = eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;//收取为正,支付为负
|
||||
decimal ratio = eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? 1m : -1m;//收取为正,支付为负
|
||||
if (marginTypes.Contains(position.InterestMode))
|
||||
{
|
||||
ratio = -ratio;
|
||||
@@ -963,6 +999,10 @@ namespace YLErp.Modules.SwapModule
|
||||
//持仓内容-利息腿-损益统计(本方视角)
|
||||
newEodPayPosition.TdInterestIncome = TdInterestAmount;
|
||||
newEodPayPosition.TdInterestFee = 0;
|
||||
Log.Info($"InterestIncomeSum is {eodPayPosition.InterestIncomeSum},TdInterestIncome is {newEodPayPosition.TdInterestIncome}" +
|
||||
$",TdCloseInterest is {newEodPayPosition.TdCloseInterest}");
|
||||
Log.Info($"InterestFeeSum is {eodPayPosition.InterestFeeSum},TdInterestFee is {newEodPayPosition.TdInterestFee}" +
|
||||
$",TdCloseInterestFee is {newEodPayPosition.TdCloseInterestFee}");
|
||||
newEodPayPosition.InterestIncomeSum = eodPayPosition.InterestIncomeSum + newEodPayPosition.TdInterestIncome - newEodPayPosition.TdCloseInterest;
|
||||
newEodPayPosition.InterestFeeSum = eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee;
|
||||
newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum;
|
||||
@@ -972,10 +1012,11 @@ namespace YLErp.Modules.SwapModule
|
||||
//累计已实现
|
||||
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio;
|
||||
newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest;
|
||||
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee;
|
||||
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate
|
||||
, seekPreday: true, currencyRateType: eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell);
|
||||
newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate);
|
||||
Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}");
|
||||
if (newEodPayPosition.id == 0)
|
||||
{
|
||||
DbContext.eod_swap_position.Add(newEodPayPosition);
|
||||
|
||||
Reference in New Issue
Block a user