保证金算法&资金计算

This commit is contained in:
吴方海
2025-04-16 15:15:59 +08:00
parent 6e644083df
commit 8e61f23e18
47 changed files with 695 additions and 1194 deletions
@@ -4096,6 +4096,11 @@ namespace YLErp.Modules.RiskModule
{
throw new ServiceException("未找到客户信息");
}
var dealDate = DateTime.Parse(clientRiskCheckReq.dealDate);
if (client.EvaluateExpireDate< dealDate)
{
throw new ServiceException("适当性评估已经过期,只有在适当性有效期内才可以新开仓");
}
using var bondDb = new BondOmsDBContext();
var (clientPositions, clientOrderPositions) = GetClientPositionsAndOrders(bondDb, clientRiskCheckReq.orderId);
var position = clientPositions
@@ -4106,7 +4111,7 @@ namespace YLErp.Modules.RiskModule
AddClientRiskCheckPosition(clientRiskCheckReq, clientPositions);
var umCodes = GetUnderlyingCodes(clientPositions, clientRiskCheckReq.securityId);
var ums = GetUnderlyings(umCodes);
var dealDate = DateTime.Parse(clientRiskCheckReq.dealDate);
var checkPoisiList = BuildCheckQuotaMoitorModels(clientPositions, ums, dealDate);
foreach (var settingItem in precheckQuotaSettingList)
{
@@ -4150,15 +4155,14 @@ namespace YLErp.Modules.RiskModule
}
private (List<ClientPosition>, List<ClientOrder>) GetClientPositionsAndOrders(BondOmsDBContext bondDb, long orderId)
{
var clientLongIds = DataCacheProvider.GetClientDataSource()
.AsQueryable()
.Where(s => s.BusinessUseType == "否")
.Select(s => (long)s.id)
.ToList();
var clientPositions = bondDb.client_position.Where(x => clientLongIds.Contains(x.client_id ?? 0)).AsNoTracking().ToList();
var clientPositions = bondDb.client_position.AsNoTracking().ToList();
var startDate = DateTime.Now.Date;
var nextDate = startDate.AddDays(1);
var clientOrderPositions = bondDb.client_order.Where(x => x.status == 0 && x.create_time > startDate && x.create_time < nextDate && x.id != orderId).AsNoTracking().ToList();
clientPositions.ForEach(x =>
{
x.position_qty *= 10000;
});
return (clientPositions, clientOrderPositions);
}
/// <summary>
@@ -4170,29 +4174,48 @@ namespace YLErp.Modules.RiskModule
/// <returns></returns>
private List<QuotaSetting> FilterPrecheckQuotaSettings(List<QuotaSetting> precheckQuotaSettingList, ClientRiskCheckItemParam clientRiskCheckReq)
{
// 过滤出与当前客户端相关的配额设置
var clientPrecheckQuotaSettingList = precheckQuotaSettingList
.Where(x => x.QuotaRange == clientRiskCheckReq.clientId && x.QuotaType == QuotaTypeEnum.CLIENT)
.ToList();
// 过滤出所有客户端通用的配额设置
var allClientPrecheckQuotaSettingList = precheckQuotaSettingList
.Where(x => x.QuotaRange == 0 && x.QuotaType == QuotaTypeEnum.CLIENT)
.ToList();
// 获取底层数据源
var clientId = clientRiskCheckReq.clientId;
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(clientRiskCheckReq.securityId);
var noneClientAllUnderlyingPrecheckQuotaSettingList = precheckQuotaSettingList
.Where(x => x.QuotaType == QuotaTypeEnum.UNDERLYING)
.ToList();
// 处理客户端相关的配额设置
if (clientPrecheckQuotaSettingList.Count > 0)
{
precheckQuotaSettingList = precheckQuotaSettingList
.Except(allClientPrecheckQuotaSettingList)
.ToList();
}
return precheckQuotaSettingList;
var underlyingId = um?.id;
// 分离三种类型数据
var clientQuotas = precheckQuotaSettingList.Where(x => x.QuotaType == QuotaTypeEnum.CLIENT);
var underlyingQuotas = precheckQuotaSettingList.Where(x => x.QuotaType == QuotaTypeEnum.UNDERLYING);
var otherQuotas = precheckQuotaSettingList.Where(x =>
x.QuotaType != QuotaTypeEnum.CLIENT &&
x.QuotaType != QuotaTypeEnum.UNDERLYING
);
// 1. CLIENT类型处理(按QuotaIndex分组+三层优先级)
var filteredClient = clientQuotas
.GroupBy(x => x.QuotaIndex)
.SelectMany(g => {
// 优先级1: QuotaRange=clientId
var p1 = g.Where(x => x.QuotaRange == clientId);
if (p1.Any()) return p1;
// 优先级2: QuotaRange=0
return g.Where(x => x.QuotaRange == 0);
})
.ToList();
// 2. UNDERLYING类型分层筛选
var filteredUnderlying = underlyingQuotas
.GroupBy(x => x.QuotaIndex)
.SelectMany(g => {
// 优先级1: QuotaRange=underlyingId
var p1 = g.Where(x => x.QuotaRange == underlyingId);
if (p1.Any()) return p1;
// 优先级2: QuotaRange=0
return g.Where(x => x.QuotaRange == 0);
}).ToList();
// 3. 合并所有类型(保留其他类型原样)
return filteredClient
.Concat(filteredUnderlying)
.Concat(otherQuotas)
.ToList();
}
/// <summary>
/// 构建风控指标类
@@ -4234,8 +4257,8 @@ namespace YLErp.Modules.RiskModule
full_price_now = item.full_price,
deal_full_price_avg = item.full_price ?? 0,
client_id = item.client_id,
position_qty = item.order_qty,
position_notional_principal = item.full_price * item.order_qty* ConsGlobal.bondPriceMultiple,
position_qty = item.order_qty*10000,
position_notional_principal = item.full_price * item.order_qty* ConsGlobal.bondPriceMultiple * 10000,
direction = (int)SwapDirectionEnum.,
id = item.id,
Current = false,
@@ -4259,11 +4282,11 @@ namespace YLErp.Modules.RiskModule
deal_full_price_avg = clientRiskCheckReq.price * ConsGlobal.bondShowPriceMultiple,
client_id = clientRiskCheckReq.clientId,
position_qty = clientRiskCheckReq.qty,
position_notional_principal = clientRiskCheckReq.amount,
direction = (int)SwapDirectionEnum.,
id = clientRiskCheckReq.orderId,
Current = true,
};
posi.position_notional_principal = posi.position_qty * posi.deal_full_price_avg* ConsGlobal.bondPriceMultiple;
clientPositions.Add(posi);
}
/// <summary>
@@ -5296,6 +5319,7 @@ namespace YLErp.Modules.RiskModule
switch (checkItem.quotaType)
{
case "轧差名义本金":
currentValue = Math.Abs(Convert.ToDouble(currentPv));
if (!ValidateQuoteResult(checkItem, currentValue, posiVal))
{
return checkItem;