标的交易&风控

This commit is contained in:
吴方海
2025-04-25 15:50:51 +08:00
parent 428938cb6f
commit fe4b431faf
8 changed files with 60 additions and 97 deletions
+9 -10
View File
@@ -594,16 +594,6 @@ namespace YLErp.BLL.Eod
}
}
clientPosition.update_user = 0;
if (clientPosition.id == 0 && clientPosition.position_qty > 0)
{
clientPosition.update_time = DateTime.Now;
bondDb.client_position.Add(clientPosition);
}
else if (clientPosition.id > 0 && (clientPosition.position_qty > 0 || clientPosition.today_profit_loss != 0))
{
clientPosition.update_time = DateTime.Now;
}
bondDb.SaveChanges();
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;
@@ -613,6 +603,15 @@ namespace YLErp.BLL.Eod
{
BondCalcApi(clientPosition);
}
if (clientPosition.id == 0 && clientPosition.position_qty > 0)
{
clientPosition.update_time = DateTime.Now;
bondDb.client_position.Add(clientPosition);
}
else if (clientPosition.id > 0 && (clientPosition.position_qty > 0 || clientPosition.today_profit_loss != 0))
{
clientPosition.update_time = DateTime.Now;
}
bondDb.SaveChanges();
}
var sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
@@ -20,51 +20,28 @@ namespace YLErp.Modules.ExchangeTradeModule
public void ResetExchangeTradePosition()
{
var valueDate = SystemValueDate;
var lastDate = EodOperationBase.GetLastSettlementDate(valueDate, false);
List<string> tradetypes = new List<string> { "股票", "商品期货", "商品现货", "场内期权", "利率债", "信用债", "其它债券" };
var eodQuery = from et in DbContext.eod_trade_position.AsNoTracking()
where et.ValueDate == lastDate && tradetypes.Contains(et.TradeType)
select new TradePositionEx
{
UnderlyingId = et.UnderlyingId,
TradeType = et.TradeType,
BookId = et.BookId,
InstrumentCode = et.ExchangeOptionCode,
UnderlyingCode = et.UnderlyingCode,
Position = et.Amount,
PositionCost = et.Cost,
BuySell = et.PositionType
};
var positionList = eodQuery.ToList();
//如果当天未收盘
if (valueDate != lastDate)
{
var tdQuery = from trad in DbContext.ExchangeTrade.AsNoTracking()
where trad.TradeDate > lastDate && trad.TradeDate <= valueDate && trad.IsValid
select new TdTradePositionEx
{
TradeType = trad.TradeType,
BookId = trad.AssetBookId,
InstrumentCode = trad.OptionCode,
Position = trad.Notional,
BuySell = trad.TradeSide,
UnderlyingCode = trad.UnderlyingCode,
TradeSinglePrice = trad.TradeSinglePrice
};
var tdDatas = tdQuery.ToArray();
positionList.AddRange(tdDatas);
}
var tdQuery = from trad in DbContext.ExchangeTrade.AsNoTracking()
where trad.IsValid
select new TdTradePositionEx
{
TradeType = trad.TradeType,
BookId = trad.AssetBookId,
InstrumentCode = trad.OptionCode,
Position = trad.Notional,
BuySell = trad.TradeSide,
UnderlyingCode = trad.UnderlyingCode,
TradeSinglePrice = trad.TradeSinglePrice
};
var positionList = tdQuery.ToList();
var dic = new Dictionary<string, TradePosition>(positionList.Count);
foreach (var n in positionList)
{
var tradeType1 = TradeHelper.GetTradeType1(n.TradeType);
var positionType = TradeHelper.GetPositionType(n.BuySell);
var key = $"{n.BookId}^{(int)tradeType1}^{(int)positionType}^{n.UnderlyingCode}^{n.InstrumentCode}";
var key = $"{n.BookId}^{(int)tradeType1}^{n.UnderlyingCode}^{n.InstrumentCode}";
var position = n.IsEod ? n.Position : TradeHelper.GetPositionNotional(n.BuySell, n.Position);
var positionCost = n.IsEod ? n.PositionCost : position * n.TradeSinglePrice;
@@ -136,7 +136,7 @@ namespace YLErp.Modules.ExchangeTradeModule
para.positionType = TradeHelper.GetPositionType(para.tradeSide);
var predicate = PredicateBuilder.Create<TradePosition>(n => n.BookId == td.AssetBookId
&& n.TradeType1 == para.tradeType1 && n.PositionType == para.positionType && n.UnderlyingCode == td.UnderlyingCode);
&& n.TradeType1 == para.tradeType1 && n.UnderlyingCode == td.UnderlyingCode);
if (td.TradeType == "场内期权")
{
@@ -901,6 +901,7 @@ namespace YLErp.Modules.RiskModule
{
return;
}
obj.DeltaExposure= dict[obj.BusinessType].Sum(O => O.risk.Delta.Normalize());
obj.DeltaCash = dict[obj.BusinessType].Sum(O => O.risk.DeltaCash.Normalize());
obj.Vega = dict[obj.BusinessType].Sum(O => O.risk.Vega.Normalize());
obj.VegaCash = dict[obj.BusinessType].Sum(O => O.risk.VegaCash.Normalize());
@@ -1015,41 +1016,30 @@ namespace YLErp.Modules.RiskModule
setValue(swap, swapSetting);
var positionList = new List<KeyValuePair<trade, realtime_trade_risk>>();
var gloabPnl = GetTradePositionPnl();
var underly = GetTradePositionPnl();
if (dict.ContainsKey("互换"))
{
var swapPositionList = dict["互换"].Select(O => new KeyValuePair<trade, realtime_trade_risk>(O.t, O.risk));
swap.TotalPnL = swapPositionList.Sum(O => O.Value.PositionPnl.Normalize());
if (PS.Config.Is国信金阳)
{
swap.PositionPnl = swapPositionList.Sum(O => O.Value.PositionPnl.Normalize() < 0 ? O.Value.PositionPnl.Normalize() : 0);
}
else
{
swap.PositionPnl = swapPositionList.Sum(O => O.Value.PositionPnl.Normalize());
}
swap.PositionPnl = swapPositionList.Sum(O => O.Value.PositionPnl.Normalize());
positionList.AddRange(swapPositionList);
}
swap.DeltaNetExposure = double.NaN;
var checkPosiList = GetCheckPosiList();
var posiStockEqvNotional = checkPosiList.Sum(s => s.Pv);
var underly = new QuotaMonitor_Global()
{
ParentKey = "场外",
BusinessType = "标的交易",
PositionPnl = gloabPnl
};
var delta = checkPosiList.Sum(s => s.Delta);
var unTrade = new QuotaMonitor_Global()
{
ParentKey = "场外",
BusinessType = "未簿记合约",
StockEqvNotional = Convert.ToDouble(posiStockEqvNotional) - swap.StockEqvNotional.Normalize()
StockEqvNotional = Convert.ToDouble(posiStockEqvNotional) - swap.StockEqvNotional.Normalize(),
DeltaExposure=(double)delta- (swap.DeltaExposure??0)
};
var all = new QuotaMonitor_Global()
{
BusinessType = "全局",
StockEqvNotional = Convert.ToDouble(posiStockEqvNotional),
PositionPnl = underly.PositionPnl + swap.PositionPnl
PositionPnl = underly.PositionPnl + swap.PositionPnl,
DeltaExposure=(double)delta+ underly.DeltaExposure
};
var list = new List<QuotaMonitor_Global>
{
@@ -4364,7 +4354,7 @@ namespace YLErp.Modules.RiskModule
checkQuotaMoitorModel.Commision = item.commission ?? 0;
checkQuotaMoitorModel.Direction = item.direction;
checkQuotaMoitorModel.ClientId = Convert.ToInt32(item.client_id ?? 0);
checkQuotaMoitorModel.Delta = (checkQuotaMoitorModel.Side == 0 ? checkQuotaMoitorModel.Price : -checkQuotaMoitorModel.Price) * checkQuotaMoitorModel.Qty;
checkQuotaMoitorModel.Delta = (checkQuotaMoitorModel.Side == 0 ? 1 : -1) * checkQuotaMoitorModel.Qty;
EodPrice bondPrice = null;
if (eodPriceDic.ContainsKey(checkQuotaMoitorModel.UnderlyingCode))
{
@@ -4990,9 +4980,16 @@ namespace YLErp.Modules.RiskModule
/// 算标的交易盈亏
/// </summary>
/// <returns></returns>
private double GetTradePositionPnl()
private QuotaMonitor_Global GetTradePositionPnl()
{
double currentValue = 0;
QuotaMonitor_Global quotaMonitor_Global = new QuotaMonitor_Global()
{
ParentKey= "场外",
BusinessType = "标的交易",
PositionPnl=0,
DeltaExposure=0,
StockEqvNotional=0
};
List<string> tradetypes = new List<string> { "利率债", "信用债", "其它债券" };
var tposis = DbContext.TradePosition.Where(x => tradetypes.Contains(x.TradeType)).AsNoTracking().ToList();
var umCodes = tposis.Select(x => x.UnderlyingCode).Distinct().ToList();
@@ -5015,9 +5012,12 @@ namespace YLErp.Modules.RiskModule
lastPrice = bondPrice != null ? bondPrice.ClosePrice : (um.Price ?? 0) * Convert.ToDouble(ConsGlobal.bondPriceMultiple);
}
}
currentValue += lastPrice * item.Position - item.PositionCost;
quotaMonitor_Global.PositionPnl += lastPrice * item.Position - item.PositionCost;
quotaMonitor_Global.StockEqvNotional += item.PositionCost;
quotaMonitor_Global.DeltaExposure += (item.PositionType == PositionTypeFlag.Long ? -1 : 1) * item.Position;
}
return currentValue;
return quotaMonitor_Global;
}
private List<string> checkGlobal(List<CheckQuotaMoitorModel> positionList, List<CheckQuotaMoitorModel> posiList, string tag_prefix, QuotaSetting[] settings, bool warning)
{
@@ -46,13 +46,6 @@
<span class="search-label">交易类型</span>
<select name="TradeType">
<option value="">全部</option>
@if (!pageObj.IsGuoJun)
{
<option value="场内期权">场内期权</option>
}
<option value="股票">股票</option>
<option value="商品期货">商品期货</option>
<option value="商品现货">商品现货</option>
<option value="信用债">信用债</option>
<option value="利率债">利率债</option>
<option value="其它债券">其它债券</option>
+3 -16
View File
@@ -39,28 +39,15 @@
<div class="form-group">
<label class="formlabel" for="TradeType">交易类型</label>
<select class="" name="TradeType" id="TradeType">
@if (Model.TradeType == "场内期权")
{
<option value="场内期权">场内期权</option>
}
else
{
<option value="股票">股票</option>
<option value="商品期货">期货</option>
<option value="商品现货">商品现货</option>
<option value="信用债">信用债</option>
<option value="利率债">利率债</option>
<option value="其它债券">其它债券</option>
}
<option value="信用债">信用债</option>
<option value="利率债">利率债</option>
<option value="其它债券">其它债券</option>
</select>
</div>
<div class="form-group asset-type" style="display:none">
<label class="formlabel">标的资产类型</label>
<select class="" name="InstrumentType" id="InstrumentType">
<option value="CommodityFutures">商品期货</option>
<option value="CommoditySpot">商品现货</option>
<option value="Stock">股票</option>
<option value="信用债">信用债</option>
<option value="利率债">利率债</option>
<option value="其它债券">其它债券</option>
@@ -41,9 +41,6 @@
<span class="search-label">交易类型</span>
<select name="TradeType">
<option value="">全部</option>
<option value="股票">股票</option>
<option value="商品期货">商品期货</option>
<option value="商品现货">商品现货</option>
<option value="信用债">信用债</option>
<option value="利率债">利率债</option>
<option value="其它债券">其它债券</option>
@@ -1660,6 +1660,16 @@ var colModel_global = [
}
return "style='" + style + "'";
}
} , {
name: 'DeltaExposure',
label: 'Delta',
index: 'DeltaExposure',
width: 120,
align: 'right',
sortable: false,
formatter: function (cellvalue, options, rowObject) {
return !cellvalue || cellvalue == "NaN" ? "" : cellvalue;
}
}
];