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
{
///
/// trs交易端客户资金监控服务
///
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(swapMonitorConfgValue);
}
balanceMonitorForTrsRespone.WarningLine = monitorConfig.WarningLine * 0.01;
balanceMonitorForTrsRespone.UnwindLine = monitorConfig.UnwindLine * 0.01;
if (!request.ClientIds.Any())
{
var clientPredicate = PredicateBuilder.Create(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;
}
///
/// 获取客户历史资金记录
///
///
///
public List GetMonitorForTrsBuyDailyRespone(ClientBalanceMonitorFroTrsRequest request)
{
var valueDate = valuedateBLL.ValueDate;
var lastBalances = clientBalanceDailies(request.ClientIds, request.SearchDays, valueDate);
return MapToMonitorForTrsItems(lastBalances);
}
///
/// 获取客户历史资金结算
///
///
///
///
///
private List clientBalanceDailies(List clientIds, int searchDays, DateTime valueDate)
{
List clientSettleBalances = new List();
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 MapToMonitorForTrsItems(List clientSettleBalances)
{
List monitorForTrsItems = new List();
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;
}
///
/// 与昨日比较
///
///
///
///
private void MapToClientBalanceMonitor(ClientBalanceMonitorForTrsRespone balanceMonitorForTrsRespone, List balances, List 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);
}
}
}
}