Files
zszq-trs/YLErpDAL/Modules/SystemModule/SysToolModule/HeiXiang/HeixiangDailyPnlService.cs
T
2024-05-09 14:06:26 +08:00

194 lines
6.7 KiB
C#

using System.Text;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.DataProviderModule;
using YLErp.QdpModule;
namespace YLErp.Modules.SystemModule.SysToolModule.HeiXiang
{
/// <summary>
/// 黑箱dailypnl验证
/// </summary>
public class HeixiangDailyPnlService : YLBaseService
{
public HeixiangDailyPnlService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 获取黑箱dailypnl验证数据
/// </summary>
/// <returns></returns>
public IEnumerable<HeixiangDailyPnlResult> GetList(HeixiangDailyPnlRequest request)
{
if (string.IsNullOrWhiteSpace(request.HxMainTradeNumber))
{
throw new ServiceException("黑箱主交易编号不能为空");
}
var db = DbContextFactory.GetYLDbContext();
var preDate = QdpCalendarHelper.GetNonHolidayDefore(request.SettleDate.AddDays(-1));
var mainTrade = db.trade.Where(n => n.TradeNumber == request.HxMainTradeNumber)
.Select(n => new { n.id }).FirstOrDefault();
if (mainTrade == null)
{
throw new ServiceException("黑箱主交易 数据不存在");
}
IQueryable<EodTradePosition> posQry = db.eod_trade_position;
if (string.IsNullOrEmpty(request.VolType) || request.VolType == "对冲")
{
posQry = db.eod_trade_position_hedgevol;
}
var query = from t in posQry
join td in db.trade on t.TradeId equals td.id
join pt in db.eod_trade_position.Where(n => n.ValueDate == preDate)
on t.TradeId equals pt.TradeId into pt_s
from pt in pt_s.DefaultIfEmpty()
where t.ValueDate == request.SettleDate && t.ParentTradeId == mainTrade.id
select new
{
td.TradeNumber,
td.OriginalNotional,
td.TradePrice,
td.BuySell,
td.OriginalPrincipalSum,
t.TradeId,
t.Amount,
t.Pv,
t.LastPv,
t.ClosedPnL,
t.DailyPnL,
pre = pt == null ? null : new
{
pt.Pv,
pt.Amount
}
};
var datas = query.ToArray();
var subTradeIds = datas.Select(n => n.TradeId).ToArray();
var tcProvider = new TradeCashDataProvider();
tcProvider.Initialize(subTradeIds);
var list = new List<HeixiangDailyPnlResult>(datas.Length + 1);
var sb = new StringBuilder();
double sumDailyPnl = 0d, sumDailyPnlCalc = 0d;
foreach (var item in datas)
{
var result = new HeixiangDailyPnlResult
{
TradeNumber = item.TradeNumber
};
if (item.Amount < 1e-4)
{
result.TradeStatus = "完全了结";
}
else
{
var diff = Math.Abs((item.OriginalNotional ?? 0) - item.Amount);
if (diff < 1e-4)
{
result.TradeStatus = "全部成交";
}
else
{
result.TradeStatus = "部分了结";
}
}
double lastPv;
if (item.pre != null)
{
result.PrePositionPv = item.pre.Pv.OtcFormatFlex(2, 4);
result.PrePositionNotional = item.pre.Amount.OtcFormatFlex(2, 4);
lastPv = item.LastPv;
}
else
{
if (PS.Config.ErpElement.IsPVIncludePrincipal)
{
lastPv = item.TradePrice ?? 0;
}
else
{
lastPv = (item.TradePrice ?? 0) - (item.OriginalPrincipalSum ?? 0);
}
if (item.BuySell == "卖出")
{
lastPv = -lastPv;
}
}
result.PositionPv = item.Pv.OtcFormatFlex(2, 4);
result.PositionNotional = item.Amount.OtcFormatFlex(2, 4);
result.PositionDailyPnl = item.DailyPnL.OtcFormatFlex(2, 4);
sb.Clear();
sb.AppendFormat("pv({0}) - lastpv({1}) + 了结盈亏(", item.Pv.OtcFormatFlex(2, 4), lastPv.OtcFormatFlex(2, 4));
var dailyCalc = item.Pv - lastPv;
foreach (var c in tcProvider.GetTradeCashes(item.TradeId))
{
if (c.Action == ClientCashInCashOut.系统操作_期权费)
{
continue;
}
var unWindProfit = c.Amount;
if (!PS.Config.ErpElement.IsPVIncludePrincipal)
{
if (c.Action == ClientCashInCashOut.系统操作_行权费 || c.Action == ClientCashInCashOut.系统操作_平仓费 || c.IsLastAction)
{
unWindProfit -= (c.UnwindPercentRate ?? 0) * item.OriginalPrincipalSum.Value * TradeCalcHelper.GetSign(item.BuySell);
}
}
sb.Append(unWindProfit.OtcFormatFlex(2, 4)).Append(" + ");
dailyCalc += unWindProfit;
}
if (sb[sb.Length - 2] == '+')
{
sb[sb.Length - 2] = ')';
}
else
{
sb.Append(") ");
}
sb.Append(" = ").Append(dailyCalc.OtcFormatFlex(2, 4));
result.DailyPnlCalc = sb.ToString();
sumDailyPnl += item.DailyPnL;
sumDailyPnlCalc += dailyCalc;
list.Add(result);
}
var sumData = new HeixiangDailyPnlResult
{
TradeNumber = "合计:",
PositionDailyPnl = sumDailyPnl.OtcFormatFlex(2, 4),
DailyPnlCalc = sumDailyPnlCalc.OtcFormatFlex(2, 4)
};
list.Add(sumData);
return list;
}
}
}