计算指标可配置

This commit is contained in:
yexuzhong
2026-07-31 14:49:52 +08:00
parent f7e7aaa373
commit 633cd7d32d
8 changed files with 112 additions and 11 deletions
@@ -1,4 +1,4 @@
using MoreLinq;
using MoreLinq;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -248,7 +248,14 @@ namespace YLErp.Modules.CalcPriceShowConfigModule
new CalcQuotaDto{Name="Vegacash",Tip=""},
new CalcQuotaDto{Name="PV*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"},
new CalcQuotaDto{Name="Delta*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"},
new CalcQuotaDto{Name="Gamma*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"}
new CalcQuotaDto{Name="Gamma*",Tip="*号标记的字段是所有涉及到敲出的期权结构,若当天为该期权的观察日,当盘中实时价格越过敲出价时,该笔结构的估值只包含Payoff,不需要再包含时间价值,同时该笔交易的Delta手数和Gamma手数都变成0\r\n\r\n系统默认在盘中的时候期权价值=内在价值+时间价值"},
new CalcQuotaDto{Name="Delta_r",Tip=""},
new CalcQuotaDto{Name="Delta_r(1bp)",Tip=""},
new CalcQuotaDto{Name="Dv01",Tip=""},
new CalcQuotaDto{Name="Gamma_r",Tip=""},
new CalcQuotaDto{Name="Gamma_r(1bp)",Tip=""},
new CalcQuotaDto{Name="Vega_r",Tip=""},
new CalcQuotaDto{Name="Vega_r(1bp)",Tip=""},
};
}
@@ -1,4 +1,4 @@
using Qdp.Pricing.Base.Interfaces;
using Qdp.Pricing.Base.Interfaces;
namespace YLErp.Modules.CalculationModule
{
@@ -495,6 +495,26 @@ namespace YLErp.Modules.CalculationModule
/// Theta(轧差)
/// </summary>
public double ThetaNet { get; set; }
/// <summary>
/// Delta_R
/// </summary>
public double? Delta_r { get; set; }
public double? Delta_r_1bp { get; set; }
public double? Dv01 { get; set; }
public double? Gamma_r { get; set; }
public double? Gamma_r_1bp { get; set; }
public double? Vega_r { get; set; }
public double? Vega_r_1bp { get; set; }
}
public class TradeValueResultExtend
@@ -472,7 +472,7 @@ namespace YLErp.Modules.EodModule
r.DeltaLots = (r.Delta ?? 0) / um.ContractSize;
}
r.Rho *= 100;
greeksHandleService.Handle(r);
greeksHandleService.Handle(r,um);
if (r.trade == null)
{
r.TradeSinglePrice = r.etcTradePrice / r.TradeAmount;
@@ -1206,7 +1206,7 @@ namespace YLErp.Modules.EodModule
}
r.Rho *= 100;
greeksHandleService.Handle(r);
greeksHandleService.Handle(r,um);
r.CountRatio = um.CountRatio;
r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio;
r.etcTradePrice = ConsTrade.TradeTypesForHedge.Contains(r.TradeType)
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YLErp.Model;
using YLErp.Modules.CalculationModule;
namespace YLErp.Modules.EodModule
{
@@ -19,10 +20,22 @@ namespace YLErp.Modules.EodModule
}
public void Handle(EodPositionRisksDTO dto)
public void Handle(EodPositionRisksDTO dto,underlying_manager um)
{
//对Delta_r Delta_r_1bp Dv01 Gamma_r Gamma_r_1bp Vega_r Vega_r_1bp
if ("GB10".Equals(um.UnderlyingCode))
{
dto.Delta_r = dto.Delta * -1;
}
}
public void Handle(trade td,TradeValueResult calRes)
{
calRes.Delta_r = calRes.Delta * -1;
}
}
}
@@ -1,4 +1,4 @@
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Base.Implementations;
using System.Text.RegularExpressions;
using YLErp.BLL;
using YLErp.BLL.Calculation.V2;
@@ -11,6 +11,7 @@ using YLErp.Enums;
using YLErp.Model;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.EodModule;
using YLErp.Modules.PricingModule.Models;
using YLErp.Modules.TradeModule;
using YLErp.QdpModule;
@@ -500,7 +501,7 @@ namespace YLErp.Modules.PricingModule
}
}
}
var greeksHandleService = new GLMSGreeksHandleService();
foreach (var item in tdList)
{
var td = item.tdConv;
@@ -529,6 +530,9 @@ namespace YLErp.Modules.PricingModule
}
}
greeksHandleService.Handle(td, calcResult);
results.Add(new CalcOptionPriceResult
{
BuySell = td.BuySell,
+1
View File
@@ -7,6 +7,7 @@
<FunctionSub Name="波动率审核编辑" Type="Operate" Title="波动率审核"></FunctionSub>
<FunctionSub Name="利率曲线" Title="利率曲线"></FunctionSub>
<FunctionSub Name="基差曲线" Title="基差曲线"></FunctionSub>
<FunctionSub Name="定价计算指标显示设置" Type="Operate" Title="定价计算指标显示设置"></FunctionSub>
</FunctionParent>
<FunctionParent Name="交易管理" Title="交易管理">
<FunctionSub Name="交易搜索" Title="期权交易"></FunctionSub>
+50 -1
View File
@@ -1,4 +1,4 @@
@using YLErp.Modules.CalcPriceShowConfigModule
@using YLErp.Modules.CalcPriceShowConfigModule
@*定价模板*@
@model PricingModel
@{
@@ -1199,6 +1199,55 @@
<td>{{calcResult.GammaContainsKnockOut}}</td>
</tr>
}
else if ("Delta_r".Equals(quta.Name))
{
<tr>
<th title="Delta*">Delta_r</th>
<td>{{calcResult.Delta_r}}</td>
</tr>
}
else if ("Delta_r(1bp)".Equals(quta.Name))
{
<tr>
<th title="Delta*">Delta_r(1bp)</th>
<td>{{calcResult.Delta_r_1bp}}</td>
</tr>
}
else if ("Dv01".Equals(quta.Name))
{
<tr>
<th title="Delta*">Dv01</th>
<td>{{calcResult.Dv01}}</td>
</tr>
}
else if ("Gamma_r".Equals(quta.Name))
{
<tr>
<th title="Delta*">Gamma_r</th>
<td>{{calcResult.Gamma_r}}</td>
</tr>
}
else if ("Gamma_r(1bp)".Equals(quta.Name))
{
<tr>
<th title="Delta*">Gamma_r(1bp)</th>
<td>{{calcResult.Gamma_r_1bp}}</td>
</tr>
}
else if ("Vega_r".Equals(quta.Name))
{
<tr>
<th title="Delta*">Vega_r</th>
<td>{{calcResult.Vega_r}}</td>
</tr>
}
else if ("Vega_r(1bp)".Equals(quta.Name))
{
<tr>
<th title="Delta*">Vega_r(1bp)</th>
<td>{{calcResult.Vega_r_1bp}}</td>
</tr>
}
}
}
@@ -1,4 +1,4 @@
//客户选择组件
const vueClient = function () {
return {
@@ -214,7 +214,7 @@ const vueMarginTemplateName = function () {
}
//计算结果字段
const consCalcFields = Object.freeze(['TotalMargin', 'Pv', 'Delta', 'Gamma', 'Vega', 'Theta', 'Rho', 'PvContainsKnockOut', 'DeltaContainsKnockOut', 'DeltaInLots', 'GammaInLots', 'DeltaCash', 'GammaCash', 'VegaCash', 'GammaContainsKnockOut']);
const consCalcFields = Object.freeze(['TotalMargin', 'Pv', 'Delta', 'Gamma', 'Vega', 'Theta', 'Rho', 'PvContainsKnockOut', 'DeltaContainsKnockOut', 'DeltaInLots', 'GammaInLots', 'DeltaCash', 'GammaCash', 'VegaCash', 'GammaContainsKnockOut', 'Delta_r', 'Delta_r_1bp', 'Dv01', 'Gamma_r', 'Gamma_r_1bp', 'Vega_r', 'Vega_r_1bp']);
var _trades, _tradeVues, _salesCommissionCtrl;
//交易保存
@@ -1913,6 +1913,13 @@ function createVue(index, baseVue, floating) {
calcResult.PvContainsKnockOut = pricingFormat.tradePrice(result.PvContainsKnockOut);
calcResult.DeltaContainsKnockOut = pricingFormat.greek(result.DeltaContainsKnockOut);
calcResult.GammaContainsKnockOut = pricingFormat.greek(result.GammaContainsKnockOut);
calcResult.Delta_r = result.Delta_r ? pricingFormat.greek(result.Delta_r) : "";
calcResult.Delta_r_1bp = result.Delta_r_1bp ? pricingFormat.greek(result.Delta_r_1bp) : "";
calcResult.Dv01 = result.Dv01 ? pricingFormat.greek(result.Dv01) : "";
calcResult.Gamma_r = result.Gamma_r ? pricingFormat.greek(result.Gamma_r) : "";
calcResult.Gamma_r_1bp = result.Gamma_r_1bp ? pricingFormat.greek(result.Gamma_r_1bp) : "";
calcResult.Vega_r = result.Vega_r ? pricingFormat.greek(result.Vega_r) : "";
calcResult.Vega_r_1bp = result.Vega_r_1bp ? pricingFormat.greek(result.Vega_r_1bp) : "";
calcResult.TotalMargin = 0;
if (data === this.datas[this.datas.length - 1]) {
calcResult.TotalMargin = pageVue.GetTotalMargin(_.map(this.datas, x => x.trade), this.structureType);