169 lines
5.6 KiB
C#
169 lines
5.6 KiB
C#
using Qdp.Pricing.Library.Common.MathMethods.VolTermStructure;
|
|
using YLErp.Abstract;
|
|
using YLErp.Models;
|
|
using YLErp.Modules.SkewMapVolModule;
|
|
using YLErp.QdpModule;
|
|
using YLErp.QdpModule.Constants;
|
|
|
|
namespace YLErp.Modules.CalculationModule
|
|
{
|
|
public static class SkewMapVolHelper
|
|
{
|
|
public static double GetInterpolatedVol(
|
|
IVolatility volSurface,
|
|
DateTime valueDate,
|
|
string underlyingCode,
|
|
DateTime exerciseDate,
|
|
double strikePrice,
|
|
bool isBuy,
|
|
bool isCall,
|
|
double spotPrice,
|
|
double timeToMaturityDays = double.NaN,
|
|
int? skewMapVolVar = null)
|
|
{
|
|
var baseVolSurface = GetSkewMapBaseVolSurface(underlyingCode, volSurface);
|
|
var skewMapVolSurface = new SkewMapVolSurface(baseVolSurface.BaseVol);
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode);
|
|
|
|
var t = double.IsNaN(timeToMaturityDays)
|
|
? TradeCalcHelper.CalculateTTMDays(
|
|
valueDate,
|
|
exerciseDate,
|
|
varietyid: underlying?.UnderlyingTypeId ?? 0,
|
|
precisionOfMinute: false)
|
|
: timeToMaturityDays;
|
|
|
|
var volVar = skewMapVolVar ?? (int)(isBuy ? baseVolSurface.BidVar : baseVolSurface.AskVar);
|
|
|
|
return skewMapVolSurface.GetVol(
|
|
t: Math.Ceiling(t), //不考虑日内精确时间
|
|
k: strikePrice,
|
|
spot: spotPrice,
|
|
isCall: isCall,
|
|
isBuy: isBuy,
|
|
var: volVar);
|
|
}
|
|
|
|
/// <summary>
|
|
/// skewmapvol转换为正常波动率构造
|
|
/// </summary>
|
|
public static IVolatility GetNormalVolatility(
|
|
IVolatility volSurface,
|
|
DateTime valueDate,
|
|
string underlyingCode,
|
|
DateTime exerciseDate,
|
|
double strikePrice,
|
|
bool isBuy,
|
|
bool isCall,
|
|
double spotPrice,
|
|
double timeToMaturityDays = double.NaN,
|
|
int? skewMapVolVar = null)
|
|
{
|
|
var vol = GetInterpolatedVol(volSurface, valueDate, underlyingCode, exerciseDate, strikePrice, isBuy, isCall, spotPrice, timeToMaturityDays, skewMapVolVar);
|
|
var singleVols = QdpVolHelper.GenerateFlatSingleVols(vol);
|
|
return new VolatilityImpl
|
|
{
|
|
InterpolationMethod = ConsVolInfos.defInterpolationMethod,
|
|
VolSurfaceMode = ConsVolInfos.defVolMode,
|
|
VolTable = singleVols
|
|
};
|
|
}
|
|
|
|
public static SkewMapBaseVolSurface GetSkewMapBaseVolSurface(string underlyingCode, IVolatility volSurface)
|
|
{
|
|
Dictionary<string, double> baseVols = null;
|
|
|
|
try
|
|
{
|
|
baseVols = volSurface.VolTable.ToDictionary(x => x.Expire, x => x.Vol);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"{underlyingCode}的BaseVol格式不正确", ex);
|
|
}
|
|
|
|
if (baseVols == null)
|
|
{
|
|
throw new Exception($"{underlyingCode}的BaseVol为空");
|
|
}
|
|
|
|
if (!baseVols.ContainsKey("BidVar") || !baseVols.ContainsKey("AskVar"))
|
|
{
|
|
throw new Exception($"{underlyingCode}的BidVar或AskVar缺失");
|
|
}
|
|
|
|
var baseVolSurface = new SkewMapBaseVolSurface
|
|
{
|
|
BaseVol = baseVols,
|
|
BidVar = baseVols["BidVar"],
|
|
AskVar = baseVols["AskVar"]
|
|
};
|
|
|
|
return baseVolSurface;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取某交易的BaseVol
|
|
/// </summary>
|
|
public static double GetSkewMapBaseVolForTrade(
|
|
DateTime valueDate,
|
|
string UnderlyingCode,
|
|
IVolatility volSurface,
|
|
int UnderlyingTypeId,
|
|
DateTime ExerciseDate,
|
|
double timeToMaturityDays = double.NaN)
|
|
{
|
|
var baseVolSurface = GetSkewMapBaseVolSurface(UnderlyingCode, volSurface);
|
|
var skewMapVolSurface = new SkewMapVolSurface(baseVolSurface.BaseVol);
|
|
|
|
var t = double.IsNaN(timeToMaturityDays)
|
|
? TradeCalcHelper.CalculateTTMDays(
|
|
valueDate,
|
|
ExerciseDate,
|
|
UnderlyingTypeId,
|
|
precisionOfMinute: false)
|
|
: timeToMaturityDays;
|
|
|
|
//用于波动率插值的t,不考虑日内精确时间,所以向上取整
|
|
return skewMapVolSurface.GetBaseVol(Math.Ceiling(t));
|
|
}
|
|
|
|
public static List<SingleVol> ContructSkewMapVolTable(double baseVol, int bidVar, int askVar)
|
|
{
|
|
return new List<SingleVol>()
|
|
{
|
|
new SingleVol()
|
|
{
|
|
Strike = 1.0,
|
|
Expire = "1M",
|
|
Vol = baseVol
|
|
},
|
|
new SingleVol()
|
|
{
|
|
Strike = 1.0,
|
|
Expire = "3M",
|
|
Vol = baseVol
|
|
},
|
|
new SingleVol()
|
|
{
|
|
Strike = 1.0,
|
|
Expire = "6M",
|
|
Vol = baseVol
|
|
},
|
|
new SingleVol()
|
|
{
|
|
Strike = 1.0,
|
|
Expire = "BidVar",
|
|
Vol = bidVar
|
|
},
|
|
new SingleVol()
|
|
{
|
|
Strike = 1.0,
|
|
Expire = "AskVar",
|
|
Vol = askVar
|
|
},
|
|
};
|
|
}
|
|
}
|
|
}
|