Files
zszq-trs/YLErpDAL/Modules/EodModule/SettlementModule/EodClientBalanceCalc.cs
T

1395 lines
86 KiB
C#

using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.Ocsp;
using YieldChain.Helpers;
using YLErp.BLL;
using YLErp.BLL.MarginCalculation;
using YLErp.Configuration;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.EodModule.QueryModule;
using YLErp.Modules.TradeRiskCalcModule;
namespace YLErp.Modules.EodModule.SettlementModule
{
/// <summary>
/// 客户结算
/// </summary>
public class EodClientBalanceCalc : EodSettleServiceBaseV2
{
public EodClientBalanceCalc(EodSettlementContextV2 context) : base(context)
{
}
/// <summary>
/// 客户结算
/// </summary>
public bool ClientBalanceCalc()
{
var balanceDate = _context.SettleDate;
var reqClientIds = _context.Request.ClientIds;
var clientDb = DbContextFactory.GetClientDbContext(OptUser);
var currencyCodes = _context.CurrencyCodes;
var currencyProvider = _context.EodCurrencyProvider;
//预付金可取上浮比率
var marginRatio = _context.SystemValue.MarginRatio ?? 0.15;
var marginMaxRatio = marginRatio + 0.02;
var preBalanceDate = _context.PreSettleDate;
var preClientbalancedailys = DbContext.ClientBalanceDaily.Where(t => t.BalanceDate == preBalanceDate).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
preClientbalancedailys = preClientbalancedailys.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
}
//获取所有客户信息
var clients = clientDb.client.Where(t => t.ProcessStatus != "未提交").ToList();
if (reqClientIds != null && reqClientIds.Any())
{
clients = clients.Where(t => reqClientIds.Contains(t.id)).ToList();
}
var allClientIds = clients.Select(t => t.id).ToList();
#region 客户结算相关数据初始化 eod_trade_position client_span eod_trade eodPrice
//获取所有客户授信
var creditList = DbContext.credit.Where(t => t.ProcessStatus == "已审批" && (!t.CreditDeadLine.HasValue || t.CreditDeadLine >= balanceDate) && (!t.CreditStartDate.HasValue || t.CreditStartDate <= balanceDate)).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
creditList = creditList.Where(t => reqClientIds.Contains(t.ClientId ?? 0)).ToList();
}
//获取所有资信等级
var creditRatingList = clientDb.credit_rating.Where(t => t.ValidState != "InValid").ToList();
//出入金记录 获取上个结算日到当前结算日之间的所有已结算和已确认的出入金(包含周末的出入金)
var newValuedate = balanceDate.AddDays(1);
var lastBalanceDateAddOne = preBalanceDate.AddDays(1);
var entryexits = from cash in DbContext.ClientCashInCashOut.Where(t => t.ValidState != "InValid" && (t.HappenDate >= lastBalanceDateAddOne && t.HappenDate < newValuedate && (t.State == ClientCashInCashOut.已结算 || t.State == ClientCashInCashOut.已确认)))
join trade in DbContext.trade on cash.TradeId equals trade.id into trade
from td in trade.DefaultIfEmpty()
where td.TradeType != "收益互换" && td.ValidState != ConsGlobal.InValid
select cash;
if (reqClientIds != null && reqClientIds.Any())
{
entryexits = entryexits.Where(t => reqClientIds.Contains(t.ClientId ?? 0));
}
var entryexits_swapAll = from cash in DbContext.ClientCashInCashOut.Where(t => t.ValidState != "InValid" && (t.HappenDate >= lastBalanceDateAddOne && (t.State == ClientCashInCashOut.已结算 || t.State == ClientCashInCashOut.已确认)))
join trade in DbContext.trade.Where(x => x.TradeType == "收益互换") on cash.TradeId equals trade.id
select cash;
if (reqClientIds != null && reqClientIds.Any())
{
entryexits_swapAll = entryexits_swapAll.Where(t => reqClientIds.Contains(t.ClientId ?? 0));
}
var entryexits_swap = entryexits_swapAll.Where(t => t.HappenDate < newValuedate);
var entryexits_swapFuture = entryexits_swapAll.Where(t => t.HappenDate >= newValuedate);
//获取客户所有现存(抵押状态)抵押品信息
var clientProductList = (from product in DbContext.clientcashincashout_product
join variety in DbContext.variety on product.VarietyId equals variety.id into varietyTemp
from variety in varietyTemp.DefaultIfEmpty()
join um in DbContext.underlying_manager on product.UnderlyingId equals um.id into umTemp
from um in umTemp.DefaultIfEmpty()
where (product.Status == Clientcashincashout_productStatusEnum.抵押.ToString() && product.OptStatus == ClientCashInCashOut.已确认
|| product.Status == Clientcashincashout_productStatusEnum.赎回.ToString() && product.OptStatus != ClientCashInCashOut.已确认
|| product.Status == Clientcashincashout_productStatusEnum.赎回.ToString() && product.OptStatus == ClientCashInCashOut.已确认 && product.BackDate >= newValuedate)
&& allClientIds.Contains(product.ClientId) && product.HappenDate < newValuedate
select new { product, variety, um }).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
clientProductList = clientProductList.Where(t => reqClientIds.Contains(t.product.ClientId)).ToList();
}
//获取所有用户当日Eod_Risk
var eodRiskList = DbContext.eod_trade_risk.Where(t => t.ValueDate == balanceDate).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
eodRiskList = eodRiskList.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
}
//获取所有用户当日Eod_pnl
IEnumerable<EodTradePosition> eodpnlList;
if (PS.Config.Company == CompanyEnum.国投)
{
eodpnlList = DbContext.eod_trade_position_openvol.Where(t => t.ValueDate == balanceDate).ToList();
}
else if (PS.Config.Company == CompanyEnum.格林大华)
{
eodpnlList = DbContext.eod_trade_position.Where(t => t.ValueDate == balanceDate).ToList();
}
else if (PS.Config.Is山西固收)
{
eodpnlList = DbContext.eod_trade_position.Where(t => t.ValueDate == balanceDate && t.TradeType != "收益互换").ToList();
}
else
{
eodpnlList = DbContext.eod_trade_position.Where(t => t.ValueDate == balanceDate).ToList();
}
if (reqClientIds != null && reqClientIds.Any())
{
eodpnlList = eodpnlList.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
}
//获取客户导入的所有持仓信息 -- 收益互换(国君)
var EodPositionSwapMannual = DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == balanceDate).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
EodPositionSwapMannual = EodPositionSwapMannual.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
}
// 互换合约估值信息
var eodSwapQuery = from eod in DbContext.eod_swap.Where(x => x.ValueDate <= balanceDate && x.ValueDate >= preBalanceDate)
join t in DbContext.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid && ConsTrade.TradeStatusAfterConfirmed.Contains(x.TradeStatus)) on eod.SwapTradeId equals t.id
select eod;
var positionList = DbContext.trade.Where(t => (ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)||t.UnWindDate> balanceDate) && t.ValidState != "InValid"&&t.TradeType=="收益互换");
var marignQuery = from t in positionList
join s in DbContext.eod_swap_position on t.id equals s.SwapTradeId
where ConsTrade.InterestMarginModels.Contains(s.InterestMode) && !s.Invalid && s.HappenDate <= balanceDate &&s.ValueDate==balanceDate
select new
{
ClientId = t.ClientId,
StructureType = t.StructureType,
marin = s.InterestPrincipalFix * (s.InterestDirection == 1 ? -1m : 1m)
};
var eodSwaps = eodSwapQuery.ToList();
if (reqClientIds != null && reqClientIds.Any())
{
eodSwaps = eodSwaps.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
marignQuery = marignQuery.Where(t => reqClientIds.Contains(t.ClientId));
}
var swapIds = eodSwaps.Select(s => s.SwapTradeId);
var todaySwapTrades = DbContext.trade.Where(t => swapIds.Contains(t.id)).ToList();
// var swapMargins = DbContext.trade_initial_margin.Where(t => swapIds.Contains(t.TradeId)).ToList();
var underlyDataSource = DataCacheProvider.GetUnderlyingDataSource();
var varietyDataSource = DataCacheProvider.GetVarietyDataSource();
//客户预付金
var clientSpanList = DbContext.client_span.Where(t => t.ValueDate == balanceDate).ToList();
if (reqClientIds != null && reqClientIds.Any())
{
clientSpanList = clientSpanList.Where(t => reqClientIds.Contains(t.ClientId)).ToList();
}
//clientbalance
var newClientBalanceDaily = new List<ClientBalanceDaily>();
//获取客户所有交易信息(所及为客户所有确认交易,以及当日平仓或者当日执行的交易)
var trades = _context.OtcTrades.ToList();
//如果前一天是假日,要显示包含假日的交易
var preday = balanceDate.AddDays(-1);
//获取上一个交易日的下一天(例如收盘日是周一,上一个交易日就是周五,他的下一天就是周六,获取的是周六)
var nonHolidayAddOne = valuedateBLL.GetNonHolidayDefore(preday).AddDays(1);
var finishedTradeCash = DbContext.trade_cash
.Where(tc => (tc.ValueDate >= nonHolidayAddOne && tc.ValueDate <= balanceDate && tc.HappenedDate == null || tc.HappenedDate >= nonHolidayAddOne && tc.HappenedDate <= balanceDate)
&& tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted
&& (tc.Action == ClientCashInCashOut.系统操作_平仓费 || tc.Action == ClientCashInCashOut.系统操作_行权费 || tc.Action == ClientCashInCashOut.系统操作_互换 || tc.Action == ClientCashInCashOut.系统操作_票息 || tc.Action == ClientCashInCashOut.人工操作_其他));
var finishedTradeNotionalPercentDic = finishedTradeCash
.AsEnumerable()
.GroupBy(tc => tc.TradeId)
.ToDictionary(g => g.Key,
g => g.Sum(tc => tc.UnwindPercentRate ?? 0));
var keys = finishedTradeNotionalPercentDic.Select(d => d.Key).ToArray();
var dayeods = _context.GetEodPriceProvider();
//期权交易行权平仓产生的资金流水
//var tradeCashList = db.trade_cash.Where(t => allTradeIds.Contains(t.TradeId)).ToList();
//获取冻结资金信息
var clientFrozenFunds = new ClientFrozenFundsService(this).GetDatas(balanceDate, allClientIds);
#endregion
#region 循环客户信息计算客户资金信息
foreach (var client in clients)
{
_context.CancellationToken.ThrowIfCancellationRequested();
#region 变量初始化
List<ClientCashInCashOut> clientEntryexits;
List<ClientCashInCashOut> clientEntryexits_swap;
FundObject fundObject = new FundObject();
foreach (var currencyCode in currencyCodes)
{
fundObject.InFund.Add(currencyCode, 0);
fundObject.OutFund.Add(currencyCode, 0);
fundObject.NetFund.Add(currencyCode, 0);
fundObject.InFundOther.Add(currencyCode, 0);
fundObject.OutFundOther.Add(currencyCode, 0);
fundObject.OtherFund.Add(currencyCode, 0);
fundObject.TodayRemainFund.Add(currencyCode, 0);
fundObject.LastDayRemainFund.Add(currencyCode, 0);
}
//入金
var inFund = 0.0;
//出金
var outFund = 0.0;
//其他收入
var inFundOther = 0.0;
//其他支出
var outFundOther = 0.0;
//当日浮动盈亏
var CurrPnl = 0.0;
//当日浮动盈亏
var PositionPnl = 0.0;
var RoundedPositionPnl = 0.0;
//期权空头浮动盈利=∑max(期权空头持仓*(期权合约成本价-期权合约现价), 0) 从客户角度看的
var ClientSellPositionPnl = 0.0;
//当日总盈亏
var TotalPnl = 0.0;
//当日盈亏
double DailyPnl = 0;
//今日可用资金
var CurrAvailAmount = 0.0;
//今日可用资金
var LastDayAvailAmount = 0.0;
//当日资金变动
var CurrChangeAmount = 0.0;
//资信等级
//credit_rating creditRating = null;
//授信额度
var lineOfCredit = 0.0;
//用户持仓价值
double? clientPv;
double? roundedClientPv;
//用户卖出部分持仓价值
double? clientSellPv;
//客户持仓交易预付金总和,客户买入为正,客户卖出为负
double? PrepaymentAmount;
//期权费收支
var OptionPremium = 0.0;
//期权费收支
var OptionPremiumSwap = 0.0;
//结算收支(平仓行权)
var SettlementBalance = 0.0;
//平仓收支
var UnwindBalance = 0.0;
//行权收支
var ExerciseBalance = 0.0;
//实现盈亏
var WinLoss = 0.0;
//持仓期权费净额(客户角度卖出为负,买入为正)
var PositionPremiumNetCash = 0.0;
//权利金冻结(当日该客户所有持仓的卖出期权权利金)
var SellTradePrice = 0.0;
// 期初持仓交易净额
var LastDayPositionPremiumNetCash = 0.0;
//潜在行权盈余
var PotentialSurpluses = 0.0;
//权利金应付应收 总额
//var FrozenAndCopeWithExpirePremium = 0.0;
//净资金流入,其他资金,票息,互换收益,预付金余额,冻结权利金(未到期支付),冻结资金
double NetFund = 0.0, OtherFund = 0.0, Coupon = 0.0, SwapBalance = 0.0, MarginBalance, FrozenPremium, FrozenBalance = 0.0;
//应付到期权利金,应付存续权利金,应收存续权力金,了结权利金
double CopeWithExpirePremium, CopeWithLastPremium, ReceivablePremium, EndPremium = 0.0;
//未了结名义成交金额
var TotalNominal = 0.0;
//应付预付金,可提取预付金,Delta预付金,互换应付预付金
double PayableMargin = 0d, AdvisableMargin = 0d, DeltaMargin = 0d, SwapPayableMargin = 0.0;
//互换容忍预付金额 互换追保金额
double SwapUnPayableMargin = 0.0, SwapMargin = 0.0;
//双向预付金
var TwoSideMargin = 0.0;
var OtherSideMargin = 0.0;
var MySideMargin = 0.0;
//额外追保
var AdditionalMargin = 0.0;
//追保金额
var Margin = 0.0;
//昨日抵押品价值
var LastGuaranteesTotalAmount = 0.0;
//持仓名义本金规模
var AvailableStockEqvNotional = 0.0;
//潜在风险暴露
var PFE = 0d;
//互换存续预付金
var SwapMarinAmount = 0d;
//
ClientBalanceDaily clientbalancedaily = null;
#endregion
#region 客户授信 资信等级 客户昨日现金 clientbalancedaily对象初始化
//获取客户授信
var credits = creditList?.Where(t => t.ClientId == client.id);
if (credits.Any())
{
//设置的全部授信
lineOfCredit = credits.Sum(t => t.Credit ?? 0);
}
else
{
lineOfCredit = 0.0;
}
//资信等级授信额度
//creditRating = creditRatingList != null ? creditRatingList.FirstOrDefault(t => t.id == client.CreditRatingId) : null;
//if (creditRating != null)
//{
// lineOfCredit += creditRating.CreditLine ?? 0.0;
//}
clientbalancedaily = new ClientBalanceDaily()
{
ClientId = client.id,
ClientName = client.Name,
ClientNumber = client.Number,
BalanceDate = balanceDate
};
//获取用户最后结算日可用资金
var clientbalancedailyPre = preClientbalancedailys.FirstOrDefault(t => t.ClientId == client.id);
if (clientbalancedailyPre != null)
{
if (!string.IsNullOrEmpty(clientbalancedailyPre.FundJson))
{
clientbalancedailyPre.FundObject = JsonConvert.DeserializeObject<FundObject>(clientbalancedailyPre.FundJson);
if (clientbalancedailyPre.FundObject.InFund.Count() == 1 && clientbalancedailyPre.FundObject.InFund.ContainsKey(string.Empty) && currencyCodes.FirstOrDefault() != string.Empty)
{
if (string.IsNullOrEmpty(client.SettlementCurrency))
{
throw new Exception("客户:" + client.Name + "未配置结算币种");
}
clientbalancedailyPre.FundObject.InFund.Add(client.SettlementCurrency, clientbalancedailyPre.InFund ?? 0);
clientbalancedailyPre.FundObject.InFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.InFundSum ?? 0);
clientbalancedailyPre.FundObject.OutFund.Add(client.SettlementCurrency, clientbalancedailyPre.OutFund ?? 0);
clientbalancedailyPre.FundObject.OutFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.OutFundSum ?? 0);
clientbalancedailyPre.FundObject.NetFund.Add(client.SettlementCurrency, clientbalancedailyPre.NetFund ?? 0);
clientbalancedailyPre.FundObject.NetFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.NetFundSum ?? 0);
clientbalancedailyPre.FundObject.OtherFund.Add(client.SettlementCurrency, clientbalancedailyPre.OtherFund ?? 0);
clientbalancedailyPre.FundObject.OtherFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.OtherFundSum ?? 0);
clientbalancedailyPre.FundObject.TodayRemainFund.Add(client.SettlementCurrency, clientbalancedailyPre.ToDayRemainFund ?? 0);
}
foreach (var currencyCode in currencyCodes)
{
if (clientbalancedailyPre.FundObject.TodayRemainFund.ContainsKey(currencyCode))
{
fundObject.LastDayRemainFund[currencyCode] = clientbalancedailyPre.FundObject.TodayRemainFund[currencyCode];
}
}
}
else
{
clientbalancedailyPre.FundObject = new FundObject();
if (currencyCodes.Count() == 1 && currencyCodes.FirstOrDefault() == string.Empty)
{
clientbalancedailyPre.FundObject.InFund.Add(string.Empty, clientbalancedailyPre.InFund ?? 0);
clientbalancedailyPre.FundObject.InFundSum.Add(string.Empty, clientbalancedailyPre.InFundSum ?? 0);
clientbalancedailyPre.FundObject.OutFund.Add(string.Empty, clientbalancedailyPre.OutFund ?? 0);
clientbalancedailyPre.FundObject.OutFundSum.Add(string.Empty, clientbalancedailyPre.OutFundSum ?? 0);
clientbalancedailyPre.FundObject.NetFund.Add(string.Empty, clientbalancedailyPre.NetFund ?? 0);
clientbalancedailyPre.FundObject.NetFundSum.Add(string.Empty, clientbalancedailyPre.NetFundSum ?? 0);
clientbalancedailyPre.FundObject.OtherFund.Add(string.Empty, clientbalancedailyPre.OtherFund ?? 0);
clientbalancedailyPre.FundObject.OtherFundSum.Add(string.Empty, clientbalancedailyPre.OtherFundSum ?? 0);
fundObject.LastDayRemainFund[string.Empty] = clientbalancedailyPre.ToDayRemainFund ?? 0;
}
else
{
clientbalancedailyPre.FundObject.InFund.Add(client.SettlementCurrency, clientbalancedailyPre.InFund ?? 0);
clientbalancedailyPre.FundObject.InFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.InFundSum ?? 0);
clientbalancedailyPre.FundObject.OutFund.Add(client.SettlementCurrency, clientbalancedailyPre.OutFund ?? 0);
clientbalancedailyPre.FundObject.OutFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.OutFundSum ?? 0);
clientbalancedailyPre.FundObject.NetFund.Add(client.SettlementCurrency, clientbalancedailyPre.NetFund ?? 0);
clientbalancedailyPre.FundObject.NetFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.NetFundSum ?? 0);
clientbalancedailyPre.FundObject.OtherFund.Add(client.SettlementCurrency, clientbalancedailyPre.OtherFund ?? 0);
clientbalancedailyPre.FundObject.OtherFundSum.Add(client.SettlementCurrency, clientbalancedailyPre.OtherFundSum ?? 0);
fundObject.LastDayRemainFund[client.SettlementCurrency] = clientbalancedailyPre.ToDayRemainFund ?? 0;
}
}
LastDayPositionPremiumNetCash = clientbalancedailyPre.PositionPremiumNetCash ?? 0.0;
LastGuaranteesTotalAmount = clientbalancedailyPre.TodayRemianFundProduct ?? 0.0;
}
AvailableStockEqvNotional =
credits.Sum(t => t.StockEqvNotional) -
trades.Where(O => ConsTrade.PositionTradeStatusList.Contains(O.TradeStatus) && O.ClientId == client.id)
.Sum(O => (double?)O.StockEqvNotionalReal) ?? 0.0;
#endregion
#region 出金 入金 当日可用资金计算
//获取客户所有出入金列表
clientEntryexits = entryexits.Where(t => t.ClientId == client.id).ToList();
var tradeCashGroupIds = clientEntryexits.Where(y => y.IsGroup == 1).Select(y => y.TradeCashId).ToArray();
var tradeCashGroups = DbContext.trade_cash.Where(x => tradeCashGroupIds.Contains(x.id));
if (clientEntryexits != null)
{
clientEntryexits.ForEach(clientEntryexit =>
{
if (null == clientEntryexit.Direction)
{
throw new Exception("客户:" + client.Name + "有一条出入记录存在出入金方向存在问题!");
}
if (currencyCodes.Count()==1)
{
clientEntryexit.CurrencyCode = "";
}
//之前单币种环境改为多币种环境后历史数据为""和配置的币种匹配不上
if (currencyCodes.Count() >= 1 && string.IsNullOrWhiteSpace(clientEntryexit.CurrencyCode))
{
if (currencyCodes.Contains("CNY"))
{
clientEntryexit.CurrencyCode = "CNY";
}
else if (currencyCodes.Contains("RMB"))
{
clientEntryexit.CurrencyCode = "RMB";
}
}
if (clientEntryexit.Direction.Equals("入金"))
{
if (fundObject.InFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.InFund[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.InFund.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
if (fundObject.NetFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.NetFund[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.NetFund.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
}
else if (clientEntryexit.Direction.Equals("出金"))
{
if (fundObject.OutFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.OutFund[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.OutFund.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
if (fundObject.NetFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.NetFund[clientEntryexit.CurrencyCode] -= clientEntryexit.Money ?? 0;
}
else
{
fundObject.NetFund.Add(clientEntryexit.CurrencyCode, -clientEntryexit.Money ?? 0);
}
}
else if (clientEntryexit.Direction.Equals("其他收入"))
{
if (fundObject.InFundOther.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.InFundOther[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.InFundOther.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
if (fundObject.OtherFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.OtherFund[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.OtherFund.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
}
else if (clientEntryexit.Direction.Equals("其他支出"))
{
if (fundObject.OutFundOther.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.OutFundOther[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.OutFundOther.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
if (fundObject.OtherFund.ContainsKey(clientEntryexit.CurrencyCode))
{
fundObject.OtherFund[clientEntryexit.CurrencyCode] += clientEntryexit.Money ?? 0;
}
else
{
fundObject.OtherFund.Add(clientEntryexit.CurrencyCode, clientEntryexit.Money ?? 0);
}
}
else
{
if (ClientCashInCashOut.系统操作_期权费.Equals(clientEntryexit.Action))
{
//CurrPnl += clientEntryexit.Money ?? 0.0;
CurrChangeAmount += clientEntryexit.Money ?? 0.0;
OptionPremium += clientEntryexit.Money ?? 0.0;
}
//黑箱了结资金按照主交易来进行归类
else if ((ClientCashInCashOut.系统操作_行权费.Equals(clientEntryexit.Action) || ClientCashInCashOut.系统操作_平仓费.Equals(clientEntryexit.Action)) && clientEntryexit.IsGroup != 2)
{
var money = clientEntryexit.Money ?? 0;
//如果是黑箱主交易了结资金(主交易Money没有赋值),取对应tradeCash数据
if (money == 0 && clientEntryexit.IsGroup == 1)
{
var tradeCash = tradeCashGroups.FirstOrDefault(x => x.id == clientEntryexit.TradeCashId);
money = -(tradeCash?.Amount ?? 0);
}
//CurrPnl += money;
CurrChangeAmount += money;
SettlementBalance += money;
if (ClientCashInCashOut.系统操作_平仓费.Equals(clientEntryexit.Action))
{
UnwindBalance += money;
}
else
{
ExerciseBalance += money;
}
}
//黑箱了结资金按照主交易来进行归类
else if (ClientCashInCashOut.系统操作_票息.Equals(clientEntryexit.Action) && clientEntryexit.IsGroup != 2)
{
var money = clientEntryexit.Money ?? 0;
//如果是黑箱主交易了结资金(主交易Money没有赋值),取对应tradeCash数据
if (money == 0 && clientEntryexit.IsGroup == 1)
{
var tradeCash = tradeCashGroups.FirstOrDefault(x => x.id == clientEntryexit.TradeCashId);
money = -(tradeCash?.Amount ?? 0);
}
CurrChangeAmount += money;
Coupon += money;
}
}
if (ClientCashInCashOut.已确认.Equals(clientEntryexit.State))
{
clientEntryexit.SettleDate = balanceDate;
clientEntryexit.State = ClientCashInCashOut.已结算;
}
});
}
clientEntryexits_swap = entryexits_swap.Where(t => t.ClientId == client.id).ToList();
if (clientEntryexits_swap != null)
{
clientEntryexits_swap.ForEach(clientEntryexit =>
{
if (null == clientEntryexit.Direction)
{
throw new Exception("客户:" + client.Name + "有一条出入记录存在出入金方向存在问题!");
}
if (currencyCodes.Count() == 1)
{
clientEntryexit.CurrencyCode = "";
}
//之前单币种环境改为多币种环境后历史数据为""和配置的币种匹配不上
if (currencyCodes.Count() >= 1 && string.IsNullOrWhiteSpace(clientEntryexit.CurrencyCode))
{
if (currencyCodes.Contains("CNY"))
{
clientEntryexit.CurrencyCode = "CNY";
}
else if (currencyCodes.Contains("RMB"))
{
clientEntryexit.CurrencyCode = "RMB";
}
}
if (ClientCashInCashOut.系统操作_期权费.Equals(clientEntryexit.Action) || ClientCashInCashOut.系统操作_应付预付金.Equals(clientEntryexit.Action) || ClientCashInCashOut.系统操作_预付金返息.Equals(clientEntryexit.Action))
{
CurrChangeAmount += clientEntryexit.Money ?? 0.0;
OptionPremiumSwap += clientEntryexit.Money ?? 0.0;
}
else if (ClientCashInCashOut.系统操作_平仓费.Equals(clientEntryexit.Action))
{
CurrChangeAmount += clientEntryexit.Money ?? 0.0;
SwapBalance += clientEntryexit.Money ?? 0.0;
}
else if (ClientCashInCashOut.系统操作_互换.Equals(clientEntryexit.Action))
{
CurrChangeAmount += clientEntryexit.Money ?? 0.0;
SwapBalance += clientEntryexit.Money ?? 0.0;
}
if (ClientCashInCashOut.已确认.Equals(clientEntryexit.State))
{
clientEntryexit.SettleDate = balanceDate;
clientEntryexit.State = ClientCashInCashOut.已结算;
}
});
}
if (balanceDate >= new DateTime(2021, 6, 25) && PS.Config.Company == CompanyEnum.中金)
{
var clientCashInCashOutHistorys = DbContext.clientcashincashout_history.Where(x => x.ClientId == client.id && x.HappenDate == balanceDate).ToList();
if (balanceDate == new DateTime(2021, 6, 25))
{
clientCashInCashOutHistorys = DbContext.clientcashincashout_history.Where(x => x.ClientId == client.id && x.HappenDate <= new DateTime(2021, 6, 25)).ToList();
}
clientCashInCashOutHistorys.ForEach(item =>
{
if (item.Action.Equals("入金"))
{
if (fundObject.InFund.ContainsKey("CNY"))
{
fundObject.InFund["CNY"] += item.Amount ?? 0;
}
else
{
fundObject.InFund.Add("CNY", item.Amount ?? 0);
}
if (fundObject.NetFund.ContainsKey("CNY"))
{
fundObject.NetFund["CNY"] += item.Amount ?? 0;
}
else
{
fundObject.NetFund.Add("CNY", item.Amount ?? 0);
}
}
else if (item.Action.Equals("出金"))
{
if (fundObject.OutFund.ContainsKey("CNY"))
{
fundObject.OutFund["CNY"] += Math.Abs(item.Amount ?? 0);
}
else
{
fundObject.OutFund.Add("CNY", Math.Abs(item.Amount ?? 0));
}
//出金历史记录为负数,包含方向了
if (fundObject.NetFund.ContainsKey("CNY"))
{
fundObject.NetFund["CNY"] += item.Amount ?? 0;
}
else
{
fundObject.NetFund.Add("CNY", item.Amount ?? 0);
}
}
else
{
if (item.Action.Equals("期权费"))
{
CurrChangeAmount += item.Amount ?? 0.0;
OptionPremium += item.Amount ?? 0.0;
}
else if (item.Action.Equals("结算金额"))
{
CurrChangeAmount += item.Amount ?? 0.0;
SettlementBalance += item.Amount ?? 0.0;
UnwindBalance += item.Amount ?? 0.0;
}
}
});
}
foreach (var item in currencyCodes)
{
if (fundObject.TodayRemainFund.ContainsKey(item))
{
fundObject.TodayRemainFund[item] = (fundObject.LastDayRemainFund.ContainsKey(item) ? fundObject.LastDayRemainFund[item] : 0) + (fundObject.NetFund.ContainsKey(item) ? fundObject.NetFund[item] : 0) + (fundObject.OtherFund.ContainsKey(item) ? fundObject.OtherFund[item] : 0);
}
else
{
fundObject.TodayRemainFund.Add(item, (fundObject.LastDayRemainFund.ContainsKey(item) ? fundObject.LastDayRemainFund[item] : 0) + (fundObject.NetFund.ContainsKey(item) ? fundObject.NetFund[item] : 0) + (fundObject.OtherFund.ContainsKey(item) ? fundObject.OtherFund[item] : 0));
}
if ((client.SettlementCurrency ?? "CNY") == item || item == "")
{
fundObject.TodayRemainFund[item] += CurrChangeAmount;
}
var rateObj = new eod_currency_rate
{
Rate = 1,
SellRate = 1,
BuyRate = 1,
ForeignCurrency = item,
LocalCurrency = client.SettlementCurrency,
};
if (PS.Config.ErpElement.SupportMultiCurrency)
{
currencyProvider.TryGetCurrencyRate(item, client.SettlementCurrency, out rateObj);
if (rateObj == null)
{
_context.RaiseError("结算客户资金", $"[{client.Name}]找不到汇率:{item}{client.SettlementCurrency}");
}
}
CurrAvailAmount += fundObject.TodayRemainFund[item] * rateObj.Rate;
LastDayAvailAmount += fundObject.LastDayRemainFund[item] * rateObj.Rate;
inFund += fundObject.InFund[item] * rateObj.Rate;
outFund += fundObject.OutFund[item] * rateObj.Rate;
NetFund += fundObject.NetFund[item] * rateObj.Rate;
inFundOther += fundObject.InFundOther[item] * rateObj.Rate;
outFundOther += fundObject.OutFundOther[item] * rateObj.Rate;
OtherFund += fundObject.OtherFund[item] * rateObj.Rate;
}
#endregion
#region 抵押品
//抵押品资金价值
var tempClientProductList = clientProductList.Where(a => a.product.ClientId == client.id).ToList();
var GuaranteesTotalAmount = 0.0;
if (tempClientProductList.Any())
{
tempClientProductList.ForEach(t =>
{
if (t.um == null)
{
throw new Exception($"抵押品,出入金单号[{t.product.Number}]标的ID[{t.product.UnderlyingId}]未找到对应标的基本信息!");
}
if (t.variety == null)
{
throw new Exception($"抵押品,出入金单号[{t.product.Number}]品种ID[{t.product.VarietyId}]未找到对应品种基本信息!");
}
if (dayeods.TryGetPrice(t.um.UnderlyingCode, SettlementTypeEnum.ClosePrice, out var price))
{
GuaranteesTotalAmount += (t.product.ProductAmount ?? 0) * (t.product.Rate ?? 0.0) * price;
}
else
{
throw new Exception($"抵押品,出入金单号[{t.product.Number}]标的[{t.um.UnderlyingCode}]在{balanceDate:yyyy-MM-dd}收盘价不存在!");
}
});
}
#endregion
#region 当日冻结权利金 当日应收权利金 潜在行权盈余 持仓市值 持仓Pnl
//持仓交易
var positionTrades = trades.Where(t => t.TradeStatus.Equals(ConsTrade.确认成交) && t.ClientId == client.id && t.TradeType != "收益互换").ToList();
var clientEodSwaps = eodSwaps.Where(t => t.ClientId == client.id && t.ValueDate == balanceDate).ToList();
//var tradeIds = clientTrades.Where(t => t.ClientId == client.id).Select(t => t.id).ToList();
//获取所有持仓交易ids
var positionTradeIds = positionTrades == null || positionTrades.Count == 0 ? new List<int>() : positionTrades.Select(t => t.id).ToList();
//获取客户冻结资金
var clientFrozenFund = clientFrozenFunds[client.id];
//当前持仓并且未到支付日的卖出交易(客户为买入,渠道为卖出)则为冻结的权利金
//FrozenPremium = positionTrade == null || positionTrade.Count == 0 ? 0.0 : (positionTrade.Where(t => t.PremiumPayDate > balanceDate && t.BuySell == "卖出").Sum(t => t.TradePrice ?? 0.0));
FrozenPremium = clientFrozenFund.FrozenPayableOptionMoney;
//应收存续权利金
//ReceivablePremium = positionTrade == null || positionTrade.Count == 0 ? 0.0 : (positionTrade.Where(t => t.PremiumPayDate > balanceDate && t.BuySell == "买入").Sum(t => t.TradePrice ?? 0.0));
ReceivablePremium = clientFrozenFund.FrozenReceivableOptionMoney;
//冻结预付金(绝对值)
var FrozenMarginMoney = clientFrozenFund.FrozenMarginMoney;
//冻结资金=冻结权利金+到期停牌股票名义金额×6.5%*30/365(默认收取一个月资金利息,多追少补) //todo 此处需要增加股票停复牌信息,同时检查到期交易不能默认执行到期
//FrozenBalance = FrozenPremium;
//应付到期权利金
CopeWithExpirePremium = OptionPremium + OptionPremiumSwap;
//应付存续权利金
CopeWithLastPremium = FrozenPremium;
//获取客户持仓交易的pv以及浮动盈亏
var eodpnlQuery = eodpnlList.Where(t => positionTradeIds.Contains(t.TradeId));
//未了结名义成交金额 todo //持仓的买入 以及卖出是否都统计
TotalNominal = positionTrades == null || positionTrades.Count == 0 ? 0 : positionTrades.Sum(t => t.UnderlyingInstrumentType == "Stock" ? t.StockEqvNotional : (t.Notional * (t.SpotPrice ?? 0.0)));
TotalNominal += Convert.ToDouble(clientEodSwaps.Sum(x => x.NotionalValue));
//计算潜在客户行权盈余 max{名义成交金额*(标的当日结算价-标的初始价格)/行权价格, 0}
foreach (var t in positionTrades)
{
if (t.TradeType != "现金流交易" && t.TradeType != "自定义交易")
{
var spotPrice = t.SpotPrice ?? t.SpotPrice ?? 0.0;
var nominal = t.UnderlyingInstrumentType == "Stock" ? t.StockEqvNotional : (t.Notional * spotPrice);
if (!dayeods.TryGetPrice(t.UnderlyingCode, t.SettlementType, out var nowPrice))
{
throw new Exception($"找不到收盘价({t.UnderlyingCode}),无法结算!");
}
var Strike = t.IsMoneynessOptionData ? ((t.Strike ?? 0) * t.SpotPrice ?? 0) : t.Strike ?? 0;
//如果期初价格未0则已份额计算潜在行权盈余
if (spotPrice == 0)
{
PotentialSurpluses += Math.Max(Strike == 0 ? 0 : (t.Notional * (nowPrice - Strike) * ("Call".Equals(t.CallPut) ? 1 : -1)), 0) * TradeCalcHelper.GetSign(t.BuySell) * -1;
}
else
{
PotentialSurpluses += Math.Max(Strike == 0 ? 0 : (nominal * (nowPrice - Strike) / spotPrice * ("Call".Equals(t.CallPut) ? 1 : -1)), 0) * TradeCalcHelper.GetSign(t.BuySell) * -1;
}
}
if (t.BuySell == "买入" && t.TradeType != "现金流交易")
{
var um = underlyDataSource.GetData(t.UnderlyingCode);
//deltaS/S
var rate = um.DeltaS_S;
if (!rate.IsNormalize())
{
var variety = varietyDataSource.GetData(um.CommodityCode);
if (ConsGlobal.InstrumentType.IsStockIndex(um.UnderlyingInstrumentType) || ConsGlobal.InstrumentType.IsStockIF(um.UnderlyingInstrumentType))
{
rate = variety.UpLimitValue;
}
else
{
rate = variety.Margin ?? 0;
}
}
var risk = eodRiskList.Where(O => O.TradeId == t.id).FirstOrDefault();
var pfe1 = t.StockEqvNotional == 0 ? (t.Notional * t.SpotPrice ?? 0) : t.StockEqvNotional;
var pfe2 = Math.Abs(risk.DeltaCash) * rate.Value + 0.5 * 100 * rate.Value * rate.Value * Math.Abs(Math.Min(risk.GammaCash, 0));
PFE += Math.Min(pfe1, pfe2);
}
}
PositionPremiumNetCash = positionTrades.Sum(t => -TradeCalcHelper.GetSign(t.BuySell) * ((t.TradePrice ?? 0) * (t.OriginalNotional != null && t.OriginalNotional != 0 ? t.Notional / t.OriginalNotional.Value : 1)));
//现金流交易没有份额的概念
SellTradePrice = positionTrades.Where(x => x.BuySell == "买入").Sum(
t => t.OriginalNotional.HasValue && t.OriginalNotional > 0 ? (t.TradePrice ?? 0) * t.Notional / t.OriginalNotional.Value : (t.TradePrice ?? 0));
//客户持仓交易预付金总和,客户买入为正,客户卖出为负
PrepaymentAmount = positionTrades.Sum(x => x.StockEqvNotional * (x.trade_snowball?.PrepaymentRatio ?? 0) * (x.BuySell == "卖出" ? 1 : -1));
var todayFinishedTrades = DbContext.trade.Where(t => keys.Contains(t.id) && t.IsGroup != 1 && t.ClientId == client.id)
.Select(x => new { x.id, x.TradeType, x.BuySell, x.TradePrice }).ToList();
var clientSwapIds = clientEodSwaps.Select(s => s.SwapTradeId).Distinct();
var todaySwapFinishedTrades = todaySwapTrades.Where(t => clientSwapIds.Contains(t.id) && ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus));
var todayFinishedTradeCash = from tc in finishedTradeCash
join td in DbContext.trade on tc.TradeId equals td.id
where td.IsGroup != 1 && td.ClientId == client.id
group tc by td.id into g
select new
{
tradeId = g.Key,
amountSum = g.Sum(n => n.Amount)
};
var todaySwapFinishedTradeIds = todaySwapFinishedTrades.Select(s => s.id).ToList();
var todaySwapFinishedCash = clientEntryexits_swap.Where(x => todaySwapFinishedTradeIds.Contains(x.TradeId ?? 0)).ToList();
var list = todayFinishedTradeCash.ToList();
WinLoss = todayFinishedTrades.ToArray().Sum(t =>
t.TradeType != "远期" ?
-TradeCalcHelper.GetSign(t.BuySell) * (t.TradePrice ?? 0) * finishedTradeNotionalPercentDic[t.id] + (todayFinishedTradeCash.FirstOrDefault(x => x.tradeId == t.id)?.amountSum ?? 0)
// 远期客户角度的实现盈亏 = 开仓总费用+平仓总费用
: (t.TradePrice ?? 0) * finishedTradeNotionalPercentDic[t.id] + (todayFinishedTradeCash.FirstOrDefault(x => x.tradeId == t.id)?.amountSum ?? 0)) * -1;
//了结开仓费用
EndPremium = todayFinishedTrades.Sum(t => t.TradeType != "远期" ? -TradeCalcHelper.GetSign(t.BuySell) * (t.TradePrice ?? 0) * finishedTradeNotionalPercentDic[t.id] : (t.TradePrice ?? 0) * finishedTradeNotionalPercentDic[t.id]) * -1;
EndPremium = EndPremium + todaySwapFinishedCash.Sum(s => s.Money ?? 0);
var eodPnlSum = new EodPnlGridSum();
if (eodpnlQuery.Any())
{
eodPnlSum.LastPvSum = eodpnlQuery.Sum(q => q.LastPv) * (-1);//昨日价值
eodPnlSum.PvSum = eodpnlQuery.Sum(q => q.Pv) * (-1);//当日价值
eodPnlSum.SellPvSum = eodpnlQuery.Where(x => x.BuySell == "买入").Sum(q => q.Pv) * (-1);//当日价值
eodPnlSum.RoundedPvSum = eodpnlQuery.Sum(q => q.RoundedPv) * (-1);//当日四舍五入价值
if (_context.SystemValue.PotentialSurplusCalcMode == valuedate.PotentialSurplusCalcMode_Pv)
{
PotentialSurpluses = eodPnlSum.PvSum ?? 0;
}
PositionPnl = eodpnlQuery.Sum(q => q.PositionPnL) * (-1);
RoundedPositionPnl = eodpnlQuery.Sum(q => q.RoundedPositionPnL) * (-1);
TotalPnl = eodpnlQuery.Sum(q => q.TotalPnL) * (-1);
#region 期权空头浮动盈利=max(期权空头持仓*(期权合约成本价-期权合约现价), 0) 从客户角度看的, 结构化交易需要将两条腿的空头Pnl合计
var singlePositionPnlTotal = eodpnlQuery.Where(x => x.TradeType != "结构化交易" && x.ParentTradeId == 0).Sum(n => n.BuySell == "买入" ? Math.Max(-n.PositionPnL, 0) : 0);
ClientSellPositionPnl = singlePositionPnlTotal;
#endregion
}
if (eodpnlList.Where(t => t.ClientId == client.id).Any())
{
eodPnlSum.DailyPnLSum = eodpnlList.Where(t => t.ClientId == client.id).Sum(q => q.DailyPnL) * (-1);//当日浮动盈亏
DailyPnl = eodpnlList.Where(t => t.ClientId == client.id).Sum(q => q.DailyPnL) * (-1);
}
#region 收益互换V2
var clientEodSwapsLast = clientEodSwaps.ToList();
foreach (var item in clientEodSwapsLast)
{
var lastEodSwap = eodSwaps.FirstOrDefault(t => t.SwapTradeId == item.SwapTradeId && t.ValueDate == preBalanceDate);
PotentialSurpluses += Convert.ToDouble(item.PostionValue) * (-1);
WinLoss += Convert.ToDouble(item.TdRealizedPnL) * (-1);
var lastPv = lastEodSwap != null ? Convert.ToDouble(lastEodSwap.PostionValue) * (-1) : 0;
eodPnlSum.LastPvSum = eodPnlSum.LastPvSum.HasValue ? eodPnlSum.LastPvSum + lastPv : lastPv;
var pnl = item.FloatingPnL + item.InterestPnL;
eodPnlSum.PvSum = eodPnlSum.PvSum.HasValue ? eodPnlSum.PvSum - Convert.ToDouble(item.PostionValue) : Convert.ToDouble(item.PostionValue) * (-1);
eodPnlSum.SellPvSum = eodPnlSum.SellPvSum.HasValue ? eodPnlSum.SellPvSum - Convert.ToDouble(item.MarketValueShort) : Convert.ToDouble(item.MarketValueShort) * (-1);
eodPnlSum.RoundedPvSum = eodPnlSum.RoundedPvSum.HasValue ? eodPnlSum.RoundedPvSum - Math.Round(Convert.ToDouble(item.PostionValue), 2) : Math.Round(Convert.ToDouble(item.PostionValue), 2) * (-1);
eodPnlSum.DailyPnLSum = eodPnlSum.DailyPnLSum.HasValue ? eodPnlSum.DailyPnLSum - Convert.ToDouble(item.TdRealizedPnL) : Convert.ToDouble(item.TdRealizedPnL) * (-1);
PositionPnl += Convert.ToDouble(pnl) * (-1);
RoundedPositionPnl += Math.Round(Convert.ToDouble(pnl), 2) * (-1);
TotalPnl += Convert.ToDouble(item.RealizedPnL) * (-1);
ClientSellPositionPnl += Math.Max(-Convert.ToDouble(item.MarketValueShort), 0);
var lastPnl = lastEodSwap != null ? lastEodSwap.FloatingPnL + lastEodSwap.InterestPnL : 0;
DailyPnl += Convert.ToDouble(pnl - lastPnl+item.TdRealizedPnL) * (-1);
//PayableMargin += Convert.ToDouble(item.InitMarginLoss + item.InitMarginGain+ item.PostionMarginLoss + item.PostionMarginGain);
}
var clientmarignQuery = marignQuery.Where(x => x.ClientId == client.id&&x.StructureType!="多空组合");
SwapMarinAmount = Convert.ToDouble(clientmarignQuery.Sum(s => s.marin));
#endregion
//合计持仓浮动盈亏
CurrPnl = eodPnlSum.DailyPnLSum ?? 0;
clientPv = eodPnlSum.PvSum;
roundedClientPv = eodPnlSum.RoundedPvSum;
clientSellPv = eodPnlSum.SellPvSum;
#endregion
#region 应缴预付金 预付金余额 可取预付金 追保额度
//获取tradespan 追保金额 = (当日资金余额 - 维持预付金) + 授信额度
var clientSpan = clientSpanList == null || clientSpanList.Count == 0 ? null : clientSpanList.FirstOrDefault(t => t.ClientId == client.id && t.ValueDate == balanceDate && t.SpanType == ClientSpan.SpanType_Eod);
if (clientSpan != null)
{
PayableMargin += clientSpan.WorstCastClientPayable ?? 0d;
DeltaMargin = clientSpan.DeltaMargin ?? 0d;
SwapPayableMargin = clientSpan.SwapWorstCastClientPayable ?? 0d;
SwapUnPayableMargin = clientSpan.SwapUnMargin ?? 0d;
TwoSideMargin = clientSpan.TwoSideMargin ?? 0d;
OtherSideMargin = clientSpan.OtherSideMargin ?? 0d;
MySideMargin = clientSpan.MySideMargin ?? 0d;
AdditionalMargin = (clientSpan.AdditionalWorstCastClientPayable) ?? 0d;
}
//var todaySwapMargins = clientEntryexits_swap.Where(x=>x.Action== ClientCashInCashOut.系统操作_应付预付金).ToList().Sum(s=>s.Money)??0;
//var swapFrozenBalance = entryexits_swapFuture.Where(x => x.Action == ClientCashInCashOut.系统操作_应付预付金 || x.Action == ClientCashInCashOut.系统操作_期权费).ToList().Sum(s => s.Money) ?? 0;
//PayableMargin += todaySwapMargins;
//SwapPayableMargin += todaySwapMargins;
//冻结资金
//FrozenMarginMoney += swapFrozenBalance;
FrozenBalance = ReceivablePremium - FrozenPremium - (clientFrozenFund.OutFunds + clientFrozenFund.RedeemFunds) - FrozenMarginMoney;
//预付金余额
MarginBalance = CurrAvailAmount + GuaranteesTotalAmount + FrozenBalance;
if (PS.Config.Is申万)
{
//期权空头浮动盈亏
MarginBalance -= ClientSellPositionPnl;
//空头持仓市值
MarginBalance -= Math.Abs(clientSellPv ?? 0);
}
else
{
//判断潜在行权盈余是否计入预付金余额
if ((valuedateBLL.SystemDate.IsPotentialSurplusUseMargin ?? 0) == 1)
{
MarginBalance += PotentialSurpluses;
}
}
//可取预付金为预付金余额 - 应缴预付金(上浮2%) 20220207新增减去互换预付金容忍额
AdvisableMargin = Math.Max(MarginBalance + (PayableMargin - SwapUnPayableMargin) * marginMaxRatio / marginRatio, 0);
//计算追保金额 维持预付金带方向 所以计算追保金额是 为相加
var IsTradeCredit = (client.IsTradeCredit ?? 0) == 1;
// 场外预付金资金占用后剩余资金
var marginBalanceSurplus = 0d;
//是否期权费授信
if (IsTradeCredit)
{
//授信是否可用于互换
if (client.creditCanApplySwap)
{
//期权费授信可以支付权利金 则预付金余额未0时 资金从
Margin = Math.Min(MarginBalance + lineOfCredit + (PayableMargin - SwapUnPayableMargin), 0);
}
else
{
//互换最大可用资金
marginBalanceSurplus = Math.Max(Math.Min(Math.Max(MarginBalance - OptionPremiumSwap + lineOfCredit + (PayableMargin - SwapPayableMargin), 0), Math.Max(MarginBalance - OptionPremiumSwap, 0)), 0);
//收益互换追保金额 剩余可支付互换资金 - (互换占用预付金 - 互换容忍预付金额度)
SwapMargin = Math.Min(marginBalanceSurplus + OptionPremiumSwap + (SwapPayableMargin - SwapUnPayableMargin), 0);
//计算期权追保
Margin = Math.Min(MarginBalance - OptionPremiumSwap + lineOfCredit + (PayableMargin - SwapPayableMargin), 0) + SwapMargin;
}
}
else
{
//授信是否可用于互换
if (client.creditCanApplySwap)
{
//期权费授信不可以支付权力金时
Margin = Math.Min(Math.Max(MarginBalance, 0) + lineOfCredit + (PayableMargin - SwapUnPayableMargin), 0) + Math.Min(MarginBalance, 0);
}
else
{
//互换最大可用资金
marginBalanceSurplus = Math.Max(Math.Min(Math.Max(Math.Max(MarginBalance - OptionPremiumSwap, 0) + lineOfCredit + (PayableMargin - SwapUnPayableMargin), 0), Math.Max(MarginBalance - OptionPremiumSwap, 0)), 0);
//收益互换追保金额 剩余可支付互换资金 - (互换占用预付金 - 互换容忍预付金额度)
SwapMargin = Math.Min(marginBalanceSurplus + OptionPremiumSwap + (SwapPayableMargin - SwapUnPayableMargin), 0) + Math.Min(marginBalanceSurplus + OptionPremiumSwap, 0);
//计算期权追保
Margin = Math.Min(Math.Max(MarginBalance - OptionPremiumSwap, 0) + lineOfCredit + (PayableMargin - SwapUnPayableMargin), 0) + Math.Min(MarginBalance - OptionPremiumSwap, 0) + SwapMargin;
}
}
#endregion
#region 国君收益互换--导入持仓
//获取客户导入的所有持仓信息 -- 收益互换(国君)
var clientEodPositionSwapMannual = EodPositionSwapMannual.Where(x => x.ClientId == client.id).ToList();
if (clientEodPositionSwapMannual.Any())
{
double swapMargin = 0.0;
double swappv = 0.0;
double swappnl = 0.0;
clientEodPositionSwapMannual.ForEach(x =>
{
var underly = underlyDataSource.GetData(x.UnderlyingCode);
var variety = varietyDataSource.GetData(underly.UnderlyingTypeId);
currencyProvider.TryGetCurrencyRate(variety.QuoteCurrency, client.SettlementCurrency, out var rateObj);
//预付金导入是客户方向,其他值是交易员方向
swapMargin += (x.Margin) * rateObj.Rate;
swappv += (-x.PositionPnl + x.TotalFee) * rateObj.Rate;
swappnl += (-x.PositionPnl * rateObj.Rate);
});
PayableMargin -= swapMargin;
clientPv = (clientPv ?? 0) + swappv;
roundedClientPv = (roundedClientPv ?? 0) + swappv;
PositionPnl += swappnl;
RoundedPositionPnl += swappnl;
}
#endregion
#region ClientBalacedaily ClientBalace对象赋值
if (client.BoundSide == BoundSideEnum.南向 && clientSpan != null)
{
var credit = DbContext.credit.FirstOrDefault(x => x.CreditStartDate <= balanceDate && x.CreditDeadLine >= balanceDate && x.ClientId == client.id && x.ProcessStatus == "已审批");
var PFECredit = credit != null ? credit.PFECredit : 0;
clientSpan.PFEUsed = Math.Max(Math.Min((clientSpan.PFEUsed ?? 0) - CurrAvailAmount, PFECredit ?? 0), 0);
}
clientbalancedaily.ToDayRemainFund = CurrAvailAmount;
clientbalancedaily.LastDayRemainFund = LastDayAvailAmount;
clientbalancedaily.PositionPremiumNetCash = PositionPremiumNetCash;
clientbalancedaily.SellTradePrice = SellTradePrice;
clientbalancedaily.LastDayPositionPremiumNetCash = LastDayPositionPremiumNetCash;
clientbalancedaily.WinLoss = WinLoss;
clientbalancedaily.EndPremium = EndPremium;
clientbalancedaily.InFundOther = inFundOther;
clientbalancedaily.OutFundOther = outFundOther;
clientbalancedaily.BalanceDate = balanceDate;
clientbalancedaily.DayGainLoss = CurrPnl;
clientbalancedaily.PositionPnl = PositionPnl;
clientbalancedaily.RoundedPositionPnl = RoundedPositionPnl;
clientbalancedaily.ClientSellPositionPnl = ClientSellPositionPnl;
clientbalancedaily.TotalPnl = TotalPnl;
clientbalancedaily.DailyPnl = DailyPnl;
clientbalancedaily.OptionPremium = OptionPremium;
clientbalancedaily.OptionPremiumSwap = OptionPremiumSwap;
clientbalancedaily.SettlementBalance = SettlementBalance;
clientbalancedaily.UnwindBalance = UnwindBalance;
clientbalancedaily.Coupon = Coupon;
clientbalancedaily.SwapBalance = SwapBalance;
clientbalancedaily.ExerciseBalance = ExerciseBalance;
clientbalancedaily.AdvisableMargin = AdvisableMargin;
clientbalancedaily.TotalNominal = TotalNominal;
clientbalancedaily.Pv = clientPv ?? 0;
clientbalancedaily.RoundedPv = roundedClientPv ?? 0;
clientbalancedaily.SellPv = clientSellPv ?? 0;
clientbalancedaily.PrepaymentAmount = PrepaymentAmount;
clientbalancedaily.CopeWithLastPremium = CopeWithLastPremium;
clientbalancedaily.CopeWithExpirePremium = CopeWithExpirePremium;
clientbalancedaily.FrozenBalance = FrozenBalance;
clientbalancedaily.FrozenPremium = FrozenPremium;
clientbalancedaily.FrozenOutFund = clientFrozenFund.OutFunds;
clientbalancedaily.FrozenRedeemFunds = clientFrozenFund.RedeemFunds;
clientbalancedaily.MarginBalance = MarginBalance;
clientbalancedaily.InFund = inFund;
clientbalancedaily.OutFund = outFund;
clientbalancedaily.NetFund = NetFund;
clientbalancedaily.OtherFund = OtherFund;
clientbalancedaily.IsTradeCredit = IsTradeCredit;
clientbalancedaily.Credit = lineOfCredit;
clientbalancedaily.CashDeposit = PayableMargin;
clientbalancedaily.PayableMargin = PayableMargin;
clientbalancedaily.DeltaMargin = DeltaMargin;
clientbalancedaily.SwapPayableMargin = SwapPayableMargin;
clientbalancedaily.SwapUnPayableMargin = SwapUnPayableMargin;
clientbalancedaily.TwoSideMargin = TwoSideMargin;
clientbalancedaily.OtherSideMargin = OtherSideMargin;
clientbalancedaily.MySideMargin = MySideMargin;
clientbalancedaily.IsPayableMarginManual = clientSpan?.ModifiedFlag;
clientbalancedaily.FrozenMarginMoney = FrozenMarginMoney;
clientbalancedaily.Margin = Margin;
clientbalancedaily.TodayRemianFundProduct = GuaranteesTotalAmount;
clientbalancedaily.CashInCashOutProductChange = GuaranteesTotalAmount - LastGuaranteesTotalAmount;
clientbalancedaily.PotentialSurpluses = PotentialSurpluses;
clientbalancedaily.OptId = UserId;
clientbalancedaily.OptName = UserName;
clientbalancedaily.OptDate = DateTime.Now;
clientbalancedaily.AdditionalMargin = AdditionalMargin;
clientbalancedaily.AvailableStockEqvNotional = AvailableStockEqvNotional;
clientbalancedaily.PFE = PFE;
clientbalancedaily.EAD = Math.Max(PFE - (clientbalancedaily.Pv ?? 0) - (clientbalancedaily.ToDayRemainFund ?? 0), 0);
var clientAmount = clientbalancedaily.ToDayRemainFund + clientbalancedaily.Credit + clientbalancedaily.TodayRemianFundProduct;
var clientSwapMarinAmount = clientAmount + SwapMarinAmount;
var MaintenanceLine = clientSwapMarinAmount == 0 ? 0 : (clientAmount + clientbalancedaily.PayableMargin) / clientSwapMarinAmount;
clientbalancedaily.MaintenanceLine = Math.Round(MaintenanceLine ?? 0, 2);
if (PS.Config.Is厦门象屿)
{
var xmxyClient = new XiaMenXiangYuClientInfo
{
ClientId = client.id,
ClientName = client.Name,
ClientNumber = client.Number,
FundThreshold = client.FundThreshold
};
if (balanceDate != DateTime.Today && clientDb.client_Axis_Fundthresholds.Where(x => x.ClientId == client.id).Any())
{
xmxyClient.FundThreshold = clientDb.client_Axis_Fundthresholds.Where(x => x.ValueDate <= balanceDate && x.ClientId == client.id).OrderByDescending(x => x.ValueDate)?.FirstOrDefault()?.FundThreshold;
}
new XiaMenXiangYuCashService(this).ExecuteV2(xmxyClient, clientbalancedaily, fundObject, out var InOutFund, _context.SettleDate, positionTrades.Count);
NetFund += InOutFund;
MarginBalance += InOutFund;
}
clientbalancedaily.FundObject = fundObject;
clientbalancedaily.FundJson = JsonHelper.Serialize(fundObject);
#endregion
#region 客户冻结状态
//如果应付资金总额PayableFund大于0 则设置client
//PayableFund => Math.Max(ClosedTradePayableFund + PositionTradePayableFund + MarginByPayableMarginCalc, 0);
var ToDayRemainFund = clientbalancedaily.ToDayRemainFund ?? 0;
//var PositionPremiumNetCash = clientbalancedaily.PositionPremiumNetCash ?? 0;
//请知道d1、d2、d3含义的注释一下
var d1 = Math.Min(ToDayRemainFund + PositionPremiumNetCash, 0);
var d2 = Math.Max(PositionPremiumNetCash - Math.Max(ToDayRemainFund + PositionPremiumNetCash, 0), 0);
var d3 = -(clientbalancedaily.PayableMargin ?? 0.0) - Math.Max(ToDayRemainFund - d1 + d2, 0)
- (clientbalancedaily.TodayRemianFundProduct ?? 0.0) - (clientbalancedaily.Credit ?? 0.0);
if (Math.Max(-d1 + d2 + d3, 0) > 0)
{
client.PendingMarginCallPayment = 1;
clientbalancedaily.State = "冻结";
}
else
{
//如果计算追保金额小于等于0则解冻
if (client.PendingMarginCallPayment == 1)
{
client.PendingMarginCallPayment = 0;
clientbalancedaily.State = "正常";
}
}
#endregion
#region 结算合计
clientbalancedaily.OptionPremiumSum = clientbalancedaily.OptionPremium;
clientbalancedaily.OptionPremiumSwapSum = clientbalancedaily.OptionPremiumSwap;
clientbalancedaily.SettlementBalanceSum = clientbalancedaily.SettlementBalance;
clientbalancedaily.UnwindBalanceSum = clientbalancedaily.UnwindBalance;
clientbalancedaily.ExerciseBalanceSum = clientbalancedaily.ExerciseBalance;
clientbalancedaily.CouponSum = clientbalancedaily.Coupon;
clientbalancedaily.SwapBalanceSum = clientbalancedaily.SwapBalance;
clientbalancedaily.WinLossSum = clientbalancedaily.WinLoss;
clientbalancedaily.EndPremiumSum = clientbalancedaily.EndPremium;
clientbalancedaily.CashInCashOutProductChangeSum = clientbalancedaily.CashInCashOutProductChange;
if (clientbalancedailyPre != null)
{
clientbalancedaily.NetFundSum = 0;
clientbalancedaily.InFundSum = 0;
clientbalancedaily.OutFundSum = 0;
clientbalancedaily.OtherFundSum = 0;
foreach (var item in currencyCodes)
{
var rateObj = new eod_currency_rate
{
Rate = 1,
SellRate = 1,
BuyRate = 1,
ForeignCurrency = item,
LocalCurrency = client.SettlementCurrency,
};
if (PS.Config.ErpElement.SupportMultiCurrency)
{
currencyProvider.TryGetCurrencyRate(item, client.SettlementCurrency, out rateObj);
if (rateObj == null)
{
_context.RaiseError("结算客户资金", $"[{client.Name}]找不到汇率:{item}{client.SettlementCurrency}");
}
}
clientbalancedailyPre.FundObject.NetFundSum.TryGetValue(item, out var preNetFundSum);
clientbalancedaily.FundObject.NetFund.TryGetValue(item, out var netFundToday);
clientbalancedaily.FundObject.NetFundSum[item] = preNetFundSum + netFundToday;
clientbalancedaily.NetFundSum += clientbalancedaily.FundObject.NetFundSum[item] * rateObj.Rate;
clientbalancedailyPre.FundObject.InFundSum.TryGetValue(item, out var preInFundSum);
clientbalancedaily.FundObject.InFund.TryGetValue(item, out var inFundToday);
clientbalancedaily.FundObject.InFundSum[item] = preInFundSum + inFundToday;
clientbalancedaily.InFundSum += clientbalancedaily.FundObject.InFundSum[item] * rateObj.Rate;
clientbalancedailyPre.FundObject.OutFundSum.TryGetValue(item, out var preOutFundSum);
clientbalancedaily.FundObject.OutFund.TryGetValue(item, out var outFundToday);
clientbalancedaily.FundObject.OutFundSum[item] = preOutFundSum + outFundToday;
clientbalancedaily.OutFundSum += clientbalancedaily.FundObject.OutFundSum[item] * rateObj.Rate;
clientbalancedailyPre.FundObject.OtherFundSum.TryGetValue(item, out var preOtherFundSum);
clientbalancedaily.FundObject.OtherFund.TryGetValue(item, out var otherFundToday);
clientbalancedaily.FundObject.OtherFundSum[item] = preOtherFundSum + otherFundToday;
clientbalancedaily.OtherFundSum += clientbalancedaily.FundObject.OtherFundSum[item] * rateObj.Rate;
}
clientbalancedaily.OptionPremiumSum += clientbalancedailyPre.OptionPremiumSum;
clientbalancedaily.OptionPremiumSwapSum += (clientbalancedailyPre.OptionPremiumSwapSum ?? 0);
clientbalancedaily.SettlementBalanceSum += clientbalancedailyPre.SettlementBalanceSum;
clientbalancedaily.UnwindBalanceSum += clientbalancedailyPre.UnwindBalanceSum;
clientbalancedaily.ExerciseBalanceSum += clientbalancedailyPre.ExerciseBalanceSum;
clientbalancedaily.CouponSum += clientbalancedailyPre.CouponSum;
clientbalancedaily.SwapBalanceSum += clientbalancedailyPre.SwapBalanceSum;
clientbalancedaily.WinLossSum += clientbalancedailyPre.WinLossSum;
clientbalancedaily.EndPremiumSum += (clientbalancedailyPre.EndPremiumSum ?? 0);
clientbalancedaily.CashInCashOutProductChangeSum += clientbalancedailyPre.CashInCashOutProductChangeSum;
}
else
{
clientbalancedaily.FundObject.NetFundSum = clientbalancedaily.FundObject.NetFund;
clientbalancedaily.FundObject.InFundSum = clientbalancedaily.FundObject.InFund;
clientbalancedaily.FundObject.OutFundSum = clientbalancedaily.FundObject.OutFund;
clientbalancedaily.FundObject.OtherFundSum = clientbalancedaily.FundObject.OtherFund;
clientbalancedaily.NetFundSum = clientbalancedaily.NetFund;
clientbalancedaily.InFundSum = clientbalancedaily.InFund;
clientbalancedaily.OutFundSum = clientbalancedaily.OutFund;
clientbalancedaily.OtherFundSum = clientbalancedaily.OtherFund;
}
#endregion
clientbalancedaily.FundJson = JsonHelper.Serialize(clientbalancedaily.FundObject);
newClientBalanceDaily.Add(clientbalancedaily);
if (PS.Config.Is广发商贸)
{
clientbalancedaily.PositionPnl = 0;
clientbalancedaily.RoundedPositionPnl = 0;
clientbalancedaily.RoundedPv = 0;
clientbalancedaily.Pv = 0;
}
}
#endregion
#region 计算渠道方合计
var baseName = PS.Config.CompanyFullName;
var baseClient = clientDb.client.FirstOrDefault(t => baseName.Equals(t.Name));
//判断存在渠道商配置信息时
if (baseClient != null)
{
//获取当前结算的非渠道本身的所有客户的结算信息(当日)
var allNewClientbalanceList = newClientBalanceDaily.Where(t => t.ClientId != baseClient.id);
//渠道客户当日结算信息(不包括其他客户合计)
var baseClientBalanceDaily = newClientBalanceDaily.FirstOrDefault(t => t.ClientId == baseClient.id);
#region 处理渠道商历史资金结算信息
//检查当前渠道商是否已有过结算记录
var tempBaseClientbalancedaily = preClientbalancedailys.FirstOrDefault(t => t.ClientId == baseClient.id);
//如果渠道商客户结算数据不存在则按结算日期顺序结算历史数据行
var RemainFund = 0.0;
if (tempBaseClientbalancedaily == null)
{
var allOldClientbalancedaily = DbContext.ClientBalanceDaily.AsNoTracking().Where(t => t.BalanceDate < balanceDate && allClientIds.Contains(t.ClientId) && t.ClientId != baseClient.id).ToList();
var balanceDateList = allOldClientbalancedaily.Select(t => t.BalanceDate).Distinct().OrderBy(t => t).ToList();
for (var i = 0; i < balanceDateList.Count; i++)
{
var tempBalancedaily = allOldClientbalancedaily.Where(t => t.BalanceDate == balanceDateList[i]);
var tempNewclientbalancedaily = new ClientBalanceDaily
{
ClientId = baseClient.id,
ClientName = baseClient.Name,
ClientNumber = baseClient.Number,
BalanceDate = balanceDateList[i],
ToDayRemainFund = RemainFund + tempBalancedaily.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))),
LastDayRemainFund = RemainFund,
DayGainLoss = tempBalancedaily.Sum(t => -(t.DayGainLoss ?? 0.0)),
OptionPremium = tempBalancedaily.Sum(t => -(t.OptionPremium ?? 0.0)),
OptionPremiumSwap = tempBalancedaily.Sum(t => -(t.OptionPremiumSwap ?? 0.0)),
SettlementBalance = tempBalancedaily.Sum(t => -(t.SettlementBalance ?? 0.0)),
UnwindBalance = tempBalancedaily.Sum(t => -(t.UnwindBalance ?? 0.0)),
SwapBalance = tempBalancedaily.Sum(t => -(t.SwapBalance ?? 0.0)),
Coupon = tempBalancedaily.Sum(t => -(t.Coupon ?? 0.0)),
ExerciseBalance = tempBalancedaily.Sum(t => -(t.ExerciseBalance ?? 0.0)),
AdvisableMargin = RemainFund + tempBalancedaily.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))),
TotalNominal = tempBalancedaily.Sum(t => (t.TotalNominal ?? 0.0)),
Pv = tempBalancedaily.Sum(t => -(t.Pv ?? 0.0)),
MarginBalance = RemainFund + tempBalancedaily.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))),
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
};
RemainFund = tempNewclientbalancedaily.ToDayRemainFund ?? 0.0;
newClientBalanceDaily.Add(tempNewclientbalancedaily);
}
}
#endregion
if (allNewClientbalanceList.Any())
{
if (baseClientBalanceDaily == null)
{
baseClientBalanceDaily = new ClientBalanceDaily
{
ClientId = baseClient.id,
ClientName = baseClient.Name,
ClientNumber = baseClient.Number,
BalanceDate = balanceDate,
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
};
}
baseClientBalanceDaily.ToDayRemainFund += allNewClientbalanceList.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))) + RemainFund;
baseClientBalanceDaily.LastDayRemainFund += RemainFund;
baseClientBalanceDaily.DayGainLoss = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.DayGainLoss) + allNewClientbalanceList.Sum(t => -(t.DayGainLoss ?? 0.0));
baseClientBalanceDaily.OptionPremium = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.OptionPremium) + allNewClientbalanceList.Sum(t => -(t.OptionPremium ?? 0.0));
baseClientBalanceDaily.OptionPremiumSwap = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.OptionPremiumSwap) + allNewClientbalanceList.Sum(t => -(t.OptionPremiumSwap ?? 0.0));
baseClientBalanceDaily.SettlementBalance = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.SettlementBalance) + allNewClientbalanceList.Sum(t => -(t.SettlementBalance ?? 0.0));
baseClientBalanceDaily.UnwindBalance = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.UnwindBalance) + allNewClientbalanceList.Sum(t => -(t.UnwindBalance ?? 0.0));
baseClientBalanceDaily.ExerciseBalance = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.ExerciseBalance) + allNewClientbalanceList.Sum(t => -(t.ExerciseBalance ?? 0.0));
baseClientBalanceDaily.Coupon = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.Coupon) + allNewClientbalanceList.Sum(t => -(t.Coupon ?? 0.0));
baseClientBalanceDaily.SwapBalance = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.SwapBalance) + allNewClientbalanceList.Sum(t => -(t.SwapBalance ?? 0.0));
baseClientBalanceDaily.AdvisableMargin = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.ToDayRemainFund) + allNewClientbalanceList.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))) + RemainFund;
baseClientBalanceDaily.TotalNominal = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.TotalNominal) + allNewClientbalanceList.Sum(t => (t.TotalNominal ?? 0.0));
baseClientBalanceDaily.Pv = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.Pv) + allNewClientbalanceList.Sum(t => -(t.Pv ?? 0.0));
baseClientBalanceDaily.MarginBalance = (baseClientBalanceDaily == null ? 0 : baseClientBalanceDaily.MarginBalance) + allNewClientbalanceList.Sum(t => -((t.OptionPremium ?? 0.0) + (t.OptionPremiumSwap ?? 0.0) + (t.SettlementBalance ?? 0.0) + (t.Coupon ?? 0.0) + (t.SwapBalance ?? 0.0))) + RemainFund;
}
}
#endregion
#region DB删除历史数据 增加当日数据
var sql = $"{nameof(ClientBalanceDaily.BalanceDate)}='{balanceDate.ToSqlDate()}'";
if (_context.ClienIds != null && _context.ClienIds.Any())
{
sql += $" and ClientId in ({string.Join(",", _context.ClienIds)})";
}
//删除 当日导入的old日数据
DbContext.BulkDelete<ClientBalanceDaily>(sql);
//MySqlBulkExtensions.BulkInsert(DbContext, newClientBalanceDaily);
DbContext.ClientBalanceDaily.AddRange(newClientBalanceDaily);
DbContext.SaveChanges();
#endregion
return true;
}
}
}