194 lines
6.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|