fix: 实时持仓计算持仓盈亏
This commit is contained in:
@@ -510,7 +510,7 @@ namespace YLErp.BLL.Eod
|
||||
&& t.TradeType == "收益互换").ToList();
|
||||
//OTC持仓交易
|
||||
var tradeIdList = tradeList.Select(t => t.id).ToList();
|
||||
var positions = db.swap_position.Where(x => tradeIdList.Contains(x.SwapTradeId) && !x.IsInitial && x.PosiQuantity > 0&&!x.Invalid).ToList();
|
||||
var positions = db.swap_position.Where(x => tradeIdList.Contains(x.SwapTradeId) && !x.IsInitial && x.PosiQuantity > 0 && !x.Invalid).ToList();
|
||||
var swapFlows = db.swap_flow.Where(x => x.DataState == (int)SwapFlowDateStateEnum.等待完成).ToList();
|
||||
using var bondDb = new BondOmsDBContext();
|
||||
var clientPositions = bondDb.client_position.AsEnumerable();
|
||||
@@ -533,18 +533,18 @@ namespace YLErp.BLL.Eod
|
||||
td,
|
||||
p
|
||||
};
|
||||
var positionGroup = query.AsEnumerable().GroupBy(x => new { x.p.UnderlyingCode, x.td.ClientId,x.p.PosiDirection});
|
||||
var positionGroup = query.AsEnumerable().GroupBy(x => new { x.p.UnderlyingCode, x.td.ClientId, x.p.PosiDirection });
|
||||
var dealSwapFlowIds = new List<long>();
|
||||
SwapTradeAutoService swapTradeAutoService = new SwapTradeAutoService(optUser);
|
||||
var datenow = DateTime.Now;
|
||||
foreach (var pair in positionGroup)
|
||||
{
|
||||
var client = DataCacheProvider.GetClientDataSource().GetData(pair.Key.ClientId);
|
||||
if (client == null||string.IsNullOrEmpty(pair.Key.UnderlyingCode))
|
||||
if (client == null || string.IsNullOrEmpty(pair.Key.UnderlyingCode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var clientPosition = clientPositions.FirstOrDefault(x => x.client_id == pair.Key.ClientId && x.security_id == pair.Key.UnderlyingCode&&x.direction== pair.Key.PosiDirection);
|
||||
var clientPosition = clientPositions.FirstOrDefault(x => x.client_id == pair.Key.ClientId && x.security_id == pair.Key.UnderlyingCode && x.direction == pair.Key.PosiDirection);
|
||||
var trades = pair.Select(s => s.td).ToList();
|
||||
var tradeIds = trades.Select(x => x.id);
|
||||
var positionGroupItems = positions.Where(x => tradeIds.Contains(x.SwapTradeId) && x.UnderlyingCode == pair.Key.UnderlyingCode && x.PosiDirection == pair.Key.PosiDirection);
|
||||
@@ -563,15 +563,17 @@ namespace YLErp.BLL.Eod
|
||||
var multiplier = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType) ? ConsGlobal.bondShowPriceMultiple : 1;
|
||||
|
||||
// 计算加权平均价格(区分债券和非债券)
|
||||
var weightedPrice = posiQty==0?0: positionGroupItems
|
||||
.Sum(s => {
|
||||
var weightedPrice = posiQty == 0 ? 0 : positionGroupItems
|
||||
.Sum(s =>
|
||||
{
|
||||
decimal price = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType)
|
||||
? s.PosiGrossPrice * ConsGlobal.bondShowPriceMultiple
|
||||
: s.PosiGrossPrice;
|
||||
return s.PosiQuantity * price;
|
||||
}) / posiQty;
|
||||
var weightedNetPrice = posiQty==0?0: positionGroupItems
|
||||
.Sum(s => {
|
||||
var weightedNetPrice = posiQty == 0 ? 0 : positionGroupItems
|
||||
.Sum(s =>
|
||||
{
|
||||
decimal price = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType)
|
||||
? s.PosiNetPrice * ConsGlobal.bondShowPriceMultiple
|
||||
: s.PosiNetPrice;
|
||||
@@ -584,7 +586,7 @@ namespace YLErp.BLL.Eod
|
||||
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(pair.Key.UnderlyingCode);
|
||||
clientPosition = CreateClientPosition(clientPosition, pair.Key.ClientId, pair.Key.UnderlyingCode, netPrice, price, posiQty / 10000, comminsions, positionType == PositionTypeFlag.Long ? 0 : 1, lastPosi.ContractSize, pair.Key.PosiDirection);
|
||||
clientPosition.position_notional_principal = totalNotional;
|
||||
if (pair.Key.PosiDirection==(int)SwapDirectionEnum.支付)
|
||||
if (pair.Key.PosiDirection == (int)SwapDirectionEnum.支付)
|
||||
{
|
||||
var flowMerges = MergeSwapFlow(newSwapFlows, multiplier);
|
||||
dealSwapFlowIds.AddRange(newSwapFlows.Select(s => s.id));
|
||||
@@ -596,7 +598,7 @@ namespace YLErp.BLL.Eod
|
||||
clientPosition.update_user = 0;
|
||||
SetClientPositionPrice(clientPosition);
|
||||
clientPosition.swap_market_value = clientPosition.full_price_now * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1);
|
||||
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1) - clientPosition.commission;
|
||||
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * 0.01m * (clientPosition.position_qty * 10000) * (clientPosition.side == 0 ? 1 : -1) - clientPosition.commission;
|
||||
clientPosition.position_profit_loss = Math.Round(clientPosition.position_profit_loss ?? 0, 2, MidpointRounding.AwayFromZero);
|
||||
clientPosition.today_profit_loss = clientPosition.swap_market_value - lastPv;
|
||||
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)//发kafka 获取成交收益率
|
||||
@@ -629,7 +631,7 @@ namespace YLErp.BLL.Eod
|
||||
continue;
|
||||
}
|
||||
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlowGroup.Key.UnderlyingCode);
|
||||
var multiplier = um!=null&& um.IsBond() ? ConsGlobal.bondShowPriceMultiple : 1;
|
||||
var multiplier = um != null && um.IsBond() ? ConsGlobal.bondShowPriceMultiple : 1;
|
||||
var flowMerges = MergeSwapFlow(swapFlowGroup.ToList(), multiplier);
|
||||
var flowMergeMax = flowMerges.OrderByDescending(s => s.TradingQty).First();
|
||||
var flowMergeMin = flowMerges.FirstOrDefault(x => x.BsType != flowMergeMax.BsType);
|
||||
@@ -665,7 +667,7 @@ namespace YLErp.BLL.Eod
|
||||
bondDb.SaveChanges();
|
||||
}
|
||||
}
|
||||
sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
|
||||
sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
|
||||
bondDb.BulkDelete<ClientPosition>(sql);
|
||||
bondDb.SaveChanges();
|
||||
#endregion
|
||||
@@ -741,10 +743,10 @@ namespace YLErp.BLL.Eod
|
||||
private static void BondCalcApi(ClientPosition clientPosition)
|
||||
{
|
||||
var resp = BondCalcHepler.BondCalc(clientPosition.security_id, clientPosition.deal_full_price_avg ?? 0, "DP");
|
||||
if (resp!=null)
|
||||
if (resp != null)
|
||||
{
|
||||
clientPosition.deal_yield_avg = resp.ytm* ConsGlobal.bondPriceMultiple;
|
||||
_yLCache.StringSetWithNoPrefix<CalBondResult>("TRS-BondFullPrice:" + clientPosition.security_id, resp,TimeSpan.FromHours(1));
|
||||
clientPosition.deal_yield_avg = resp.ytm * ConsGlobal.bondPriceMultiple;
|
||||
_yLCache.StringSetWithNoPrefix<CalBondResult>("TRS-BondFullPrice:" + clientPosition.security_id, resp, TimeSpan.FromHours(1));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -759,7 +761,7 @@ namespace YLErp.BLL.Eod
|
||||
/// <param name="comminsion"></param>
|
||||
/// <param name="side"></param>
|
||||
/// <returns></returns>
|
||||
private static ClientPosition CreateClientPosition(ClientPosition clientPosition, int clientId, string underlyingCode, decimal price, decimal fullPrice, decimal qty, decimal comminsion, int side,decimal contractsize,int direction)
|
||||
private static ClientPosition CreateClientPosition(ClientPosition clientPosition, int clientId, string underlyingCode, decimal price, decimal fullPrice, decimal qty, decimal comminsion, int side, decimal contractsize, int direction)
|
||||
{
|
||||
var underlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode)?.UnderlyingName;
|
||||
var client = DataCacheProvider.GetClientDataSource().GetData(clientId);
|
||||
@@ -781,7 +783,7 @@ namespace YLErp.BLL.Eod
|
||||
clientPosition.side = side;
|
||||
clientPosition.create_time = DateTime.Now;
|
||||
clientPosition.client_user_id = 0;
|
||||
clientPosition.position_notional_principal = fullPrice* qty * 10000 * contractsize * ConsGlobal.bondPriceMultiple;
|
||||
clientPosition.position_notional_principal = fullPrice * qty * 10000 * contractsize * ConsGlobal.bondPriceMultiple;
|
||||
clientPosition.direction = direction;
|
||||
return clientPosition;
|
||||
}
|
||||
@@ -865,7 +867,7 @@ namespace YLErp.BLL.Eod
|
||||
clientPosition.deal_full_price_avg = priceResult.Item1;
|
||||
}
|
||||
clientPosition.commission = flowMerges.Sum(s => s.TradingFee);
|
||||
clientPosition.position_qty = Math.Abs(allPosiQty/10000);
|
||||
clientPosition.position_qty = Math.Abs(allPosiQty / 10000);
|
||||
clientPosition.position_notional_principal = Math.Abs(allPosiQty) * clientPosition.deal_full_price_avg * ConsGlobal.bondPriceMultiple;
|
||||
if (allPosiQty < 0)
|
||||
{
|
||||
@@ -881,7 +883,7 @@ namespace YLErp.BLL.Eod
|
||||
return (clientPosition.deal_full_price_avg ?? 0, clientPosition.deal_price_avg ?? 0);
|
||||
}
|
||||
var sameAmount = flowMergeSame.TradingAmountAvg * flowMergeSame.TradingQty;
|
||||
var sameNetAmount = (flowMergeSame.TradingAmountNetAvg??0) * flowMergeSame.TradingQty;
|
||||
var sameNetAmount = (flowMergeSame.TradingAmountNetAvg ?? 0) * flowMergeSame.TradingQty;
|
||||
var totalQty = (clientPosition.position_qty ?? 0) + flowMergeSame.TradingQty;
|
||||
if (totalQty == 0)
|
||||
{
|
||||
@@ -1052,7 +1054,7 @@ namespace YLErp.BLL.Eod
|
||||
//根据TradeId,VolType,ValueDate更新已经存在的数据
|
||||
var tradeids = resultRisks.Select(t => t.TradeId).ToList();
|
||||
var tradeRisks = db.realtime_trade_risk.Where(x => tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
|
||||
var delTradeRisks= db.realtime_trade_risk.Where(x => !tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
|
||||
var delTradeRisks = db.realtime_trade_risk.Where(x => !tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
|
||||
db.realtime_trade_risk.RemoveRange(delTradeRisks);
|
||||
for (var i = 0; i < tradeRisks.Count; i++)
|
||||
{
|
||||
@@ -2388,7 +2390,7 @@ namespace YLErp.BLL.Eod
|
||||
|
||||
public static ClientBalanceForTrsResponse GetClientBalance(int clientId)
|
||||
{
|
||||
if (_yLCache!=null)
|
||||
if (_yLCache != null)
|
||||
{
|
||||
return _yLCache.StringGet<ClientBalanceForTrsResponse>("ClientBalance:" + clientId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user