Merge branch 'glms/feature/1.4.2' into glms/feature/dotnumber
This commit is contained in:
@@ -1,10 +1,19 @@
|
||||
using Dapper;
|
||||
using Org.BouncyCastle.Asn1.Mozilla;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using Qdp.Foundation.Implementations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YLErp.Abstract.DataProviders;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Model;
|
||||
using YLErp.Modules.CalculationModule;
|
||||
using YLErp.Modules.DataProviderModule;
|
||||
using YLErp.Modules.MarketRiskMoudule.Dto;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
@@ -13,29 +22,363 @@ namespace YLErp.Modules.EodModule
|
||||
/// </summary>
|
||||
public class GLMSGreeksHandleService
|
||||
{
|
||||
private readonly List<string> calcInstrumentTypes = new List<string>() { ConsGlobal.InstrumentType.TBonds, ConsGlobal.InstrumentType.CreditBonds, ConsGlobal.InstrumentType.OtherBonds,
|
||||
ConsGlobal.InstrumentType.RateYield,ConsGlobal.InstrumentType.BondIndex,ConsGlobal.InstrumentType.TBFutures };
|
||||
|
||||
private readonly List<string> instrumentBondsTypes = new List<string>() { ConsGlobal.InstrumentType.TBonds, ConsGlobal.InstrumentType.CreditBonds, ConsGlobal.InstrumentType.OtherBonds };
|
||||
|
||||
Dictionary<string, double?> _pDic = new Dictionary<string, double?>();
|
||||
Dictionary<string, double?> _dDic = new Dictionary<string, double?>();
|
||||
Dictionary<string, double?> _cDic = new Dictionary<string, double?>();
|
||||
Dictionary<string, double?> _ytmDic = new Dictionary<string, double?>();
|
||||
Dictionary<string, double?> _cfDic = new Dictionary<string, double?>();
|
||||
//期货对应的债券代码
|
||||
Dictionary<string, string> _TFeaturesBondCodeDic = new Dictionary<string, string>();
|
||||
|
||||
|
||||
public void InitData(DateTime valueDate,List<string> underlyingCodes)
|
||||
{
|
||||
var umDatas = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().Where(p => underlyingCodes.Contains(p.UnderlyingCode) && calcInstrumentTypes.Contains(p.UnderlyingInstrumentType)).ToList();
|
||||
if (umDatas == null || umDatas.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var eodPriceProvier = new EodPriceProvider(valueDate);
|
||||
eodPriceProvier.Initialize(underlyingCodes);
|
||||
underlyingCodes.ForEach(e => {
|
||||
_pDic.Add(e, eodPriceProvier.GetPrice(e, SettlementTypeEnum.ClosePrice));
|
||||
});
|
||||
using var db = DbContextFactory.GetYLDbContext();
|
||||
var conn = db.Database.GetDbConnection();
|
||||
var bondsUmCodes = umDatas.Where(p => instrumentBondsTypes.Contains(p.UnderlyingInstrumentType)).Select(p => p.UnderlyingCode).Distinct().ToList();
|
||||
if (bondsUmCodes == null)
|
||||
{
|
||||
bondsUmCodes = new List<string>();
|
||||
}
|
||||
|
||||
var bondIndexUmInnerCodes = umDatas.Where(p => ConsGlobal.InstrumentType.BondIndex.Equals(p.UnderlyingInstrumentType)).Select(p => p.InnerCode??0).Distinct().ToList();
|
||||
if (bondIndexUmInnerCodes != null && bondIndexUmInnerCodes.Count > 0)
|
||||
{
|
||||
var querySql = "SELECT InnerCode,Duration1,Convexity1,YTM FROM bond_chinabondindexquote WHERE TradingDay = @ValueDate AND InnerCode IN @InnerCodes";
|
||||
|
||||
var bondIndexQuoteDatas = conn.Query<ChinaBondIndexQuoteQueryDto>(querySql, new
|
||||
{
|
||||
ValueDate = valueDate,
|
||||
InnerCodes = bondIndexUmInnerCodes
|
||||
}, commandTimeout: 1800).ToList();
|
||||
|
||||
if (bondIndexQuoteDatas != null && bondIndexQuoteDatas.Count > 0)
|
||||
{
|
||||
foreach (var item in bondIndexQuoteDatas)
|
||||
{
|
||||
var umCode = umDatas.First(d => d.InnerCode == item.InnerCode).UnderlyingCode;
|
||||
_dDic.Add(umCode, item.Duration1 != null ? (double)item.Duration1 : null);
|
||||
_cDic.Add(umCode, item.Convexity1 != null ? (double)item.Convexity1 : null);
|
||||
_ytmDic.Add(umCode, item.YTM != null ? (double)item.YTM : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bondFeatureUmCodes = umDatas.Where(p => ConsGlobal.InstrumentType.TBFutures.Equals(p.UnderlyingInstrumentType)).Select(p => p.UnderlyingCode).Distinct().ToList();
|
||||
if (bondFeatureUmCodes != null && bondFeatureUmCodes.Count > 0)
|
||||
{
|
||||
var tFeatureBondInnerCodeDic = GetTFeatureBondInnerCode(bondFeatureUmCodes, valueDate, conn);
|
||||
if (tFeatureBondInnerCodeDic != null && tFeatureBondInnerCodeDic.Count > 0)
|
||||
{
|
||||
var contractInnerCodeBondInnerCodeDic = new Dictionary<long, long>();
|
||||
foreach (var item in tFeatureBondInnerCodeDic)
|
||||
{
|
||||
var bondUm = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().FirstOrDefault(p => p.InnerCode == item.Value);
|
||||
if (bondUm != null)
|
||||
{
|
||||
_TFeaturesBondCodeDic.Add(item.Key, bondUm.UnderlyingCode);
|
||||
bondsUmCodes.Add(bondUm.UnderlyingCode);
|
||||
}
|
||||
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.Key);
|
||||
if (um.InnerCode != null)
|
||||
{
|
||||
contractInnerCodeBondInnerCodeDic.Add(um.InnerCode ?? 0, item.Value);
|
||||
}
|
||||
}
|
||||
if (contractInnerCodeBondInnerCodeDic.Count > 0)
|
||||
{
|
||||
var cfDatas = GetCFDatas(contractInnerCodeBondInnerCodeDic, conn);
|
||||
if (cfDatas != null && cfDatas.Count > 0)
|
||||
{
|
||||
foreach (var item in cfDatas)
|
||||
{
|
||||
var um = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().FirstOrDefault(p => p.InnerCode == item.Key);
|
||||
if (um != null)
|
||||
{
|
||||
_cfDic.Add(um.UnderlyingCode, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bondsUmCodes != null && bondsUmCodes.Count > 0)
|
||||
{
|
||||
bondsUmCodes = bondsUmCodes.Distinct().ToList();
|
||||
var datas = db.china_bond_valuation.AsNoTracking().Where(p => p.valuation_date == valueDate && bondsUmCodes.Contains(p.bond_id)).Select(p => new
|
||||
{
|
||||
p.bond_id,
|
||||
p.modi_dura,
|
||||
p.convexity,
|
||||
p.yield
|
||||
}).ToList();
|
||||
if (datas != null && datas.Count > 0)
|
||||
{
|
||||
foreach (var item in datas)
|
||||
{
|
||||
_dDic.Add(item.bond_id, item.modi_dura != null ? (double)item.modi_dura : null);
|
||||
_cDic.Add(item.bond_id, item.convexity != null ? (double)item.convexity : null);
|
||||
_ytmDic.Add(item.bond_id, item.yield != null ? (double)item.yield : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
var calcDto = new GreeksCalcDto
|
||||
{
|
||||
dto.Delta_r = dto.Delta * -1;
|
||||
Delta = dto.Delta,
|
||||
Gamma = dto.Gamma,
|
||||
Vega = dto.Vega,
|
||||
};
|
||||
handle(calcDto, um);
|
||||
dto.Delta_r = calcDto.Delta_r;
|
||||
dto.Gamma_r = calcDto.Gamma_r;
|
||||
dto.Vega_r = calcDto.Vega_r;
|
||||
dto.Delta_r_1bp = calcDto.Delta_r_1bp;
|
||||
dto.Dv01 = calcDto.Dv01;
|
||||
dto.Gamma_r_1bp = calcDto.Gamma_r_1bp;
|
||||
dto.Vega_r_1bp = calcDto.Vega_r_1bp;
|
||||
}
|
||||
|
||||
|
||||
public void Handle(trade td,TradeValueResult calRes, underlying_manager um)
|
||||
{
|
||||
var calcDto = new GreeksCalcDto
|
||||
{
|
||||
Delta = calRes.Delta,
|
||||
Gamma = calRes.Gamma,
|
||||
Vega = calRes.Vega,
|
||||
};
|
||||
handle(calcDto, um);
|
||||
calRes.Delta_r = calcDto.Delta_r;
|
||||
calRes.Gamma_r = calcDto.Gamma_r;
|
||||
calRes.Vega_r = calcDto.Vega_r;
|
||||
calRes.Delta_r_1bp = calcDto.Delta_r_1bp;
|
||||
calRes.Dv01 = calcDto.Dv01;
|
||||
calRes.Gamma_r_1bp = calcDto.Gamma_r_1bp;
|
||||
calRes.Vega_r_1bp = calcDto.Vega_r_1bp;
|
||||
}
|
||||
|
||||
|
||||
private Dictionary<string,long> GetTFeatureBondInnerCode(List<string> underlyingCodes,DateTime valueDate,DbConnection conn)
|
||||
{
|
||||
var sql = "SELECT contractcode,deliverableinnercode,spread FROM fut_cgbderiv WHERE TradingDay = @ValueDate AND pricetype = 3 AND (contractcode,irr) IN (SELECT contractcode,MAX(irr) FROM fut_cgbderiv WHERE TradingDay = @ValueDate AND contractcode IN (@UmCodes) AND pricetype = 3 GROUP BY contractcode);";
|
||||
var datas = conn.Query<TFeatureBondInnerCodeQueryDto>(sql, new
|
||||
{
|
||||
ValueDate = valueDate,
|
||||
UmCodes = underlyingCodes
|
||||
}, commandTimeout: 1800).ToList();
|
||||
var res = new Dictionary<string,long>();
|
||||
if (datas != null && datas.Count > 0)
|
||||
{
|
||||
res = datas.GroupBy(p => p.contractcode).ToDictionary(p => p.Key, p => p.OrderBy(d => d.spread).First().deliverableinnercode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private GLMSGreeksCalcArgs GetCalcArgs(string underlyingCode, string underlyingInstrumentType)
|
||||
{
|
||||
var res = new GLMSGreeksCalcArgs();
|
||||
if (ConsGlobal.InstrumentType.RateYield.Equals(underlyingInstrumentType))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (ConsGlobal.InstrumentType.TBFutures.Equals(underlyingInstrumentType))
|
||||
{
|
||||
var bondUnderlyingCode = _TFeaturesBondCodeDic.GetValueOrDefault(underlyingCode, null);
|
||||
if (!string.IsNullOrEmpty(bondUnderlyingCode))
|
||||
{
|
||||
res.P = _pDic.GetValueOrDefault(bondUnderlyingCode, null);
|
||||
res.D = _dDic.GetValueOrDefault(bondUnderlyingCode, null);
|
||||
res.C = _cDic.GetValueOrDefault(bondUnderlyingCode, null);
|
||||
res.Ytm = _ytmDic.GetValueOrDefault(bondUnderlyingCode, null);
|
||||
}
|
||||
res.CF = _cfDic.GetValueOrDefault(underlyingCode, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
res.P = _pDic.GetValueOrDefault(underlyingCode, null);
|
||||
res.D = _dDic.GetValueOrDefault(underlyingCode, null);
|
||||
res.C = _cDic.GetValueOrDefault(underlyingCode, null);
|
||||
res.Ytm = _ytmDic.GetValueOrDefault(underlyingCode, null);
|
||||
}
|
||||
//
|
||||
return res;
|
||||
}
|
||||
|
||||
private Dictionary<long, double?> GetCFDatas(Dictionary<long, long> contractInnerCodeBondInnerCodeDic, DbConnection conn)
|
||||
{
|
||||
|
||||
if (contractInnerCodeBondInnerCodeDic == null || contractInnerCodeBondInnerCodeDic.Count == 0)
|
||||
return new Dictionary<long, double?>();
|
||||
|
||||
var parameters = new DynamicParameters();
|
||||
var tupleList = new List<string>();
|
||||
int idx = 0;
|
||||
foreach (var kvp in contractInnerCodeBondInnerCodeDic)
|
||||
{
|
||||
var cp = $"@C{idx}";
|
||||
var bp = $"@B{idx}";
|
||||
tupleList.Add($"({cp},{bp})");
|
||||
parameters.Add(cp, kvp.Key);
|
||||
parameters.Add(bp, kvp.Value);
|
||||
idx++;
|
||||
}
|
||||
|
||||
var sql = $@"SELECT infopubldate, contractinnercode, ibmarketinnercode, conversionfactors
|
||||
FROM fut_conversionfactors
|
||||
WHERE (contractinnercode, ibmarketinnercode) IN ({string.Join(",", tupleList)})";
|
||||
|
||||
var datas = conn.Query<CFQueryDto>(sql, parameters, commandTimeout: 1800).ToList();
|
||||
|
||||
return datas.GroupBy(p => p.contractinnercode).ToDictionary(d => d.Key, d =>
|
||||
{
|
||||
var res = d.OrderByDescending(p => p.infopubldate).First().conversionfactors;
|
||||
return res != null ? (double)res : (double?)null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Handle(trade td,TradeValueResult calRes)
|
||||
private void handle(GreeksCalcDto dto, underlying_manager um)
|
||||
{
|
||||
calRes.Delta_r = calRes.Delta * -1;
|
||||
if (!calcInstrumentTypes.Contains(um.UnderlyingInstrumentType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var calcArgs = GetCalcArgs(um.UnderlyingCode, um.UnderlyingInstrumentType);
|
||||
|
||||
if (ConsGlobal.InstrumentType.RateYield.Equals(um.UnderlyingInstrumentType))
|
||||
{
|
||||
//利率收益率
|
||||
dto.Delta_r = dto.Delta * -1;
|
||||
dto.Gamma_r = dto.Gamma;
|
||||
dto.Vega_r = dto.Vega;
|
||||
}
|
||||
else if (instrumentBondsTypes.Contains(um.UnderlyingInstrumentType))
|
||||
{
|
||||
//利率债、信用债、其它债券
|
||||
dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D;
|
||||
dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C + (calcArgs.P * calcArgs.D) * (calcArgs.P * calcArgs.D) * dto.Gamma;
|
||||
dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm;
|
||||
}
|
||||
else if (ConsGlobal.InstrumentType.BondIndex.Equals(um.UnderlyingInstrumentType))
|
||||
{
|
||||
//债券指数
|
||||
dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D;
|
||||
dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C + (calcArgs.P * calcArgs.D) * (calcArgs.P * calcArgs.D) * dto.Gamma;
|
||||
dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm;
|
||||
}
|
||||
else if (ConsGlobal.InstrumentType.TBFutures.Equals(um.UnderlyingInstrumentType))
|
||||
{
|
||||
//国债期货
|
||||
dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D / calcArgs.CF;
|
||||
dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C / calcArgs.CF + (calcArgs.P * calcArgs.D / calcArgs.CF) * (calcArgs.P * calcArgs.D / calcArgs.CF) * dto.Gamma;
|
||||
dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm;
|
||||
}
|
||||
|
||||
dto.Delta_r_1bp = dto.Delta_r * 0.0001;
|
||||
dto.Dv01 = dto.Delta_r_1bp;
|
||||
dto.Gamma_r_1bp = dto.Gamma_r * 0.0001 * 0.0001;
|
||||
dto.Vega_r_1bp = dto.Vega_r * 0.0001;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GLMSGreeksCalcArgs
|
||||
{
|
||||
//计算日的全价
|
||||
public double? P { get; set; }
|
||||
|
||||
public double? D { get; set; }
|
||||
|
||||
public double? CF { get; set; }
|
||||
|
||||
public double? C { get; set; }
|
||||
|
||||
public double? Ytm { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GreeksCalcDto
|
||||
{
|
||||
public double? Delta { get; set; }
|
||||
|
||||
public double? Gamma { get; set; }
|
||||
|
||||
public double? Vega { 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 ChinaBondIndexQuoteQueryDto
|
||||
{
|
||||
public long InnerCode { get; set; }
|
||||
|
||||
public decimal? Duration1 { get; set; }
|
||||
|
||||
public decimal? Convexity1 { get; set; }
|
||||
|
||||
public decimal? YTM { get; set; }
|
||||
}
|
||||
|
||||
public class TFeatureBondInnerCodeQueryDto
|
||||
{
|
||||
public string contractcode { get; set; }
|
||||
|
||||
public long deliverableinnercode { get; set; }
|
||||
|
||||
public decimal? spread { get; set; }
|
||||
}
|
||||
|
||||
public class CFQueryDto
|
||||
{
|
||||
public DateTime infopubldate { get; set; }
|
||||
|
||||
public long contractinnercode { get; set; }
|
||||
public long ibmarketinnercode { get; set; }
|
||||
public decimal? conversionfactors { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,8 +530,8 @@ namespace YLErp.Modules.PricingModule
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
greeksHandleService.Handle(td, calcResult);
|
||||
|
||||
greeksHandleService.Handle(td, calcResult, underlying);
|
||||
|
||||
results.Add(new CalcOptionPriceResult
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user