从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.Modules.VolatilityModule;
|
||||
using YLErp.QdpModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule.SettlementModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 结算波动率接口(暂未考虑多标的处理)
|
||||
/// </summary>
|
||||
public interface IEodVolProvider
|
||||
{
|
||||
double? GetVol(OtcTradeBase td, double spotPrice);
|
||||
}
|
||||
|
||||
#region----持仓波动率----
|
||||
|
||||
/// <summary>
|
||||
/// TradeVol模式持仓波动率提供
|
||||
/// </summary>
|
||||
class EodPositionVolProvider_Trade : TradeVolitalityProvider, IEodVolProvider
|
||||
{
|
||||
Dictionary<int, double> _overridVolDic;
|
||||
|
||||
public EodPositionVolProvider_Trade(DateTime valueDate) : base(valueDate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
if (td is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(td));
|
||||
}
|
||||
|
||||
if (td.id < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_overridVolDic == null)
|
||||
{
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
_overridVolDic = db.eod_trade_vol_override.Where(x => x.valuedate == _valueDate)
|
||||
.Select(n => new { n.tradeid, n.vol }).ToDictionary(n => n.tradeid, m => m.vol);
|
||||
}
|
||||
}
|
||||
|
||||
if (_overridVolDic.TryGetValue(td.id, out var vol))
|
||||
{
|
||||
return vol;
|
||||
}
|
||||
|
||||
if (TryGetVol(td.id, td.ExerciseDate.Value, out vol))
|
||||
{
|
||||
return vol;
|
||||
}
|
||||
|
||||
return VolatilityHelper.GetTradeVol(_valueDate, td.TradeDate.Value, td.ExerciseDate.Value,
|
||||
td.TradeOpenVolatility ?? 0, td.TradeCloseVolatility ?? 0, td.NumOfSmoothingDays ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region----曲面波动率----
|
||||
|
||||
/// <summary>
|
||||
/// 曲面波动率模式持仓波动率提供
|
||||
/// </summary>
|
||||
class EodUnderlyingVolProvider : UnderlyingVolitalityProvider
|
||||
{
|
||||
protected EodUnderlyingVolProvider(DateTime valueDate, IEnumerable<string> volTypes) : base(valueDate, volTypes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected double? InnerGetVol(OtcTradeBase td, string volType, double spotPrice)
|
||||
{
|
||||
if (td is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(td));
|
||||
}
|
||||
|
||||
var userGroup = string.Empty;
|
||||
|
||||
if (ConsUserGroup.HasGroup)
|
||||
{
|
||||
userGroup = DataCacheProvider.GetAssetUnitDataSource().GetData(td.AssetId)?.UserGroup;
|
||||
|
||||
if (string.IsNullOrEmpty(userGroup))
|
||||
{
|
||||
throw new Exception($"[结算交易'{td.TradeNumber}'][取{volType}波动率]未能获取用户组!");
|
||||
}
|
||||
}
|
||||
|
||||
var unVol = GetVol(volType, userGroup, td.UnderlyingCode);
|
||||
|
||||
if (unVol == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var constVol = VolatilityHelper.GetInterpolatedVol(
|
||||
volConstructionType: PS.Config.ErpElement.SkewMapVolConstruction ? VolConstructionType.SkewMap : VolConstructionType.Normal,
|
||||
volSurface: unVol,
|
||||
valueDate: _valueDate,
|
||||
underlyingCode: td.UnderlyingCode,
|
||||
exerciseDate: td.ExerciseDate.Value,
|
||||
strike: td.Strike ?? 0,
|
||||
isBuy: td.BuySell == "买入",
|
||||
isCall: td.CallPut == "Call",
|
||||
spotPrice: spotPrice,
|
||||
isMoneynessOption: td.IsMoneynessOption == "是",
|
||||
isEodCalc: true);
|
||||
|
||||
return constVol;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单个曲面波动率类型
|
||||
/// </summary>
|
||||
class EodUnderlyingSingleVolProvider : EodUnderlyingVolProvider, IEodVolProvider
|
||||
{
|
||||
readonly string _volType;
|
||||
|
||||
public EodUnderlyingSingleVolProvider(DateTime valueDate, string volType)
|
||||
: base(valueDate, new[] { volType })
|
||||
{
|
||||
_volType = volType ?? throw new ArgumentNullException(nameof(volType));
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
return InnerGetVol(td, _volType, spotPrice);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 曲面波动率模式持仓波动率提供
|
||||
/// </summary>
|
||||
class EodPositionVolProvider_Underlying : EodUnderlyingVolProvider, IEodVolProvider
|
||||
{
|
||||
readonly string _volType;
|
||||
|
||||
Dictionary<int, double> _overridVolDic;
|
||||
|
||||
public EodPositionVolProvider_Underlying(DateTime valueDate, string volType)
|
||||
: base(valueDate, new[] { volType })
|
||||
{
|
||||
_volType = volType ?? throw new ArgumentNullException(nameof(volType));
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
if (_overridVolDic == null)
|
||||
{
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
_overridVolDic = db.eod_trade_vol_override.Where(x => x.valuedate == _valueDate)
|
||||
.Select(n => new { n.tradeid, n.vol }).ToDictionary(n => n.tradeid, m => m.vol);
|
||||
}
|
||||
}
|
||||
|
||||
if (_overridVolDic.TryGetValue(td.id, out var vol))
|
||||
{
|
||||
return vol;
|
||||
}
|
||||
|
||||
return InnerGetVol(td, _volType, spotPrice);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region----对冲波动率----
|
||||
|
||||
/// <summary>
|
||||
/// 对冲波动率提供
|
||||
/// </summary>
|
||||
class EodHedgeVolProvider : TradeHedgeVolProvider, IEodVolProvider
|
||||
{
|
||||
public EodHedgeVolProvider(DateTime valueDate) : base(valueDate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
if (td is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(td));
|
||||
}
|
||||
|
||||
if (TryGetVol(td.id, out var vol))
|
||||
{
|
||||
return vol;
|
||||
}
|
||||
|
||||
return td.TradeSavedVol ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开仓波动率提供(开仓波动率只在TradeVol模式下结算)
|
||||
/// </summary>
|
||||
class EodOpenVolProvider : TradeHedgeVolProvider, IEodVolProvider
|
||||
{
|
||||
public EodOpenVolProvider(DateTime valueDate) : base(valueDate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
return td?.TradeOpenVolatility;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region----扩展波动率----
|
||||
|
||||
/// <summary>
|
||||
/// 扩展波动率(光证)提供
|
||||
/// </summary>
|
||||
class EodExtendVolProvider_GZ : VarietyVolProvider, IEodVolProvider
|
||||
{
|
||||
public EodExtendVolProvider_GZ(DateTime valueDate) : base(valueDate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
if (td is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(td));
|
||||
}
|
||||
|
||||
if (TryGetVol(td.UnderlyingCode, out var vol))
|
||||
{
|
||||
return vol;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扩展波动率(BidAskVol)提供
|
||||
/// </summary>
|
||||
class EodExtendVolProvider_BidAskVol : EodUnderlyingVolProvider, IEodVolProvider
|
||||
{
|
||||
public EodExtendVolProvider_BidAskVol(DateTime valueDate)
|
||||
: base(valueDate, new[] { "报价Ask", "报价Bid" })
|
||||
{
|
||||
}
|
||||
|
||||
public double? GetVol(OtcTradeBase td, double spotPrice)
|
||||
{
|
||||
if (td is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(td));
|
||||
}
|
||||
|
||||
return InnerGetVol(td, td.BuySell == "买入" ? "报价Ask" : "报价Bid", spotPrice);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 波动率提供者工厂
|
||||
/// </summary>
|
||||
public class EodVolProviderFactory
|
||||
{
|
||||
public static IEodVolProvider GetEodVolProvider(DateTime valueDate, string volType)
|
||||
{
|
||||
switch (volType)
|
||||
{
|
||||
case "持仓":
|
||||
if (PS.Config.IsTradeVol)
|
||||
{
|
||||
return new EodPositionVolProvider_Trade(valueDate);
|
||||
}
|
||||
volType = BLL.valuedateBLL.SystemDate.EodSettleVolMode.TrimToNull() ?? "财务";
|
||||
return new EodPositionVolProvider_Underlying(valueDate, volType);
|
||||
case "开仓":
|
||||
return new EodOpenVolProvider(valueDate);
|
||||
case "对冲":
|
||||
return new EodHedgeVolProvider(valueDate);
|
||||
case "BidAskVol":
|
||||
return new EodExtendVolProvider_BidAskVol(valueDate);
|
||||
case "光证":
|
||||
return new EodExtendVolProvider_GZ(valueDate);
|
||||
default:
|
||||
return new EodUnderlyingSingleVolProvider(valueDate, volType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user