using BaseOUDAL;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Spreadsheet;
using MathNet.Numerics;
using NPOI.SS.UserModel;
using YLErp.BLL.Eod;
using YLErp.DBModels;
using YLErp.DBModels.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Models;
using YLErp.Modules;
using YLErp.Modules.ClientModule;
using YLErp.Modules.SwapModule;
using YLErp.Modules.SwapModule.Margin;
namespace YLErp.BLL.EodSettlement
{
///
/// 客户结算信息工具类
///
public class ClientBalanceUtility
{
private static readonly IYcLogger logger = LogFactory.GetLogger("客户资金结算");
///
/// 获取startDate至endDate 所有客户结算信息统计
///
public static IEnumerable GetAllClientBanlances(DateTime startDate, DateTime endDate, bool IsGetOuterMarginGap = false
, Abstract.IDataSource clientDataSource = null)
{
using var db = DbContextFactory.GetClientDbContext(null);
var clientIds = db.client.Where(s => s.ProcessStatus != "未提交").Select(n => n.id).ToList();
return GetClientBanlances(
clientIdList: clientIds,
startDate: startDate,
endDate: endDate,
IsGetOuterMarginGap: IsGetOuterMarginGap,
clientDataSource: clientDataSource);
}
///
/// 获取startDate至endDate 客户结算信息统计
///
public static IEnumerable GetClientBanlances(List clientIdList
, DateTime startDate, DateTime endDate, bool IsClientBalanceGap = false, bool IsGetOuterMarginGap = false, bool ParentFlag = false
, Abstract.IDataSource clientDataSource = null)
{
if (startDate > endDate)
{
throw new ArgumentException("startDate不能大于endDate");
}
if (null == clientIdList || !clientIdList.Any())
{
return Enumerable.Empty();
}
var returnClientId = clientIdList[0];
if (ParentFlag)
{
clientIdList = GetSubclientId(clientIdList[0]);
}
//一些客户在下面没有关联的数据,在这里直接赋值
var dic = clientIdList.ToHashSet().ToDictionary(n => n, m => new ClientSettleBalance
{
ClientId = m,
ValueDate = endDate,
});
foreach (var clientId in clientIdList)
{
var balance = dic[clientId];
var client = DataCacheProvider.GetClientDataSource().GetData(clientId);
balance.DesirableRate = client?.DesirableRate ?? 0;
balance.CreditCanApplySwap = client?.creditCanApplySwap ?? false;
balance.ClientType = client?.SwapTradeType ?? 0;
}
if (PS.Config.Is广期资本)
{
Dictionary samePeerDic = null;
using (var clientDb = DbContextFactory.GetClientDbContext(null))
{
samePeerDic = clientDb.client.AsNoTracking().Where(p => clientIdList.Contains(p.id)).ToDictionary(p => p.id, p => p.SamePeer);
}
samePeerDic ??= new Dictionary();
foreach (var kv in dic)
{
kv.Value.SamePeer = samePeerDic.ContainsKey(kv.Key) ? samePeerDic[kv.Key] ?? 0 : 0;
}
}
if (PS.Config.Is宏源)
{
Dictionary ratio1Dic = null;
using (var clientDb = DbContextFactory.GetClientDbContext(null))
{
ratio1Dic = (from c in clientDb.client
join cl in clientDb.clientlevel on c.LevelId equals cl.id into t_cl
from temp in t_cl.DefaultIfEmpty()
where clientIdList.Contains(c.id)
select new { Id = c.id, Ratio1 = temp == null ? null : temp.Ratio1 }).ToDictionary(p => p.Id, p => p.Ratio1);
}
ratio1Dic ??= new Dictionary();
foreach (var kv in dic)
{
kv.Value.Ratio1 = ratio1Dic.ContainsKey(kv.Key) ? ratio1Dic[kv.Key] ?? 1.0 : 1.0;
}
}
var clientIdS = new List();
clientIdS.AddRange(clientIdList);
using (var db = new YLContext())
{
//系统交易日
var valuedate = valuedateBLL.ValueDate;
var lastpushLog = db.push_log.Where(x => x.data_type == (int)SwapPushDataEnum.日终估值获取 && x.data_state == (int)SwapPushDataStateEnum.接收处理成功 && x.create_time > valuedate).OrderByDescending(o => o.create_time).FirstOrDefault();
//获取根据系统时间
var lastBalanceDate = EodOperationBase.GetLastSettlementDate(valuedate);
var lastDate = lastBalanceDate;
//查询历史记录
if (startDate <= lastBalanceDate)
{
if (endDate < lastBalanceDate)
{
lastDate = db.ClientBalanceDaily.Where(n => n.BalanceDate <= endDate)
.Max(n => n.BalanceDate) ?? DateTime.MinValue;
}
var sumQuery = from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate && clientIdS.Contains(t.ClientId)
select new ClientSettleBalance
{
ClientId = t.ClientId,
NetFund = t.NetFundSum ?? 0,
InFund = t.InFundSum ?? 0,
OutFund = t.OutFundSum ?? 0,
OtherFund = t.OtherFundSum ?? 0,
OptionPremium = t.OptionPremiumSum ?? 0,
OptionPremiumSwap = t.OptionPremiumSwapSum ?? 0,
SettlementBalance = t.SettlementBalanceSum ?? 0,
UnwindBalance = t.UnwindBalanceSum ?? 0,
SwapBalance = t.SwapBalanceSum ?? 0,
Coupon = t.CouponSum ?? 0,
ExerciseBalance = t.ExerciseBalanceSum ?? 0,
CashInCashOutProductChange = t.CashInCashOutProductChangeSum ?? 0,
WinLoss = t.WinLossSum ?? 0,
EndPremiumSum = t.EndPremiumSum ?? 0,
FundJson = t.FundJson,
PFE = t.PFE,
EAD = t.EAD,
LastSettlemetTime = t.OptDate,
TradeFee = t.trade_fee_sum ?? 0,
InterestPnl = t.interest_pnl_sum ?? 0
};
var sumDatas = sumQuery.ToArray();
//获取结束日期那一天的Sum总值
//例如2018-08-08到2019-08-08:区间段sum值 = sum(2019-08-08) - sum(2018-08-08)
//此处取的是sum(2019-08-08)
foreach (var data in sumDatas)
{
var balance = dic[data.ClientId];
balance.NetFund = data.NetFund;
balance.InFund = data.InFund;
balance.OutFund = data.OutFund;
balance.OtherFund = data.OtherFund;
balance.OptionPremium = data.OptionPremium;
balance.OptionPremiumSwap = data.OptionPremiumSwap;
balance.OptionPremiumAndSwapSum = data.OptionPremium + data.OptionPremiumSwap;
balance.EndPremiumSum = data.EndPremiumSum;
balance.SettlementBalance = data.SettlementBalance;
balance.UnwindBalance = data.UnwindBalance;
balance.ExerciseBalance = data.ExerciseBalance;
balance.SwapBalance = data.SwapBalance;
balance.Coupon = data.Coupon;
balance.CashInCashOutProductChange = data.CashInCashOutProductChange;
balance.WinLoss = data.WinLoss;
balance.TradeFee = data.TradeFee;
balance.InterestPnl = data.InterestPnl;
//起始时间 有值 和 WinLoss 区分 -- 国投不含当天
balance.WinLossSum = data.WinLoss;
balance.FundJson = data.FundJson;
balance.PFE = data.PFE;
balance.EAD = data.EAD;
balance.LastSettlemetTime = endDate <= lastDate ? data.LastSettlemetTime : null;
balance.LastHTSettlemetTime = lastpushLog == null ? "未同步" : lastpushLog.update_time.ToString("yyyy-MM-dd HH:mm:ss");
}
}
//--------------------------------------------
// 期末资金信息(取最新结算日当日信息)
//--------------------------------------------
//当日客户资金
if (valuedate > lastBalanceDate && lastBalanceDate < endDate)
{
var todayClientBalance = new RealTimeClientBanlanceService(OptUserInfo.SystemUser)
.GetBanlances(clientIdS, startDate > lastBalanceDate ? startDate : lastBalanceDate.AddDays(1), endDate);
foreach (var data in todayClientBalance)
{
data.TdWinLoss = data.WinLoss; //当日实现盈亏
if (dic.TryGetValue(data.ClientId, out var balance))
{
data.NetFund += balance.NetFund;
data.InFund += balance.InFund;
data.OutFund += balance.OutFund;
data.OtherFund += balance.OtherFund;
data.OptionPremium += balance.OptionPremium;
data.OptionPremiumSwap += balance.OptionPremiumSwap;
data.OptionPremiumAndSwapSum += balance.OptionPremium + balance.OptionPremiumSwap;
data.EndPremiumSum += balance.EndPremiumSum;
data.SettlementBalance += balance.SettlementBalance;
data.UnwindBalance += balance.UnwindBalance;
data.ExerciseBalance += balance.ExerciseBalance;
data.SwapBalance += balance.SwapBalance;
data.Coupon += balance.Coupon;
data.CashInCashOutProductChange += balance.CashInCashOutProductChange;
data.WinLoss += balance.WinLoss;
data.TradeFee += balance.TradeFee;
data.InterestPnl += balance.InterestPnl;
//data.AvailableStockEqvNotional = balance.AvailableStockEqvNotional;
data.LastSettlemetTime = balance.LastSettlemetTime;
data.LastHTSettlemetTime = balance.LastHTSettlemetTime;
}
dic[data.ClientId] = data;
data.UpdateDate = DateTime.Now;
data.IsLatestDate = true;
}
}
else
{
var endQuery = from t in db.ClientBalanceDaily
join cs in db.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 == lastDate
&& clientIdS.Contains(t.ClientId)
select new
{
ClientId = t.ClientId,
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,
MaintenanceMargin = cs.VariationMargin ?? 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,
MaintenanceLine = t.MaintenanceLine,
TotalNominal = t.TotalNominal,
InFundSum = t.InFundSum,
OutFundSum = t.OutFundSum,
VmInFundSum = t.vm_in_fund_sum,
VmOutFundSum = t.vm_out_fund_sum,
};
var endDatas = endQuery.ToArray();
//阶段三 §3.2 估值报告口径输入:已使用授信(授信出入表)、互换初始保证金(应付预付金净额)、
//交易维度追加保证金合计(Σ(维持−累计),规则15交易)——与实时口径共用同一查询(SwapSpanBalanceQueryService)
var usedCreditDic = ClientCreditInoutService.GetUsedCreditByClients(clientIdS, db);
var swapInitMarginDic = SwapSpanBalanceQueryService.GetSwapInitMarginByClients(clientIdS, lastDate, db);
var swapAdditionalDic = SwapSpanBalanceQueryService.GetTradeAdditionalMarginByClients(clientIdS, lastDate, db);
//合约维度追保金额新口径(2026-08-28):当日追加保证金现金部分合计
var todayCashAddDic = SwapSpanBalanceQueryService.GetTodayCashAdditionalMarginByClients(clientIdS, lastDate, db);
//原始授信额度(展示用):与 EOD 写入 clientbalancedaily.Credit 同批过滤条件(EodClientBalanceCalc :68),
//取 Σ(OriginalCredit ?? Credit) 不经比例折算;TotalCredit 仍为折算后值供公式使用
var originalCreditDic = db.credit.AsNoTracking()
.Where(t => t.ClientId != null && clientIdS.Contains(t.ClientId.Value)
&& t.ProcessStatus == "已审批"
&& (!t.CreditDeadLine.HasValue || t.CreditDeadLine >= lastDate)
&& (!t.CreditStartDate.HasValue || t.CreditStartDate <= lastDate))
.GroupBy(t => t.ClientId.Value)
.Select(g => new { ClientId = g.Key, Sum = g.Sum(t => (t.OriginalCredit ?? t.Credit) ?? 0d) })
.ToDictionary(x => x.ClientId, x => x.Sum);
foreach (var data in endDatas)
{
if (dic.TryGetValue(data.ClientId, out var balance))
{
var client = DataCacheProvider.GetClientDataSource().GetData(data.ClientId);
var lasttoDay = EodOperationBase.GetLastSettlementDate(lastDate, true);
var lastClientBalanceDaily = db.ClientBalanceDaily.Where(a => a.BalanceDate == lasttoDay && a.ClientId == data.ClientId).FirstOrDefault();
balance.FrozenBalance = data.FrozenBalance;
balance.FreezePremium = data.FreezePremium;
balance.ReceivablesPremium = data.ReceivablesPremium;
balance.AmountFund = data.AmountFund;
balance.TotalCredit = data.TotalCredit;
balance.OriginalTotalCredit = originalCreditDic.TryGetValue(data.ClientId, out var originalCredit) ? originalCredit : 0;
balance.PayableMargin = data.PayableMargin;
balance.GuaranteesTotalAmount = data.GuaranteesTotalAmount;
balance.FrozenMarginMoney = data.FrozenMarginMoney;
balance.DaliyPnl = data.DaliyPnl;
balance.RoundedDaliyPnl = data.RoundedPositionPnl - (lastClientBalanceDaily?.RoundedPositionPnl ?? 0);
balance.PositionPnl = data.PositionPnl;
balance.RoundedPositionPnl = data.RoundedPositionPnl;
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.MaintenanceMargin = data.MaintenanceMargin;
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.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.MaintenanceLine = data.MaintenanceLine ?? 0;
balance.PositionNotionalPrincipal = data.TotalNominal ?? 0;
balance.OutFundSum = data.OutFundSum ?? 0;
balance.InFundSum = data.InFundSum ?? 0;
balance.VmInFundSum = data.VmInFundSum ?? 0;
balance.VmOutFundSum = data.VmOutFundSum ?? 0;
//预付金金额=期末结存-初始预付金金额
balance.MarginBalance = balance.AmountFund - balance.MySideMargin;
//阶段三 §3.2:已使用授信/互换初始保证金/交易维度追加保证金(估值报告字段与可用资金公式共用输入)
balance.UsedCredit = usedCreditDic.TryGetValue(data.ClientId, out var usedCredit) ? usedCredit : 0;
balance.SwapInitMargin = swapInitMarginDic.TryGetValue(data.ClientId, out var swapInit) ? swapInit : 0;
balance.SwapAdditionalMarginTotal = swapAdditionalDic.TryGetValue(data.ClientId, out var swapAdd) ? swapAdd : 0;
// 可用资金:配置了追保规则维度的客户按维度分流(R2公式,实时/EOD三处一致);
// 未配置(MarginWatchRule=NULL,存量客户)维持旧口径:期末结存-追保账户余额
if (client?.MarginWatchRule == 0)
{
//定稿 2026-08-28:Max(现金结存 + 授信额度 − 已使用授信, 0),不再减交易维度追加保证金(避免双重扣减)
balance.AvailableAmount = SwapSpanBalanceCalc.CalcContractDimensionAvailable(
balance.AmountFund, balance.TotalCredit, balance.UsedCredit);
}
else if (client?.MarginWatchRule == 1)
{
//维持保证金(净收取为正)= -MySideMargin(client_span 维持保证金反号聚合)
balance.AvailableAmount = SwapSpanBalanceCalc.CalcClientDimensionAvailable(
balance.AmountFund, balance.TotalCredit, balance.UsedCredit,
balance.SwapInitMargin, -balance.MySideMargin);
}
else
{
balance.AvailableAmount = balance.MarginBalance - (balance.VmInFundSum - balance.VmOutFundSum);
}
// 是否追保/追保金额(按维度分流,定稿 2026-08-28 起均 Max(...,0) 截断、恒 ≥ 0,只追不退):
// 客户维度(==1)= Max((维持−初始) − (现金+授信−已使用), 0);
// 合约维度(==0)= 当日追加保证金现金部分合计(2026-08-28 新口径:不与现金结存轧差、闲置现金不冲抵、授信部分不追);
// 未配置(NULL 存量)维持旧口径:盯市低于维持时 = 初始保证金金额−盯市金额,否则 0
if (client?.MarginWatchRule == 1)
{
balance.MarginByPayableMarginTotal = SwapSpanBalanceCalc.CalcClientDimensionCallMargin(
balance.AmountFund, balance.TotalCredit, balance.UsedCredit, balance.SwapInitMargin, -balance.MySideMargin);
balance.NeedAddMargin = balance.MarginByPayableMarginTotal > 0;
}
else if (client?.MarginWatchRule == 0)
{
balance.MarginByPayableMarginTotal = SwapSpanBalanceCalc.CalcContractDimensionCallMargin(
todayCashAddDic.TryGetValue(data.ClientId, out var todayCashAdd) ? todayCashAdd : 0);
balance.NeedAddMargin = balance.MarginByPayableMarginTotal > 0;
}
else
{
balance.NeedAddMargin = balance.SwapMarketAmount < balance.MaintenanceMargin;
balance.MarginByPayableMarginTotal = balance.NeedAddMargin ? (balance.MySideMargin - balance.SwapMarketAmount) : 0;
}
// 可取资金(定稿 2026-08-28 分维度口径,只算现金部分——授信不可取现;min(持仓盈亏,0) 只扣浮亏、浮盈不放行):
// 合约维度(==0)= Max(现金结存 + min(持仓盈亏,0), 0)(追保已落账进现金结存,无需再叠加保证金约束);
// 客户维度(==1)= Max(现金结存 + 初始保证金 − 维持保证金 + min(持仓盈亏,0), 0)(追保不产现金流,显式叠加保证金约束);
// 未配置(NULL 存量)维持旧口径
if (client?.MarginWatchRule == 0)
{
balance.DesirableFund = SwapSpanBalanceCalc.CalcContractDimensionDesirableFund(
balance.AmountFund, balance.RoundedPositionPnl);
}
else if (client?.MarginWatchRule == 1)
{
balance.DesirableFund = SwapSpanBalanceCalc.CalcClientDimensionDesirableFund(
balance.AmountFund, balance.SwapInitMargin, -balance.MySideMargin, balance.RoundedPositionPnl);
}
else
{
balance.DesirableFund = Math.Max(balance.MarginBalance + Math.Min(balance.RoundedPositionPnl, 0), 0);
}
logger.Info($"客户资金结算:客户{client?.id}({client?.Name}){balance.ValueDate:yyyy-MM-dd} MarginWatchRule={client?.MarginWatchRule?.ToString() ?? "NULL"} 可用资金={balance.AvailableAmount:0.00} 追保金额={balance.MarginByPayableMarginTotal:0.00} 是否追保={balance.NeedAddMargin} 可取资金={balance.DesirableFund:0.00}(期末结存{balance.AmountFund:0.00} 授信{balance.TotalCredit:0.00} 已用授信{balance.UsedCredit:0.00} 互换初始{balance.SwapInitMargin:0.00} 维持{-balance.MySideMargin:0.00} 追加合计{balance.SwapAdditionalMarginTotal:0.00})");
}
}
}
//--------------------------------------------
//对出入金,权利金,结算收支,实现盈亏,抵押品变化区间段sum处理
//例如2018-08-08到2019-08-08:区间段sum值 = sum(2019-08-08) - sum(2018-08-07)
//--------------------------------------------
if (startDate <= lastBalanceDate)
{
//默认期初结存为0
foreach (var balance1 in dic.Values)
{
balance1.LastDayRemainFund = 0;
balance1.LastDayRemainFundWithProduct = 0;
balance1.LastGuaranteesTotalAmount = 0;
balance1.LastDayPositionPremiumNetCash = 0;
}
//该判断代表起始时间是选择了的,而不是空,需要区间逻辑处理
if (startDate.Year > 2008)
{
var query = from t in db.ClientBalanceDaily
where t.BalanceDate >= startDate && t.BalanceDate <= endDate
&& clientIdS.Contains(t.ClientId)
group t by t.ClientId into g
select new
{
ClientId = g.Key,
BalanceDate = g.Min(n => n.BalanceDate)
};
var startQuery = from t in db.ClientBalanceDaily
join t2 in query on new { t.ClientId, t.BalanceDate } equals new { t2.ClientId, t2.BalanceDate }
select new
{
ClientId = t.ClientId,
LastDayRemainFund = t.LastDayRemainFund ?? 0,
TodayRemianFundProduct = t.TodayRemianFundProduct ?? 0,
CashInCashOutProductChange = t.CashInCashOutProductChange ?? 0,
LastDayPositionPremiumNetCash = t.LastDayPositionPremiumNetCash ?? 0,
//此处取上一日的sum,例如sum(2018-08-07)
NetFundSum = (t.NetFundSum ?? 0) - (t.NetFund ?? 0),
InFundSum = (t.InFundSum ?? 0) - (t.InFund ?? 0),
OutFundSum = (t.OutFundSum ?? 0) - (t.OutFund ?? 0),
OtherFundSum = (t.OtherFundSum ?? 0) - (t.OtherFund ?? 0),
OptionPremiumSum = (t.OptionPremiumSum ?? 0) - (t.OptionPremium ?? 0),
OptionPremiumSwapSum = (t.OptionPremiumSwapSum ?? 0) - (t.OptionPremiumSwap ?? 0),
SettlementBalanceSum = (t.SettlementBalanceSum ?? 0) - (t.SettlementBalance ?? 0),
UnwindBalanceSum = (t.UnwindBalanceSum ?? 0) - (t.UnwindBalance ?? 0),
ExerciseBalanceSum = (t.ExerciseBalanceSum ?? 0) - (t.ExerciseBalance ?? 0),
SwapBalanceSum = (t.SwapBalanceSum ?? 0) - (t.SwapBalance ?? 0),
CouponSum = (t.CouponSum ?? 0) - (t.Coupon ?? 0),
WinLossSum = (t.WinLossSum ?? 0) - (t.WinLoss ?? 0),
CashInCashOutProductChangeSum = (t.CashInCashOutProductChange ?? 0) - (t.CashInCashOutProductChange ?? 0),
};
var startDatas = startQuery.ToArray();
foreach (var data in startDatas)
{
if (dic.TryGetValue(data.ClientId, out var balance))
{
balance.LastDayRemainFund = data.LastDayRemainFund;
balance.LastDayRemainFundWithProduct = data.LastDayRemainFund + data.TodayRemianFundProduct - data.CashInCashOutProductChange;
balance.LastGuaranteesTotalAmount = data.TodayRemianFundProduct - data.CashInCashOutProductChange;
balance.LastDayPositionPremiumNetCash = data.LastDayPositionPremiumNetCash;
//例如2018-08-08到2019-08-08:区间段sum值 = sum(2019-08-08) - sum(2018-08-07)
balance.NetFund -= data.NetFundSum;
balance.InFund -= data.InFundSum;
balance.OutFund -= data.OutFundSum;
balance.OtherFund -= data.OtherFundSum;
balance.OptionPremium -= data.OptionPremiumSum;
balance.OptionPremiumSwap -= data.OptionPremiumSwapSum;
balance.OptionPremiumAndSwapSum -= data.OptionPremiumSum + data.OptionPremiumSwapSum;
balance.SettlementBalance -= data.SettlementBalanceSum;
balance.UnwindBalance -= data.UnwindBalanceSum;
balance.ExerciseBalance -= data.ExerciseBalanceSum;
balance.SwapBalance -= data.SwapBalanceSum;
balance.Coupon -= data.CouponSum;
balance.CashInCashOutProductChange -= data.CashInCashOutProductChangeSum;
balance.WinLoss -= data.WinLossSum;
balance.WinLossSum -= balance.WinLoss;
}
}
}
}
var gapList = db.ClientBalanceGap.Where(c => clientIdS.Contains(c.ClientId) && c.ValueDate == endDate).ToList();
gapList ??= new List();
if (IsClientBalanceGap || IsGetOuterMarginGap)
{
var ClientBalanceGap = new ClientBalanceGap();
foreach (var item in dic.Values)
{
if (IsClientBalanceGap)
{
ClientBalanceGap = gapList.FirstOrDefault(c => c.ClientId == item.ClientId && c.ValueDate == endDate && !c.IsImportOuterMargin);
}
if (IsGetOuterMarginGap)
{
ClientBalanceGap = gapList.FirstOrDefault(c => c.ClientId == item.ClientId && c.ValueDate == endDate && c.IsImportOuterMargin);
}
if (ClientBalanceGap != null)
{
if (IsClientBalanceGap)
{
item.ClientBalanceGap = ClientBalanceGap;
item.IsGap = true;
item.AmountFund += ClientBalanceGap.ToDayRemainFund ?? 0;
item.AvailableAmount += (ClientBalanceGap.ToDayRemainFund ?? 0) - (ClientBalanceGap.PayableMargin ?? 0);
item.NetFund += ClientBalanceGap.NetFund ?? 0;
item.OptionPremium += ClientBalanceGap.OptionPremium ?? 0;
item.OptionPremiumSwap += ClientBalanceGap.OptionPremiumSwap ?? 0;
item.OptionPremiumAndSwapSum += ClientBalanceGap.OptionPremium ?? 0;
item.OptionPremiumAndSwapSum += ClientBalanceGap.OptionPremiumSwap ?? 0;
item.SettlementBalance += ClientBalanceGap.SettlementBalance ?? 0;
item.Coupon += ClientBalanceGap.Coupon ?? 0;
item.SwapBalance += ClientBalanceGap.SwapBalance ?? 0;
item.OtherFund += ClientBalanceGap.OtherFund ?? 0;
item.TotalCredit += ClientBalanceGap.Credit ?? 0;
//if (ClientBalanceGap.PayableFund != null && ClientBalanceGap.PayableFund != 0)
//{
// item.PayableFund += ClientBalanceGap.PayableFund ?? 0;
//}
//else
//{
// item.MarginByPayableMargin += ClientBalanceGap.MarginByPayableMargin ?? 0;
//}
item.WinLoss += ClientBalanceGap.WinLoss ?? 0;
item.PositionPnl += ClientBalanceGap.PositionPnl ?? 0;
item.RoundedPositionPnl += ClientBalanceGap.PositionPnl ?? 0;
item.PositionPv += ClientBalanceGap.PositionPv ?? 0;
item.RoundedPositionPv += ClientBalanceGap.PositionPv ?? 0;
}
if (IsGetOuterMarginGap)
{
item.ClientBalanceGap = ClientBalanceGap;
//(ClientBalanceGap.PayableMargin ?? 0)正数代表客户应付预付金
//item.PayableMargin负数代表客户应付预付金
//(ClientBalanceGap.PayableMargin ?? 0) + item.PayableMargin代表客户支付预付金的差额
item.AvailableAmount += (ClientBalanceGap.ToDayRemainFund ?? 0) - ((ClientBalanceGap.PayableMargin ?? 0) + item.PayableMargin);
item.IsGap = true;
}
}
}
}
//return dic.Values;
}
using (var clientDB = new ClientDBContext())
{
var balance1 = dic[returnClientId];
if (!clientDB.client_Axis_Fundthresholds.Where(x => x.ClientId == returnClientId).Any() || endDate == DateTime.Today)
{
balance1.FundThreshold = clientDB.client.Where(n => n.id == returnClientId).Select(n => n.FundThreshold).FirstOrDefault();
}
else
{
balance1.FundThreshold = clientDB.client_Axis_Fundthresholds.Where(x => x.ValueDate <= endDate && x.ClientId == returnClientId).OrderByDescending(x => x.ValueDate)?.FirstOrDefault()?.FundThreshold;
}
}
if (clientDataSource != null)
{
foreach (var item in dic.Values)
{
var client = clientDataSource.GetData(item.ClientId);
item.ClientNumber = client?.Number;
item.ClientName = client?.Name;
}
}
else
{
foreach (var item in dic.Values)
{
var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId);
item.ClientNumber = client?.Number;
item.ClientName = client?.Name;
}
}
if (dic.Values != null && dic.Values.Count > 0)
{
if (PS.Config.Is宏源 || PS.Config.Company == Configuration.CompanyEnum.广发商贸)
{
//宏源 二次计算预付金占用及相关数据
//var clientIds = new List();
//foreach (var item in dic.Values)
//{
// clientIds.Add(item.ClientId);
//}
var marginFactorDict = new ClientMarginTemplateService(OptUserInfo.SystemUser).GetMarginFactorDict(endDate, clientIdList, true);
dic.Values.ToList().ForEach(p => p.ReCaculatePayableMargin(p.ClientId, marginFactorDict));
}
}
//当是单一客户的时候,或者包含子级 执行新的字段返回,其他来源使用原来字段
if (ParentFlag || clientIdList.Count() == 1)
{
var DicTotal = dic[returnClientId];
#region 循环统计所有客户
foreach (var dc in dic)
{
#region 所有客户数据进行累加
if (dc.Key == returnClientId)
{
DicTotal.OptionPremiumAndUnwindBalanceTotal = DicTotal.OptionPremiumAndUnwindBalance;
DicTotal.MinusPayableMarginTotal = DicTotal.MinusPayableMargin;
DicTotal.TotalMarginTotal = DicTotal.TotalMargin;
DicTotal.RoundedTotalAmountTotal = DicTotal.RoundedTotalAmount;
DicTotal.TotalAmountTotal = DicTotal.TotalAmount;
DicTotal.MarginByPayableMarginTotal = DicTotal.MarginByPayableMarginTotal;
//if (PS.Config.Is广期资本)
//{
// DicTotal.MarginByPayableMarginTotal = Math.Max(-DicTotal.AvailableAmount, 0);
//}
DicTotal.ClosedTradePayableFundTotal = DicTotal.ClosedTradePayableFund;
DicTotal.PositionTradePayableFundTotal = DicTotal.PositionTradePayableFund;
DicTotal.PayableFundTotal = DicTotal.PayableFund;
DicTotal.DesirableFundTotal = DicTotal.DesirableFund;
DicTotal.TotalNetSettlementTotal = DicTotal.TotalNetSettlement;
DicTotal.IsLatestDate = true;
continue;
}
DicTotal.SettlementBalance += dc.Value.SettlementBalance;
DicTotal.LastDayRemainFund += dc.Value.LastDayRemainFund;
DicTotal.NetFund += dc.Value.NetFund;
DicTotal.InFund += dc.Value.InFund;
DicTotal.OutFund += dc.Value.OutFund;
DicTotal.OptionPremium += dc.Value.OptionPremium;
DicTotal.OptionPremiumSwap += dc.Value.OptionPremiumSwap;
DicTotal.OptionPremiumAndSwapSum += dc.Value.OptionPremiumAndSwapSum;
DicTotal.OtherFund += dc.Value.OtherFund;
DicTotal.Coupon += dc.Value.Coupon;
DicTotal.SwapBalance += dc.Value.SwapBalance;
DicTotal.OptionPremiumAndUnwindBalanceTotal += dc.Value.OptionPremiumAndUnwindBalance;
DicTotal.ExerciseBalance += dc.Value.ExerciseBalance;
DicTotal.AmountFund += dc.Value.AmountFund;
DicTotal.GuaranteesTotalAmount += dc.Value.GuaranteesTotalAmount;
DicTotal.MinusPayableMarginTotal += dc.Value.MinusPayableMargin;
DicTotal.AvailableAmount += dc.Value.AvailableAmount;
DicTotal.TotalMarginTotal += dc.Value.TotalMargin;
DicTotal.TotalCredit += dc.Value.TotalCredit;
DicTotal.OriginalTotalCredit += dc.Value.OriginalTotalCredit;
DicTotal.WinLoss += dc.Value.WinLoss;
DicTotal.TdWinLoss += dc.Value.TdWinLoss;
DicTotal.PositionPremiumNetCash += dc.Value.PositionPremiumNetCash;
DicTotal.RoundedPositionPv += dc.Value.RoundedPositionPv;
DicTotal.PositionPv += dc.Value.PositionPv;
DicTotal.RoundedPositionPnl += dc.Value.RoundedPositionPnl;
DicTotal.PositionPnl += dc.Value.PositionPnl;
DicTotal.RoundedTotalAmountTotal += dc.Value.RoundedTotalAmount;
DicTotal.TotalAmountTotal += dc.Value.TotalAmount;
DicTotal.MarginByPayableMarginTotal += dc.Value.MarginByPayableMarginTotal;
DicTotal.ClosedTradePayableFundTotal += dc.Value.ClosedTradePayableFund;
DicTotal.PositionTradePayableFundTotal += dc.Value.PositionTradePayableFund;
DicTotal.PayableFundTotal += dc.Value.PayableFund;
DicTotal.DesirableFundTotal += dc.Value.DesirableFund;
DicTotal.SellTradePrice += dc.Value.SellTradePrice;
DicTotal.ClientSellPositionPnl += dc.Value.ClientSellPositionPnl;
DicTotal.TotalNetSettlementTotal += dc.Value.TotalNetSettlement;
DicTotal.MarginBalance += dc.Value.MarginBalance;
DicTotal.FrozenMarginMoney += dc.Value.FrozenMarginMoney;
DicTotal.FrozenRedeemFunds += dc.Value.FrozenRedeemFunds;
//DicTotal.FundThreshold += dc.Value.FundThreshold;
#endregion
}
#endregion
}
return dic.Values;
}
///
/// 获取历史交易中追保金额不为0的客户ids(排除对系统日实时的数据的筛选)
///
///
///
public static List GetHaveMarginAmount(DateTime searchDate, string MarginShownType = "default")
{
//获取根据系统时间
var lastDate = searchDate;// EodOperationBase.GetLastSettlementDate(DateTime.Now.Date);
var clientlist = new List();
var baseQuery = new List();
using var db = new YLContext();
switch (MarginShownType)
{
case "default":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
select new Pairs
{
tdaily = t,
tgap = null
}).ToList();
break;
case "ClientBalanceGap":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
join tgap in db.ClientBalanceGap.Where(o => !o.IsImportOuterMargin && o.ValueDate == lastDate)
on new { t.ClientId, date = t.BalanceDate ?? DateTime.MinValue }
equals new { tgap.ClientId, date = tgap.ValueDate } into tempTgap
from tgap in tempTgap.DefaultIfEmpty()
select new Pairs
{
tdaily = t,
tgap = tgap
}).ToList();
break;
case "GetOuterMargin":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
join tgap in db.ClientBalanceGap.Where(o => o.IsImportOuterMargin && o.ValueDate == lastDate)
on new { t.ClientId, date = t.BalanceDate ?? DateTime.MinValue }
equals new { tgap.ClientId, date = tgap.ValueDate } into tempTgap
from tgap in tempTgap.DefaultIfEmpty()
select new Pairs
{
tdaily = t,
tgap = tgap
}).ToList();
break;
}
if (PS.Config.Is广期资本)
{
//同业客户:期末结存+持仓盈亏-冻结+授信+质押市值<0,追保
//非同业客户:期末结存 + 持仓盈亏 - 预付金占用 - 冻结 + 授信 + 质押市值 < 0,追保
if (baseQuery == null || baseQuery.Count == 0)
{
return clientlist;
}
var clientIds = baseQuery.Select(p => p.tdaily.ClientId).Distinct().ToList();
//List samePeerList = null;
Dictionary samePeerDic = null;
using (var clientDb = DbContextFactory.GetClientDbContext(null))
{
samePeerDic = clientDb.client.AsNoTracking().Where(p => clientIds.Contains(p.id)).ToDictionary(p => p.id, p => p.SamePeer);
}
samePeerDic ??= new Dictionary();
foreach (var t in baseQuery)
{
var clientId = t.tdaily.ClientId;
var clientSettleBalance = new ClientSettleBalance
{
AmountFund = t.tdaily.ToDayRemainFund ?? 0.0,
GuaranteesTotalAmount = t.tdaily.TodayRemianFundProduct ?? 0.0,
PositionPnl = t.tdaily.PositionPnl ?? 0.0,
FreezePremium = t.tdaily.FrozenPremium ?? 0.0,
FrozenOutFund = t.tdaily.FrozenOutFund ?? 0.0,
FrozenRedeemFunds = t.tdaily.FrozenRedeemFunds ?? 0.0,
FrozenMarginMoney = t.tdaily.FrozenMarginMoney ?? 0.0,
TotalCredit = t.tdaily.Credit ?? 0.0,
PayableMargin = t.tdaily.PayableMargin ?? 0.0,
PositionPremiumNetCash = t.tdaily.PositionPremiumNetCash ?? 0.0,
};
if (t.tgap != null)
{
clientSettleBalance.ClientBalanceGap = t.tgap;
clientSettleBalance.IsGap = true;
}
clientSettleBalance.SamePeer = samePeerDic.ContainsKey(clientId) ? samePeerDic[clientId] ?? 0 : 0;
if (clientSettleBalance.OtherMarginByPayableMargin < 0)
{
clientlist.Add(clientId);
}
}
}
else
{
//-PayableMargin - Math.Max(AmountFund + ClosedTradePayableFund + PositionTradePayableFund, 0) - GuaranteesTotalAmount - TotalCredit
//ClosedTradePayableFund: -1 * Math.Min(AmountFund + PositionPremiumNetCash, 0)
//PositionTradePayableFund: Math.Max(PositionPremiumNetCash - Math.Max(AmountFund + PositionPremiumNetCash, 0), 0)
foreach (var t in baseQuery)
{
var clientId = t.tdaily.ClientId;
double MarginPayableMargin = 0;
if (t.tgap != null)
{
if (t.tgap.MarginByPayableMargin != null && t.tgap.MarginByPayableMargin != 0)
{
MarginPayableMargin = -(t.tdaily.PayableMargin ?? 0.0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0), 0), 0)
- (t.tdaily.TodayRemianFundProduct ?? 0.0)
- (t.tdaily.Credit ?? 0.0)
+ (t.tgap.MarginByPayableMargin ?? 0);
}
else
{
MarginPayableMargin = -((t.tdaily.PayableMargin ?? 0.0) - (t.tgap.PayableMargin ?? 0))
- Math.Max((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0), 0), 0)
- ((t.tdaily.TodayRemianFundProduct ?? 0.0) + (t.tgap.ToDayRemainFund ?? 0))
- ((t.tdaily.Credit ?? 0.0) + (t.tgap.Credit ?? 0));
}
}
else
{
MarginPayableMargin = -(t.tdaily.PayableMargin ?? 0.0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0), 0), 0), 0)
- (t.tdaily.TodayRemianFundProduct ?? 0.0)
- (t.tdaily.Credit ?? 0.0);
}
if (MarginPayableMargin > 1e-3)
{
clientlist.Add(clientId);
}
}
}
return clientlist;
}
///
/// 获取当前客户中总资产小于1的客户ids(排除对系统日实时的数据的筛选)
///
public static List GetTotalAssetClientIds(DateTime value)
{
List result = null;
using (var db = new YLContext())
{
var tempList = db.ClientBalanceDaily.Where(O => O.BalanceDate == value).AsEnumerable();
if (PS.Config.IsPVRounded)
{
result = tempList.Where(O => (O.RoundedTotalAmount ?? 0) > 1).Select(O => O.ClientId).ToList();
}
else
{
result = tempList.Where(O => (O.TotalAmount ?? 0) > 1).Select(O => O.ClientId).ToList();
}
}
return result;
}
///
/// 获取历史交易中应付资金总额不为0的客户ids(排除对系统日实时的数据的筛选)
///
public static List GetHavePayableFund(DateTime searchDate, string MarginShownType = "default")
{
//获取根据系统时间
var lastDate = searchDate;// EodOperationBase.GetLastSettlementDate(DateTime.Now.Date);
using var db = new YLContext();
var clientlist = new List();
var baseQuery = new List();
switch (MarginShownType)
{
case "default":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
select new Pairs
{
tdaily = t,
tgap = null
}).ToList();
break;
case "ClientBalanceGap":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
join tgap in db.ClientBalanceGap.Where(o => !o.IsImportOuterMargin && o.ValueDate == lastDate)
on new { t.ClientId, date = t.BalanceDate ?? DateTime.MinValue }
equals new { tgap.ClientId, date = tgap.ValueDate } into tempTgap
from tgap in tempTgap.DefaultIfEmpty()
select new Pairs
{
tdaily = t,
tgap = tgap
}).ToList();
break;
case "GetOuterMargin":
baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == lastDate
join tgap in db.ClientBalanceGap.Where(o => o.IsImportOuterMargin && o.ValueDate == lastDate)
on new { t.ClientId, date = t.BalanceDate ?? DateTime.MinValue }
equals new { tgap.ClientId, date = tgap.ValueDate } into tempTgap
from tgap in tempTgap.DefaultIfEmpty()
select new Pairs
{
tdaily = t,
tgap = tgap
}).ToList();
break;
}
foreach (var t in baseQuery)
{
var ClientId = t.tdaily.ClientId;
double PayableFund = 0;
if (t.tgap != null)
{
if (t.tgap.PayableFund != null && t.tgap.PayableFund != 0)
{
PayableFund = Math.Max(
(-Math.Min((t.tdaily.ToDayRemainFund + t.tdaily.PositionPremiumNetCash) ?? 0, 0))
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
+ Math.Max(-(t.tdaily.PayableMargin ?? 0.0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
, 0)
- (t.tdaily.TodayRemianFundProduct ?? 0.0)
- (t.tdaily.Credit ?? 0.0), 0)
, 0)
+ (t.tgap == null ? 0 : t.tgap.PayableFund ?? 0);
}
else
{
PayableFund = Math.Max(
(-Math.Min(((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0) + t.tdaily.PositionPremiumNetCash) ?? 0, 0))
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
+ Math.Max(-((t.tdaily.PayableMargin ?? 0.0) - (t.tgap.PayableMargin ?? 0))
- Math.Max((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0) + (t.tgap.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0 + (t.tgap.ToDayRemainFund ?? 0))
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
, 0)
- (t.tdaily.TodayRemianFundProduct ?? 0.0)
- ((t.tdaily.Credit ?? 0.0) + (t.tgap.Credit ?? 0)), 0)
, 0);
}
}
else
{
PayableFund = Math.Max(
(-Math.Min((t.tdaily.ToDayRemainFund + t.tdaily.PositionPremiumNetCash) ?? 0, 0))
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
+ Math.Max(-(t.tdaily.PayableMargin ?? 0.0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
- Math.Min((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
+ Math.Max((t.tdaily.PositionPremiumNetCash ?? 0)
- Math.Max((t.tdaily.ToDayRemainFund ?? 0)
+ (t.tdaily.PositionPremiumNetCash ?? 0)
, 0)
, 0)
, 0)
- (t.tdaily.TodayRemianFundProduct ?? 0.0)
- (t.tdaily.Credit ?? 0.0), 0)
, 0);
}
if (PayableFund > 1)
{
clientlist.Add(ClientId);
}
}
return clientlist;
}
///
/// 对传入的客户进行指定日期有持仓记录的筛选(排除对系统日实时的数据的筛选)
///
public static List GetHavePositionClientIds(DateTime searchDate)
{
using var db = new YLContext();
var query = from eodpos in db.eod_trade_position
where eodpos.ValueDate == searchDate
&& eodpos.ClientId > 0
&& eodpos.TradeId > 0
select eodpos.ClientId;
return query.Distinct().ToList();
}
///
/// 进行指定日期应付了结交易款是否大于1元的筛选(排除对系统日实时的数据的筛选)
///
public static List GetClosePayableFundClientIds(DateTime searchDate, string MarginShownType = "default")
{
using var db = new YLContext();
var clientlist = new List();
var baseQuery = (from t in db.ClientBalanceDaily
where t.BalanceDate == searchDate
select t.ClientId).Distinct().ToList();
var IsGap = false;
var IsOuter = false;
if (MarginShownType == "ClientBalanceGap")
{
IsGap = true;
}
if (MarginShownType == "GetOuterMargin")
{
IsOuter = true;
}
var balances = GetClientBanlances(baseQuery, searchDate, searchDate, IsGap, IsOuter);
foreach (var item in balances)
{
if (item.ClosedTradePayableFund >= 1)
{
clientlist.Add(item.ClientId);
}
}
return clientlist;
}
///
///
///
public static IEnumerable GetClientRiskMonitor(List clientIdList, DateTime searchDate, string marginShownType)
{
if (null == clientIdList || !clientIdList.Any())
{
return null;
}
//获取根据系统时间
var lastBalanceDate = EodOperationBase.GetLastSettlementDate(DateTime.Now.Date);
//系统交易日
var valuedate = valuedateBLL.ValueDate;
using var db = new YLContext();
var IsGap = false;
var IsOuter = false;
if (marginShownType == "ClientBalanceGap")
{
IsGap = true;
}
if (marginShownType == "GetOuterMargin")
{
IsOuter = true;
}
//db.SetDebugLog();
var lastClientBalances = GetClientBanlances(clientIdList, DateTime.MinValue, searchDate, IsGap, IsOuter);
//历史查询,部分交易信息重新计算
if (valuedate <= lastBalanceDate || valuedate > searchDate)
{
//----------------------------------------
// 所有交易合计
//----------------------------------------
var allTradeQuery = from t in db.trade
where t.TradeDate <= searchDate
&& t.ValidState != "InValid"
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
&& clientIdList.Contains(t.ClientId)
&& ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)
select new
{
t.ClientId,
OriginalStockEqvNotional = t.OriginalStockEqvNotional > 0 ? t.OriginalStockEqvNotional.Value :
(t.SpotPrice ?? 0.0) * (t.OriginalNotional ?? 0),
BuyCount = t.BuySell == "买入" ? 0 : 1,//从客户角度看
SellCount = t.BuySell == "卖出" ? 0 : 1,//从客户角度看
TodayCount = t.TradeDate == searchDate ? 1 : 0
};
var allTradeQuerySum = from t in allTradeQuery
group t by t.ClientId into g
select new
{
ClientId = g.Key,
SellNotionalPrincipal = g.Sum(a => a.SellCount * a.OriginalStockEqvNotional),
BuyNotionalPrincipal = g.Sum(a => a.BuyCount * a.OriginalStockEqvNotional),
BuyCount = g.Sum(n => n.BuyCount),
SellCount = g.Sum(n => n.SellCount),
TodayCount = g.Sum(n => n.TodayCount),
TodayNotionalPrincipal = g.Sum(n => n.TodayCount * n.OriginalStockEqvNotional)
};
var tradeSumDic = allTradeQuerySum.ToDictionary(n => n.ClientId);
//----------------------------------------
// 交易结算预付金统计
//----------------------------------------
//组合交易和结构化交易获取的是父亲交易(不包含子交易)
var tradeOriginQuery = from x in db.trade
where x.ParentTradeId == 0
&& x.ValidState != ConsGlobal.InValid
select x;
var eodTradePositionQuery = from eodTradePosition in db.eod_trade_position
where eodTradePosition.ValueDate == searchDate &&
clientIdList.Contains(eodTradePosition.ClientId)
select eodTradePosition;
//组合交易和结构化交易获取的是父亲交易(不包含子交易)
var eodTradeQuery = from eodTrade in db.eod_trade
join tradeOrigin in tradeOriginQuery on eodTrade.TradeId equals tradeOrigin.id
where eodTrade.ValueDate == searchDate
&& clientIdList.Contains(eodTrade.ClientId)
&& ConsTrade.NeedMarginTradeStatusList.Contains(eodTrade.TradeStatus)
select new { eodTrade.TradeId, et = new xodTradeBase() { TradeJson = eodTrade.TradeJson } };
var positionQuery = from eodTradePosition in eodTradePositionQuery
join eodTrade in db.eod_trade on eodTradePosition.TradeId equals eodTrade.TradeId
where eodTrade.ValueDate == searchDate
&& clientIdList.Contains(eodTrade.ClientId)
&& ConsTrade.NeedMarginTradeStatusList.Contains(eodTrade.TradeStatus)
select new
{
eodTrade.TradeId,
ClientId = eodTrade.ClientId,
et = new xodTradeBase() { TradeJson = eodTrade.TradeJson },
underlyprice = eodTradePosition.UnderlyingPrice,
};
var positionQuerySum = from eodTradePosition in eodTradePositionQuery
group eodTradePosition by eodTradePosition.ClientId into g
select new
{
ClientId = g.Key,
//Margin = g.Sum(n => (n.BuySell == "买入" ? -1 : 0) * n.Margin),
//增加收益互换只计算主交易主交易限制,收益互换暂不考虑买卖反向
Margin = g.Sum(n => (((n.BuySell == "买入" && n.TradeType != "收益互换") || (n.TradeType == "收益互换" && n.ParentTradeId == 0)) ? -1 : 0) * n.Margin),
// 收益互换预付金
SwapMargin = g.Sum(n => ((n.TradeType == "收益互换" && n.ParentTradeId == 0) ? -1 : 0) * n.Margin),
// 收益互换预付金容忍金额
SwapUnMargin = g.Sum(n => ((n.TradeType == "收益互换" && n.ParentTradeId == 0) ? -1 : 0) * n.SwapUnMargin),
};
var eodTrades = eodTradeQuery.ToList().Select(o => new { o.et.trade.ClientId, o.et.trade });
var positionSumDic = positionQuerySum.ToDictionary(n => n.ClientId);
var positionDic = positionQuery.ToList();
//----------------------------------------
// 新交易统计
//----------------------------------------
var newTradeQuery = from t in db.trade
where t.TradeDate == searchDate
&& t.ValidState != "InValid"
&& (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
&& clientIdList.Contains(t.ClientId)
&& ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)
select new
{
t.id,
notionalPrincipal = t.OriginalStockEqvNotional > 0
? ((t.OriginalStockEqvNotional * t.Notional / t.OriginalNotional) ?? 0)
: (t.SpotPrice ?? 0.0) * t.Notional
};
var todayPostionQuery = from eodTradePosition in eodTradePositionQuery
join trad in newTradeQuery on eodTradePosition.TradeId equals trad.id
select new ClientBalanceEx
{
ClientId = eodTradePosition.ClientId,
UnderlyingCode = eodTradePosition.UnderlyingCode
};
var todayPostionList = todayPostionQuery.ToArray();
var todayPostionSumQuery = from t in todayPostionList
group t by t.ClientId into g
select new ClientBalanceEx
{
ClientId = g.Key
};
var todayPostionSumDic = todayPostionSumQuery.ToDictionary(n => n.ClientId);
var tradePostionMarginQuery = from eodTradePosition in eodTradePositionQuery
select new ClientBalanceEx
{
ClientId = eodTradePosition.ClientId,
BuyerPositionMargin = eodTradePosition.Margin * (eodTradePosition.BuySell == "买入" ? 1 : 0),
};
var tradePostionMarginSumQuery = from t in tradePostionMarginQuery
group t by t.ClientId into g
select new ClientBalanceEx
{
ClientId = g.Key,
BuyerPositionMargin = g.Sum(n => n.BuyerPositionMargin),
};
var tradePostionMarginSumDic = tradePostionMarginSumQuery.ToDictionary(n => n.ClientId);
//----------------------------------------
//
//----------------------------------------
foreach (var balance in lastClientBalances)
{
if (tradeSumDic.TryGetValue(balance.ClientId, out var dicItem))
{
balance.SellNotionalPrincipal = dicItem.SellNotionalPrincipal;
balance.BuyNotionalPrincipal = dicItem.BuyNotionalPrincipal;
balance.BuyCount = dicItem.BuyCount;
balance.SellCount = dicItem.SellCount;
balance.TradeCount = dicItem.TodayCount;
balance.TodayNotionalPrincipal = dicItem.TodayNotionalPrincipal;
balance.TotalNotionalPrincipal = balance.SellNotionalPrincipal + balance.BuyNotionalPrincipal;
balance.TotalTradeCount = balance.BuyCount + balance.SellCount;
}
if (positionSumDic.TryGetValue(balance.ClientId, out var dicItem2))
{
balance.TodayNewMargin = dicItem2.Margin;
}
balance.PositionCount = eodTrades.Where(x => x.ClientId == balance.ClientId).Count();
balance.SellerPositionPremium = eodTrades.Where(o => o.ClientId == balance.ClientId).Sum(o => (o.trade.TradePrice ?? 0) * (o.trade.BuySell == "买入" ? 0 : 1));
balance.PositionNotionalPrincipal = eodTrades.Where(o => o.ClientId == balance.ClientId).Sum(o => o.trade.StockEqvNotional);
if (tradePostionMarginSumDic.TryGetValue(balance.ClientId, out var dicItem4))
{
balance.BuyerPositionMargin = dicItem4.BuyerPositionMargin;
}
if (IsOuter)
{
balance.MySideMargin = balance.PayableMargin;
}
}
}
if (searchDate > lastBalanceDate)
{
//get nowTime SellerPositionPremium BuyerPositionMargin
//get postion trade
var suspensionUnderlyingIdList = DataCacheProvider.GetUnderlyingDataSource().AsQueryable()
.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
var predicate = PredicateBuilder.Create(t => t.ClientId > 0
&& ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus)
&& (t.TradeType != "结构化交易" && t.IsGroup != 1 || t.IsGroup == 1 && t.TradeType == "结构化交易")
&& (t.IsGroup != 2 || t.IsGroup == 2 && t.TradeType == "收益互换")
&& t.ValidState != ConsGlobal.InValid
&& (t.ExerciseDate >= searchDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId)));
if (clientIdList != null && clientIdList.Count() > 0)
{
predicate = predicate.And(t => clientIdList.Contains(t.ClientId));
}
var positionTradeQuery = from t in db.trade.Where(predicate)
join i in db.intraday_trade_position
on t.id equals i.TradeId
join risk in db.realtime_trade_risk.Where(tr => tr.ValueDate == searchDate && tr.VolType == "持仓") on t.id equals risk.TradeId into risks
from risk in risks.DefaultIfEmpty()
select new ClientBalanceEx
{
ClientId = t.ClientId,
SellerPositionPremium = (t.TradePrice ?? 0) * (t.BuySell == "买入" ? 0 : 1),
BuyerPositionMargin = i.Margin * (t.BuySell == "买入" ? 1 : 0),
PositionNotionalPrincipal = t.StockEqvNotional,
};
var positionTradeSumQuery = from t in positionTradeQuery
group t by t.ClientId into g
select new ClientBalanceEx
{
ClientId = g.Key,
SellerPositionPremium = g.Sum(n => n.SellerPositionPremium),
BuyerPositionMargin = g.Sum(n => n.BuyerPositionMargin),
PositionNotionalPrincipal = g.Sum(n => n.PositionNotionalPrincipal),
};
var tradePostionMarginSumDic = positionTradeSumQuery.ToDictionary(n => n.ClientId);
foreach (var balance in lastClientBalances)
{
if (tradePostionMarginSumDic.TryGetValue(balance.ClientId, out var dicItem1))
{
balance.SellerPositionPremium = dicItem1.SellerPositionPremium;
balance.BuyerPositionMargin = dicItem1.BuyerPositionMargin;
balance.PositionNotionalPrincipal = dicItem1.PositionNotionalPrincipal;
}
}
//
}
return lastClientBalances;
}
///
/// 为山西固收而写,因为GetClientBanlances已经拿了历史跟最新,不需要再判断是历史还是最新
///
///
///
///
///
public static IEnumerable GetClientRiskMonitorForShanXiGuShou(List clientIdList, DateTime searchDate, string marginShownType)
{
if (null == clientIdList || !clientIdList.Any())
{
return null;
}
//获取根据系统时间
var lastBalanceDate = EodOperationBase.GetLastSettlementDate(DateTime.Now.Date);
//系统交易日
var valuedate = valuedateBLL.ValueDate;
using var db = new YLContext();
var IsGap = false;
var IsOuter = false;
if (marginShownType == "ClientBalanceGap")
{
IsGap = true;
}
if (marginShownType == "GetOuterMargin")
{
IsOuter = true;
}
var lastClientBalances = GetClientBanlances(clientIdList, DateTime.MinValue, searchDate, IsGap, IsOuter);
if (valuedate <= lastBalanceDate || valuedate > searchDate)
{
//----------------------------------------
// 所有交易合计
//----------------------------------------
var allTradeQuery = from t in db.trade
where t.TradeDate <= searchDate
&& t.ValidState != "InValid"
&& t.TradeType == "收益互换"
&& clientIdList.Contains(t.ClientId)
&& ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)
select new
{
t.id,
t.ClientId,
OriginalStockEqvNotional = t.OriginalStockEqvNotional > 0 ? t.OriginalStockEqvNotional.Value :
(t.SpotPrice ?? 0.0) * (t.OriginalNotional ?? 0),
BuyCount = t.BuySell == "买入" ? 0 : 1,//从客户角度看
SellCount = t.BuySell == "卖出" ? 0 : 1,//从客户角度看
TodayCount = t.TradeDate == searchDate ? 1 : 0
};
var allTradeQuerySum = from t in allTradeQuery
group t by t.ClientId into g
select new
{
ClientId = g.Key,
SellNotionalPrincipal = g.Sum(a => a.SellCount * a.OriginalStockEqvNotional),
BuyNotionalPrincipal = g.Sum(a => a.BuyCount * a.OriginalStockEqvNotional),
BuyCount = g.Sum(n => n.BuyCount),
SellCount = g.Sum(n => n.SellCount),
TodayCount = g.Sum(n => n.TodayCount),
TodayNotionalPrincipal = g.Sum(n => n.TodayCount * n.OriginalStockEqvNotional)
};
var tradeSumDic = allTradeQuerySum.ToDictionary(n => n.ClientId);
var tradePosiQuery = from t in allTradeQuery
join p in db.eod_swap_position on t.id equals p.SwapTradeId
where !p.Invalid
select new
{
t.id,
t.ClientId,
p
};
foreach (var balance in lastClientBalances)
{
if (tradeSumDic.TryGetValue(balance.ClientId, out var dicItem))
{
balance.SellNotionalPrincipal = dicItem.SellNotionalPrincipal;
balance.BuyNotionalPrincipal = dicItem.BuyNotionalPrincipal;
balance.BuyCount = dicItem.BuyCount;
balance.SellCount = dicItem.SellCount;
balance.TradeCount = dicItem.TodayCount;
balance.TodayNotionalPrincipal = dicItem.TodayNotionalPrincipal;
balance.TotalNotionalPrincipal = balance.SellNotionalPrincipal + balance.BuyNotionalPrincipal;
balance.TotalTradeCount = balance.BuyCount + balance.SellCount;
}
var clientTradePosiQuery = tradePosiQuery.Where(x => x.ClientId == balance.ClientId && x.p.PosiQuantity > 0 && x.p.ValueDate == searchDate);
balance.PositionCount = clientTradePosiQuery.Select(s => s.id).Distinct().Count();
//var PosiNotionalValue = clientTradePosiQuery.Sum(o => o.p.PosiNotionalValue);
//balance.PositionNotionalPrincipal = Convert.ToDouble(PosiNotionalValue);
}
}
return lastClientBalances;
}
public static void FillClientBalanceHisTradeFee()
{
var clients = DataCacheProvider.GetClientDataSource().AsQueryable().Where(x => x.ProcessStatus == "已开户").ToList();
using var db = new YLContext();
var firstEodStatusDate = db.eodStatus.OrderBy(o => o.ValueDate).FirstOrDefault();
if (firstEodStatusDate != null)
{
var firstDate = firstEodStatusDate.ValueDate;
var preBalanceDate = valuedateBLL.GetNonHolidayDefore(valuedateBLL.ValueDate.AddDays(-1));
while (firstDate < valuedateBLL.ValueDate)
{
foreach (var client in clients)
{
var interestPnl = 0d;
var tradeFee = 0d;
var clientBalance = db.ClientBalanceDaily.FirstOrDefault(x => x.ClientId == client.id && x.BalanceDate == firstDate);
var clientBalancePre = db.ClientBalanceDaily.FirstOrDefault(x => x.ClientId == client.id && x.BalanceDate == preBalanceDate);
if (clientBalance != null)
{
// 互换平仓信息
var clientEventFlowQuery = from eod in db.swap_flow_event.Where(x => x.EventDate <= firstDate && x.EventDate > preBalanceDate && x.ClientId == client.id && x.DataState == (int)SwapFlowDateStateEnum.完成 && x.EventType == (int)SwapFlowEventTypeEnum.平仓)
join t in db.trade.Where(x => x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid) on eod.SwapTradeId equals t.id
select eod;
var clientEodSwaps = clientEventFlowQuery.ToList();
foreach (var item in clientEodSwaps.GroupBy(x => x.SwapTradeId))
{
var eventPosis = item.Where(t => t.PayDirection > 0).ToList();
var eventInterests = item.Where(t => t.PayDirection == 0).ToList();
interestPnl += Convert.ToDouble(eventInterests.Sum(s => s.InterestClosePnL)) * (-1);
tradeFee += Convert.ToDouble(eventPosis.Sum(s => s.TradingFee + s.TradingFeePending)) * (-1);
}
clientBalance.trade_fee = tradeFee;
clientBalance.interest_pnl = interestPnl;
clientBalance.trade_fee_sum = clientBalance.trade_fee;
clientBalance.interest_pnl_sum = clientBalance.interest_pnl;
if (clientBalancePre != null)
{
clientBalance.trade_fee_sum += clientBalancePre.trade_fee_sum;
clientBalance.interest_pnl_sum += clientBalancePre.interest_pnl_sum;
}
db.SaveChanges();
}
}
preBalanceDate = firstDate;
firstDate = valuedateBLL.GetNonHoliday(firstDate.AddDays(1));
}
}
}
///
/// 获取预付金率设置
///
///
///
///
private static client_marginrate GetClientMarginRate(int clientId, List clientMarginTemplates)
{
var marinRate = clientMarginTemplates.Where(x => x.ClientId == clientId).FirstOrDefault();
if (marinRate == null)
{
marinRate = clientMarginTemplates.Where(x => x.ClientId == 0).FirstOrDefault();
}
if (marinRate == null)
{
marinRate = new client_marginrate
{
InitMarginRate = 1,
MaintenanceRate = 1,
};
}
return marinRate;
}
class ClientBalanceEx : ClientSettleBalance
{
public string UnderlyingCode { get; set; }
}
class Pairs
{
public ClientBalanceDaily tdaily { get; set; }
public ClientBalanceGap tgap { get; set; }
}
///
/// 获取所有子客户id
///
public static List GetSubclientId(int id)
{
return InnerGetSubclientId(id, new HashSet());
}
private static List InnerGetSubclientId(int id, HashSet checkSet)
{
checkSet ??= new HashSet();
if (!checkSet.Add(id))
{
checkSet.Clear();
var pid = id;
var list = new List();
for (var i = 0; i < 100; i++)
{
if (pid <= 0 || !checkSet.Add(pid)) break;
var client = DataCacheProvider.GetClientDataSource().GetData(pid);
if (client == null)
{
break;
}
else
{
list.Add(client.Name);
pid = client.ParentId;
}
}
if (list.Count > 0)
{
list.Add(list[0]);
}
throw new ServiceFaultException("客户父子关系产生了循环依赖:" + string.Join("->", list));
}
var result = new List() { id };
var clientIdList = DataCacheProvider.GetClientDataSource().AsQueryable(O => O.ParentId == id).Select(O => O.id).ToList();
foreach (var c in clientIdList)
{
result.AddRange(InnerGetSubclientId(c, checkSet));
}
return result;
}
public static List queryClientRiskMonitor(ClientRiskMonitorReq req)
{
if (!req.SearchDate.HasValue)
{
req.SearchDate = valuedateBLL.ValueDate;
}
if (string.IsNullOrWhiteSpace(req.marginShownType))
{
req.marginShownType = "default";
}
if (req.ClientIds == null || req.ClientIds.Count <= 0)
{
var clientService = new ClientQueryService(OptUserInfo.SystemUser);
var predicate = clientService.CreatePredicate(new ClientReq() { ValueDate = req.SearchDate });
req.ClientIds = clientService.GetClientListByWhere(predicate).Select(o => o.id).Distinct().ToList();
}
var result = ClientBalanceUtility.GetClientRiskMonitorForShanXiGuShou(req.ClientIds, req.SearchDate.Value, req.marginShownType);
if (result == null)
{
return new List();
}
var roundFunc = new Func(O => Math.Round(O, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero));
//精简字段
var resultList = result.Select(item => new ClientBalanceView
{
ValueDate = req.SearchDate.Value,
Number = item.ClientNumber ?? "",
Name = item.ClientName ?? "",
TotalTradeCount = item.TotalTradeCount,
TotalNotionalPrincipal = roundFunc(item.TotalNotionalPrincipal),
TransactionPenNumber = item.TradeCount,
TodayNotionalPrincipal = roundFunc(item.TodayNotionalPrincipal),
PositionNotionalPrincipal = roundFunc(item.PositionNotionalPrincipal),
CurrentHoldingPenNumber = item.PositionCount,
WinLoss = roundFunc(item.WinLoss),
PositionPnl = roundFunc(item.PositionPnl),
RoundedPositionPnl = roundFunc(item.RoundedPositionPnl),
LastDayRemainFund = roundFunc(item.LastDayRemainFund),
NetFundAll = roundFunc(item.NetFundAll),
NetFund = roundFunc(item.NetFund),
VmFundSum = roundFunc(item.VmFundSum),
OtherFund = roundFunc(item.OtherFund),
AmountFund = roundFunc(item.AmountFund),
//初始/维持保证金金额与每日估值报告同口径(SettlementReportService 账户状况块):
//初始=应付预付金流水净额(SwapInitMargin),维持=−MySideMargin(client_span 反号聚合)
MySideMargin = roundFunc(item.SwapInitMargin),
MaintenanceMargin = roundFunc(-item.MySideMargin),
SwapMarketAmount = roundFunc(item.SwapMarketAmount),
SwapMarketAmountPercent = item.SwapMarketAmountPercent,
AvailableAmount = roundFunc(item.AvailableAmount),
InsuredAmount = roundFunc(item.MarginByPayableMarginTotal),
DesirableFund = roundFunc(item.DesirableFund),
TradeFee = roundFunc(item.TradeFee),
InterestPnl = roundFunc(item.InterestPnl),
Updatetime = DateTime.Now
}).ToList();
return resultList;
}
///
/// 保存客户资金监控结果, 用于浙商数据采集
///
///
public static void saveClientRiskMonitor(DateTime valueDate)
{
LogFactory.GetLogger("saveClientRiskMonitor").Info($"开始执行 {valueDate:yyyy-MM-dd} 数据落库操作");
var req = new ClientRiskMonitorReq
{
SearchDate = valueDate
};
var list = queryClientRiskMonitor(req);
if (list.Count == 0)
{
LogFactory.GetLogger("saveClientRiskMonitor").Info($"{valueDate:yyyy-MM-dd} 记录数为0,跳过落库");
}
using (var db = new YLContext())
{
db.BulkDelete($"ValueDate='{valueDate:yyyy-MM-dd}'");
db.clientBalanceView.AddRange(list);
db.SaveChanges();
}
LogFactory.GetLogger("saveClientRiskMonitor").Info($"{valueDate:yyyy-MM-dd} 记录数为{list.Count},落库完成");
}
public class ClientRiskMonitorReq
{
public List ClientIds { get; set; }
public DateTime? SearchDate { get; set; }
public string marginShownType { get; set; }
}
}
}