namespace YLErp.Modules.EodModule
{
///
/// 客户冻结资金计算服务
///
class ClientFrozenFundsService : YLBaseService
{
Dictionary _dic;
public ClientFrozenFundsService(OptUserInfo userInfo) : base(userInfo)
{
}
public ClientFrozenFundsService(YLBaseService baseService) : base(baseService)
{
}
///
/// 客户冻结资金计算
///
public Dictionary GetDatas(DateTime valueDate, IEnumerable clientIds)
{
_dic = new Dictionary();
if (clientIds == null || !clientIds.Any())
{
return _dic;
}
foreach (var id in clientIds)
{
_dic[id] = new ClientFrozenFunds();
}
//用户所有未确认出金信息
// ProcessClientCashInCashOut(valueDate);
//用户所有赎回申请抵押品
ProcessClientCashInOutProduct(valueDate);
//持仓未到权利金支付日的交易--权利金
ProcessTrade(valueDate);
return _dic;
}
//用户所有未确认出金信息
private void ProcessClientCashInCashOut(DateTime valueDate)
{
var clientIds = _dic.Keys;
var valueDateNext = valueDate.AddDays(1);
var clientCashInOutSum = from t in DbContext.ClientCashInCashOut
where t.HappenDate < valueDateNext
&& clientIds.Contains(t.ClientId.Value)
&& t.ValidState != "InValid" && t.Money != null
&& t.Direction == "出金" && t.State == "未确认"
group t by t.ClientId into g
select new
{
clientId = g.Key.Value,
//冻结出金
OutFunds = g.Sum(n => n.Money.Value)
};
var sumDatas = clientCashInOutSum.ToArray();
foreach (var data in sumDatas)
{
_dic[data.clientId].OutFunds = data.OutFunds;
}
}
//用户所有赎回申请抵押品
private void ProcessClientCashInOutProduct(DateTime valueDate)
{
var clientIds = _dic.Keys;
//抵押品冻结(这段代码逻辑的问题是使用了实时行情,抵押品用处不大暂时不改了)
var clientCashInOutProductQuery = from product in DbContext.clientcashincashout_product
join um in DbContext.underlying_manager on product.UnderlyingId equals um.id
where product.BackDate <= valueDate
&& clientIds.Contains(product.ClientId)
&& product.Status == "赎回" && product.OptStatus == "未确认"
select new
{
ClientId = product.ClientId,
//抵押品冻结
RedeemFunds = (product.ProductAmount ?? 0) * (product.Rate ?? 0) * (um.Price ?? 0)
};
var clientCashInOutProductSum = from t in clientCashInOutProductQuery
group t by t.ClientId into g
select new
{
clientId = g.Key,
RedeemFunds = g.Sum(n => n.RedeemFunds)
};
var sumDatas = clientCashInOutProductSum.ToArray();
foreach (var data in sumDatas)
{
_dic[data.clientId].RedeemFunds = data.RedeemFunds;
}
}
//持仓未到权利金支付日的交易--权利金
private void ProcessTrade(DateTime valueDate)
{
var clientIds = _dic.Keys;
//获取处于停牌状态股票信息
var suspensionUnderlyingIdList = DbContext.underlying_manager
.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToArray();
//持仓未到权利金支付日的交易
var tQuery = from t in DbContext.trade
where t.TradeDate <= valueDate
&& clientIds.Contains(t.ClientId)
&& t.PremiumPayDate > valueDate
&& t.ValidState != "InValid"
&& t.ParentTradeId == 0
&& (ConsTrade.LiveTradeStatusList.Contains(t.TradeStatus) || (ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus) && t.UnWindDate > valueDate))
&& (
(t.TradeDate == valueDate && ConsTrade.TradeTypesForHedge.Contains(t.TradeType)) ||
!ConsTrade.TradeTypesForHedge.Contains(t.TradeType) && (t.ExerciseDate >= valueDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId))
)
group t by t.ClientId into g
select new
{
clientId = g.Key,
//当前持仓并且未到支付日的卖出交易(客户为买入,渠道为卖出)则为冻结的权利金
FrozenPayableOptionMoney = g.Sum(t => t.BuySell == "卖出" ? (t.TradePrice ?? 0) : 0),
//应收存续权利金
FrozenReceivableOptionMoney = g.Sum(t => t.BuySell == "买入" ? (t.TradePrice ?? 0) : 0),
};
var sumDatas = tQuery.ToArray();
foreach (var data in sumDatas)
{
var item = _dic[data.clientId];
item.FrozenPayableOptionMoney += data.FrozenPayableOptionMoney;
item.FrozenReceivableOptionMoney = data.FrozenReceivableOptionMoney;
}
}
}
///
/// 客户冻结资金对象
///
public class ClientFrozenFunds
{
///
/// 出金
///
public double OutFunds { get; set; }
///
/// 抵押品赎回
///
public double RedeemFunds { get; set; }
///
/// 冻结应收权利金
///
public double FrozenReceivableOptionMoney { get; set; }
///
/// 冻结应付权利金
///
public double FrozenPayableOptionMoney { get; set; }
///
/// 冻结预付金(绝对值)
///
public double FrozenMarginMoney { get; set; }
}
}