317 lines
17 KiB
C#
317 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using YLErp.BLL;
|
|
using YLErp.BLL.Eod;
|
|
using YLErp.BLL.EodSettlement;
|
|
using YLErp.DBModels;
|
|
using YLErp.Model;
|
|
using YLErp.Models;
|
|
using YLErp.Modules.EodModule.QueryModule;
|
|
using YLErp.QdpModule;
|
|
|
|
namespace YLErp.Modules.SwapModule
|
|
{
|
|
/// <summary>
|
|
/// trs交易端客户资金监控服务
|
|
/// </summary>
|
|
public class SwapMonitorService : YLBaseService
|
|
{
|
|
public SwapMonitorService(OptUserInfo optUser) : base(optUser)
|
|
{
|
|
}
|
|
|
|
public ClientBalanceMonitorForTrsRespone GetMonitorForTrsRespone(ClientBalanceMonitorFroTrsRequest request)
|
|
{
|
|
var valueDate = valuedateBLL.ValueDate;
|
|
ClientBalanceMonitorForTrsRespone balanceMonitorForTrsRespone = new ClientBalanceMonitorForTrsRespone();
|
|
var swapMonitorConfgValue = AppManager.GetSwapMonitorValue();
|
|
SwapMonitorConfig monitorConfig = new SwapMonitorConfig();
|
|
if (!string.IsNullOrEmpty(swapMonitorConfgValue))
|
|
{
|
|
monitorConfig = JsonHelper.Deserialize<SwapMonitorConfig>(swapMonitorConfgValue);
|
|
}
|
|
balanceMonitorForTrsRespone.WarningLine = monitorConfig.WarningLine * 0.01;
|
|
balanceMonitorForTrsRespone.UnwindLine = monitorConfig.UnwindLine * 0.01;
|
|
if (!request.ClientIds.Any())
|
|
{
|
|
var clientPredicate = PredicateBuilder.Create<Client>(x => x.ProcessStatus == "已开户");
|
|
var clientquery = DataCacheProvider.GetClientDataSource().AsQueryable(clientPredicate);
|
|
request.ClientIds = clientquery.Select(s => s.id).ToList();
|
|
}
|
|
var balances = ClientBalanceUtility.GetClientBanlances(request.ClientIds, DateTime.MinValue, valueDate).ToList();
|
|
balanceMonitorForTrsRespone.BalanceMonitorForTrsItems = MapToMonitorForTrsItems(balances);
|
|
var lastBalances = clientBalanceDailies(request.ClientIds, 1, valueDate);
|
|
MapToClientBalanceMonitor(balanceMonitorForTrsRespone, balances, lastBalances);
|
|
return balanceMonitorForTrsRespone;
|
|
}
|
|
/// <summary>
|
|
/// 获取客户历史资金记录
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
public List<ClientBalanceMonitorForTrsItem> GetMonitorForTrsBuyDailyRespone(ClientBalanceMonitorFroTrsRequest request)
|
|
{
|
|
var valueDate = valuedateBLL.ValueDate;
|
|
var lastBalances = clientBalanceDailies(request.ClientIds, request.SearchDays, valueDate);
|
|
return MapToMonitorForTrsItems(lastBalances);
|
|
}
|
|
/// <summary>
|
|
/// 获取客户历史资金结算
|
|
/// </summary>
|
|
/// <param name="clientIds"></param>
|
|
/// <param name="searchDays"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <returns></returns>
|
|
private List<ClientSettleBalance> clientBalanceDailies(List<int> clientIds, int searchDays, DateTime valueDate)
|
|
{
|
|
List<ClientSettleBalance> clientSettleBalances = new List<ClientSettleBalance>();
|
|
if (!clientIds.Any()|| searchDays == 0)
|
|
{
|
|
return clientSettleBalances;
|
|
}
|
|
var lastBalanceDate = EodOperationBase.GetLastSettlementDate(valueDate);
|
|
if (lastBalanceDate == valueDate)
|
|
{
|
|
lastBalanceDate = QdpCalendarHelper.GetNonHolidayDefore(valueDate.AddDays(-1));
|
|
}
|
|
var days = QdpCalendarHelper.GetWorkingDatesBeforeDate(lastBalanceDate, searchDays);
|
|
var firstDay = days.OrderBy(s => s).First();
|
|
var endQuery = from t in DbContext.ClientBalanceDaily
|
|
join cs in DbContext.client_span.Where(eod_cs => eod_cs.SpanType == ClientSpan.SpanType_Eod) on new { t.ClientId, ValueDate = t.BalanceDate } equals new { cs.ClientId, cs.ValueDate }
|
|
into eodClientSpan
|
|
from cs in eodClientSpan.DefaultIfEmpty()
|
|
|
|
where t.BalanceDate >= firstDay
|
|
&& clientIds.Contains(t.ClientId)
|
|
select new
|
|
{
|
|
ClientId = t.ClientId,
|
|
ValueDate = t.BalanceDate,
|
|
FreezePremium = t.FrozenPremium ?? 0.0,
|
|
ReceivablesPremium = 0.0,
|
|
AmountFund = t.ToDayRemainFund ?? 0.0,
|
|
GuaranteesTotalAmount = t.TodayRemianFundProduct ?? 0.0,
|
|
//仅用于广期资本可用资金计算
|
|
//可用资金1 = 净入金 + 已实现盈亏 + 浮动盈亏 - 次日最大亏损;
|
|
//可用资金2 = 净入金 + 已实现盈亏 - 持仓期初净支付权利金;
|
|
//可用资金 = min(可用资金1,可用资金2);
|
|
AvailableAmount1 = (t.NetFundSum ?? 0) + (t.WinLossSum ?? 0) + (t.PositionPnl ?? 0) + (cs.WorstCastClientPayable ?? 0),
|
|
AvailableAmount2 = (t.NetFundSum ?? 0) + (t.WinLossSum ?? 0) - (t.OptionPremiumSum ?? 0) - (t.OptionPremiumSwapSum ?? 0),
|
|
AvailableAmount = (t.MarginBalance ?? 0.0) + (t.PayableMargin ?? 0.0) - (t.FrozenMarginMoney ?? 0.0) - (t.TodayRemianFundProduct ?? 0.0),//t.FrozenMarginMoney是通道业务显示所用到的
|
|
TotalCredit = t.Credit ?? 0.0,
|
|
PayableMargin = t.PayableMargin ?? 0.0,
|
|
DeltaMargin = t.DeltaMargin ?? 0d,
|
|
SwapPayableMargin = t.SwapPayableMargin ?? 0.0,
|
|
SwapUnPayableMargin = t.SwapUnPayableMargin ?? 0.0,
|
|
TwoSideMargin = t.TwoSideMargin ?? 0.0,
|
|
OtherSideMargin = t.OtherSideMargin ?? 0.0,
|
|
MySideMargin = t.MySideMargin ?? 0.0,
|
|
IsPayableMarginManual = t.IsPayableMarginManual,
|
|
IsPayableMarginLock = cs == null ? false : cs.ModifiedFlag,
|
|
FrozenMarginMoney = t.FrozenMarginMoney ?? 0.0,
|
|
FrozenOutFund = t.FrozenOutFund ?? 0.0,
|
|
MarginBalance = t.MarginBalance ?? 0.0,
|
|
Coupon = t.Coupon ?? 0.0,
|
|
SwapBalance = t.SwapBalance ?? 0.0,
|
|
Margin = t.Margin ?? 0.0,
|
|
//IsTradeCredit = t.IsTradeCredit ?? c.IsTradeCredit == 1,
|
|
TodayNewMargin = 0,
|
|
PositionPv = t.Pv ?? 0,
|
|
RoundedPositionPv = t.RoundedPv ?? 0,
|
|
SellPv = t.SellPv ?? 0,
|
|
PrepaymentAmount = t.PrepaymentAmount ?? 0.0,
|
|
DaliyPnl = t.DailyPnl ?? 0,
|
|
PositionPnl = t.PositionPnl ?? 0,
|
|
RoundedPositionPnl = t.RoundedPositionPnl ?? 0,
|
|
ClientSellPositionPnl = t.ClientSellPositionPnl ?? 0,
|
|
PositionPremiumNetCash = t.PositionPremiumNetCash ?? 0,
|
|
LastDayPositionPremiumNetCash = t.LastDayPositionPremiumNetCash ?? 0,
|
|
SellTradePrice = t.SellTradePrice,
|
|
AvailableStockEqvNotional = t.AvailableStockEqvNotional ?? 0,
|
|
FrozenBalance = t.FrozenBalance ?? 0,
|
|
TdWinLoss = t.WinLoss,
|
|
MarginJson = cs.PVJsons
|
|
};
|
|
var endDatas = endQuery.ToArray();
|
|
|
|
foreach (var data in endDatas)
|
|
{
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(data.ClientId);
|
|
ClientSettleBalance balance = new ClientSettleBalance();
|
|
balance.ClientId = data.ClientId;
|
|
balance.ValueDate = data.ValueDate;
|
|
balance.FrozenBalance = data.FrozenBalance;
|
|
balance.FreezePremium = data.FreezePremium;
|
|
balance.ReceivablesPremium = data.ReceivablesPremium;
|
|
balance.AmountFund = data.AmountFund;
|
|
balance.AvailableAmount = data.AvailableAmount;
|
|
balance.TotalCredit = data.TotalCredit;
|
|
balance.PayableMargin = data.PayableMargin;
|
|
balance.GuaranteesTotalAmount = data.GuaranteesTotalAmount;
|
|
balance.AvailableAmount = balance.AmountFund + balance.TotalCredit + balance.PayableMargin + balance.GuaranteesTotalAmount;
|
|
balance.DeltaMargin = data.DeltaMargin;
|
|
balance.SwapPayableMargin = data.SwapPayableMargin;
|
|
balance.SwapUnMargin = data.SwapUnPayableMargin;
|
|
balance.TwoSideMargin = data.TwoSideMargin;
|
|
balance.OtherSideMargin = data.OtherSideMargin;
|
|
balance.MySideMargin = data.MySideMargin;
|
|
balance.IsPayableMarginManual = data.IsPayableMarginManual;
|
|
balance.IsPayableMarginLock = data.IsPayableMarginLock;
|
|
balance.FrozenMarginMoney = data.FrozenMarginMoney;
|
|
balance.FrozenOutFund = data.FrozenOutFund;
|
|
balance.MarginBalance = data.MarginBalance;
|
|
balance.Margin = data.Margin;
|
|
balance.UpdateDate = DateTime.Now;
|
|
balance.IsTradeCredit = client?.IsTradeCredit == 1;
|
|
balance.TodayNewMargin = data.TodayNewMargin;
|
|
|
|
balance.PositionPv = data.PositionPv;
|
|
balance.RoundedPositionPv = data.RoundedPositionPv;
|
|
balance.SellPv = data.SellPv;
|
|
balance.PrepaymentAmount = data.PrepaymentAmount;
|
|
balance.DaliyPnl = data.DaliyPnl;
|
|
balance.PositionPnl = data.PositionPnl;
|
|
balance.RoundedPositionPnl = data.RoundedPositionPnl;
|
|
balance.ClientSellPositionPnl = data.ClientSellPositionPnl;
|
|
balance.PositionPremiumNetCash = data.PositionPremiumNetCash;
|
|
balance.SellTradePrice = data.SellTradePrice ?? 0;
|
|
balance.LastDayPositionPremiumNetCash = data.LastDayPositionPremiumNetCash;
|
|
balance.MarginOptionType = client?.MarginOptionType ?? 0;
|
|
balance.IsLatestDate = true;
|
|
balance.IsEodData = true;
|
|
balance.TdWinLoss = data.TdWinLoss ?? 0;
|
|
balance.AvailableStockEqvNotional = data.AvailableStockEqvNotional;
|
|
balance.MarginJson = data.MarginJson;
|
|
balance.ClientType = client.SwapTradeType ?? 0;
|
|
balance.ClientName = client.Name;
|
|
balance.ClientNumber = client.Number;
|
|
clientSettleBalances.Add(balance);
|
|
}
|
|
return clientSettleBalances;
|
|
}
|
|
|
|
private List<ClientBalanceMonitorForTrsItem> MapToMonitorForTrsItems(List<ClientSettleBalance> clientSettleBalances)
|
|
{
|
|
List<ClientBalanceMonitorForTrsItem> monitorForTrsItems = new List<ClientBalanceMonitorForTrsItem>();
|
|
clientSettleBalances.ForEach(item =>
|
|
{
|
|
ClientBalanceMonitorForTrsItem clientBalanceMonitorForTrsItem = new ClientBalanceMonitorForTrsItem()
|
|
{
|
|
ClientId=item.ClientId,
|
|
ClientName = item.ClientName,
|
|
ClientNumber = item.ClientNumber,
|
|
ClientTypeStr = item.ClientTypeStr,
|
|
AmountFund = item.AvailableAmount,
|
|
MaintenanceLine = item.MaintenanceLine,
|
|
MarginByPayableMarginTotal = item.MarginByPayableMargin,
|
|
ValueDate = item.ValueDate
|
|
};
|
|
monitorForTrsItems.Add(clientBalanceMonitorForTrsItem);
|
|
});
|
|
return monitorForTrsItems;
|
|
}
|
|
/// <summary>
|
|
/// 与昨日比较
|
|
/// </summary>
|
|
/// <param name="balanceMonitorForTrsRespone"></param>
|
|
/// <param name="balances"></param>
|
|
/// <param name="lastBalances"></param>
|
|
private void MapToClientBalanceMonitor(ClientBalanceMonitorForTrsRespone balanceMonitorForTrsRespone, List<ClientSettleBalance> balances, List<ClientSettleBalance> lastBalances)
|
|
{
|
|
var lastDurationNotionalPrincipal = lastBalances.Sum(s => Math.Abs(s.PositionNotionalPrincipal));
|
|
var lastDurationClient = lastBalances.Count(s => s.PositionPv != 0);
|
|
var lastUnwindlineClient = lastBalances.Count(s => s.MaintenanceLine <= balanceMonitorForTrsRespone.UnwindLine);
|
|
var lastFundShortageClient = lastBalances.Count(s => s.AvailableAmount < 0);
|
|
var lastWarninglineClient = lastBalances.Count(s => s.MaintenanceLine <= balanceMonitorForTrsRespone.WarningLine&&s.MaintenanceLine> balanceMonitorForTrsRespone.UnwindLine);
|
|
balanceMonitorForTrsRespone.DurationNotionalPrincipal = balances.Sum(s => Math.Abs(s.PositionNotionalPrincipal));
|
|
var DurationNotionalPrincipalCompareLastDay= Convert.ToDouble(balanceMonitorForTrsRespone.DurationNotionalPrincipal - lastDurationNotionalPrincipal);
|
|
if (lastDurationNotionalPrincipal==0)
|
|
{
|
|
if (DurationNotionalPrincipalCompareLastDay == 0)
|
|
{
|
|
balanceMonitorForTrsRespone.DurationNotionalPrincipalCompareLastDay = 0;
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.DurationNotionalPrincipalCompareLastDay = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.DurationNotionalPrincipalCompareLastDay = DurationNotionalPrincipalCompareLastDay / Convert.ToDouble(lastDurationNotionalPrincipal);
|
|
}
|
|
balanceMonitorForTrsRespone.DurationClient = balances.Count(s => s.PositionPv != 0);
|
|
var DurationClientCompareLastDay = Convert.ToDouble(balanceMonitorForTrsRespone.DurationClient - lastDurationClient);
|
|
if (lastDurationClient == 0)
|
|
{
|
|
if (DurationClientCompareLastDay == 0)
|
|
{
|
|
balanceMonitorForTrsRespone.DurationClientCompareLastDay = 0;
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.DurationClientCompareLastDay = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.DurationClientCompareLastDay = DurationClientCompareLastDay / Convert.ToDouble(lastDurationClient);
|
|
}
|
|
balanceMonitorForTrsRespone.UnwindlineClient = balances.Count(s => s.MaintenanceLine <= balanceMonitorForTrsRespone.UnwindLine);
|
|
var UnwindlineClientCompareLastDay = Convert.ToDouble(balanceMonitorForTrsRespone.UnwindlineClient - lastUnwindlineClient);
|
|
if (lastUnwindlineClient == 0)
|
|
{
|
|
if (UnwindlineClientCompareLastDay == 0)
|
|
{
|
|
balanceMonitorForTrsRespone.UnwindlineClientCompareLastDay = 0;
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.UnwindlineClientCompareLastDay = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.UnwindlineClientCompareLastDay = UnwindlineClientCompareLastDay / Convert.ToDouble(lastUnwindlineClient);
|
|
}
|
|
balanceMonitorForTrsRespone.FundShortageClient = balances.Count(s => s.AvailableAmount < 0);
|
|
var FundShortageClientCompareLastDay = Convert.ToDouble(balanceMonitorForTrsRespone.FundShortageClient - lastFundShortageClient);
|
|
if (lastFundShortageClient == 0)
|
|
{
|
|
if (FundShortageClientCompareLastDay == 0)
|
|
{
|
|
balanceMonitorForTrsRespone.FundShortageClientCompareLastDay = 0;
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.FundShortageClientCompareLastDay = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.FundShortageClientCompareLastDay = FundShortageClientCompareLastDay / Convert.ToDouble(lastFundShortageClient);
|
|
}
|
|
balanceMonitorForTrsRespone.WarninglineClient = balances.Count(s => s.MaintenanceLine <= balanceMonitorForTrsRespone.WarningLine && s.MaintenanceLine > balanceMonitorForTrsRespone.UnwindLine);
|
|
var WarninglineClientCompareLastDay = Convert.ToDouble(balanceMonitorForTrsRespone.WarninglineClient - lastWarninglineClient);
|
|
if (lastWarninglineClient == 0)
|
|
{
|
|
if (WarninglineClientCompareLastDay == 0)
|
|
{
|
|
balanceMonitorForTrsRespone.WarninglineClientCompareLastDay = 0;
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.WarninglineClientCompareLastDay = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
balanceMonitorForTrsRespone.WarninglineClientCompareLastDay = WarninglineClientCompareLastDay / Convert.ToDouble(lastWarninglineClient);
|
|
}
|
|
}
|
|
}
|
|
}
|