从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Concurrent;
|
||||
using YLErp.Abstract;
|
||||
using YLErp.Modules.ExchangeOptionTradeModule;
|
||||
|
||||
namespace YLErp.Modules.DataProviderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场内期权保存波动率提供
|
||||
/// </summary>
|
||||
public class ExOptionSavedVolProvider : IDataUpdater, IJsonSerializable
|
||||
{
|
||||
readonly DateTime _valueDate;
|
||||
//使用场内期权代码做为主键
|
||||
readonly ConcurrentDictionary<string, double?> _dic;
|
||||
//业务操作上来说,旧的波动率不会再变更
|
||||
readonly ConcurrentDictionary<string, double?> _dicOld;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="valueDate">当前结算日期</param>
|
||||
public ExOptionSavedVolProvider(DateTime valueDate)
|
||||
{
|
||||
_valueDate = valueDate;
|
||||
_dic = new ConcurrentDictionary<string, double?>();
|
||||
_dicOld = new ConcurrentDictionary<string, double?>();
|
||||
}
|
||||
|
||||
public string TableName => nameof(ExchangeOptionVol);
|
||||
|
||||
/// <summary>
|
||||
/// 获取交易波动率
|
||||
/// </summary>
|
||||
public double? GetSavedVol(string optionCode, DateTime valueDate)
|
||||
{
|
||||
var dic = valueDate < _valueDate ? _dicOld : _dic;
|
||||
if (!dic.TryGetValue(optionCode, out var vol))
|
||||
{
|
||||
vol = new ExchangeOptionVolQueryService(OptUserInfo.SystemUser).GetSavedVol(optionCode, valueDate);
|
||||
dic.AddOrUpdate(optionCode, vol, (n, m) => vol);
|
||||
}
|
||||
return vol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据--keyid为optionCode
|
||||
/// </summary>
|
||||
public void UpdateData(IEnumerable<string> updateKeyIds)
|
||||
{
|
||||
foreach (var optionCode in updateKeyIds)
|
||||
{
|
||||
if (optionCode != null)
|
||||
{
|
||||
_dic.TryRemove(optionCode, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return new { _valueDate, _dic, _dicOld }.ToJson();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Collections.Concurrent;
|
||||
using YLErp.Abstract;
|
||||
|
||||
namespace YLErp.Modules.DataProviderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场外期权结算波动率提供
|
||||
/// </summary>
|
||||
public class OtcEodOverrideVolProvider : IDataUpdater, IJsonSerializable
|
||||
{
|
||||
readonly DateTime _valueDate;
|
||||
//数据ID做为KEY
|
||||
readonly ConcurrentDictionary<int, double?> _dic;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public OtcEodOverrideVolProvider(DateTime valueDate)
|
||||
{
|
||||
_valueDate = valueDate;
|
||||
_dic = new ConcurrentDictionary<int, double?>();
|
||||
}
|
||||
|
||||
public string TableName => nameof(eod_trade_vol_override);
|
||||
|
||||
/// <summary>
|
||||
/// 获取交易波动率
|
||||
/// </summary>
|
||||
public double? GetVol(int tradeId, DateTime valueDate)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(_valueDate == valueDate);
|
||||
|
||||
if (!_dic.TryGetValue(tradeId, out double? vol))
|
||||
{
|
||||
vol = DbContextFactory.GetYLDbContext().eod_trade_vol_override
|
||||
.Where(n => n.valuedate == valueDate && n.tradeid == tradeId)
|
||||
.Select(n => (double?)n.vol).FirstOrDefault();
|
||||
_dic.AddOrUpdate(tradeId, vol, (n, m) => vol);
|
||||
}
|
||||
|
||||
if (vol == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Convert.ToDouble(vol.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据
|
||||
/// </summary>
|
||||
public void UpdateData(IEnumerable<string> updateKeyIds)
|
||||
{
|
||||
var tradeIds = DataConvert.ConvertToInt32Array(updateKeyIds);
|
||||
foreach (var tradeId in tradeIds)
|
||||
{
|
||||
_dic.TryRemove(tradeId, out _);
|
||||
}
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return new { _valueDate, _dic }.ToJson();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Concurrent;
|
||||
using YLErp.Abstract;
|
||||
|
||||
namespace YLErp.Modules.DataProviderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场外期权对冲波动率提供
|
||||
/// </summary>
|
||||
public class OtcHedgingVolProvider : IDataUpdater, IJsonSerializable
|
||||
{
|
||||
readonly DateTime _valueDate;
|
||||
//使用tradeid做为主键
|
||||
readonly ConcurrentDictionary<int, double?> _dic;
|
||||
//业务操作上来说,旧的波动率不会再变更
|
||||
readonly ConcurrentDictionary<int, double?> _dicOld;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="valueDate">当前结算日期</param>
|
||||
public OtcHedgingVolProvider(DateTime valueDate)
|
||||
{
|
||||
_valueDate = valueDate;
|
||||
_dic = new ConcurrentDictionary<int, double?>();
|
||||
_dicOld = new ConcurrentDictionary<int, double?>();
|
||||
}
|
||||
|
||||
public string TableName => nameof(trade_hedge_vol);
|
||||
|
||||
/// <summary>
|
||||
/// 获取交易波动率
|
||||
/// </summary>
|
||||
public double? GetVol(int tradeId, DateTime valueDate)
|
||||
{
|
||||
var dic = valueDate < _valueDate ? _dicOld : _dic;
|
||||
if (!dic.TryGetValue(tradeId, out double? vol))
|
||||
{
|
||||
vol = DbContextFactory.GetYLDbContext().trade_hedge_vol
|
||||
.Where(n => n.TradeId == tradeId && n.ValueDate <= valueDate)
|
||||
.OrderByDescending(n => n.ValueDate)
|
||||
.Select(n => (double?)n.TradeSavedVol).FirstOrDefault();
|
||||
dic.AddOrUpdate(tradeId, vol, (n, m) => vol);
|
||||
}
|
||||
return vol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据
|
||||
/// </summary>
|
||||
public void UpdateData(IEnumerable<string> updateKeyIds)
|
||||
{
|
||||
var tradeIds = DataConvert.ConvertToInt32Array(updateKeyIds);
|
||||
foreach (var tradeId in tradeIds)
|
||||
{
|
||||
_dic.TryRemove(tradeId, out _);
|
||||
}
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return new { _valueDate, _dic, _dicOld }.ToJson();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Concurrent;
|
||||
using YLErp.Abstract;
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.DataProviderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场外期权开仓平仓波动率提供
|
||||
/// </summary>
|
||||
public class OtcPositionVolProvider : IDataUpdater, IJsonSerializable
|
||||
{
|
||||
readonly DateTime _valueDate;
|
||||
//使用tradeid做为主键,为当日取波动率提供服务
|
||||
readonly ConcurrentDictionary<int, IOtcTradeVolatility> _dic;
|
||||
//业务操作上来说,旧的波动率不会再变更,为上一交易日取波动率提供服务
|
||||
readonly ConcurrentDictionary<int, IOtcTradeVolatility> _dicOld;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="valueDate">当前结算日期</param>
|
||||
public OtcPositionVolProvider(DateTime valueDate)
|
||||
{
|
||||
_valueDate = valueDate;
|
||||
_dic = new ConcurrentDictionary<int, IOtcTradeVolatility>();
|
||||
_dicOld = new ConcurrentDictionary<int, IOtcTradeVolatility>();
|
||||
}
|
||||
|
||||
public string TableName => nameof(TradeVolatility);
|
||||
|
||||
/// <summary>
|
||||
/// 获取交易波动率
|
||||
/// </summary>
|
||||
public IOtcTradeVolatility GetVol(int tradeId, DateTime valueDate)
|
||||
{
|
||||
var dic = valueDate < _valueDate ? _dicOld : _dic;
|
||||
if (!dic.TryGetValue(tradeId, out var vol))
|
||||
{
|
||||
var tradVol = DbContextFactory.GetYLDbContext().TradeVolatility
|
||||
.Where(n => n.TradeId == tradeId && n.ValueDate <= valueDate)
|
||||
.OrderByDescending(n => n.ValueDate)
|
||||
.Select(n => new
|
||||
{
|
||||
n.NumOfSmoothingDays,
|
||||
n.TradePositionVolatility,
|
||||
n.TradeCloseVolatility,
|
||||
n.IsFromTradeAdd,
|
||||
n.ValueDate
|
||||
}).FirstOrDefault();
|
||||
|
||||
if (tradVol != null)
|
||||
{
|
||||
vol = new OtcTradeVolatility
|
||||
{
|
||||
ValueDate = tradVol.ValueDate,
|
||||
OpenVol = tradVol.TradePositionVolatility ?? 0,
|
||||
CloseVol = tradVol.TradeCloseVolatility ?? 0,
|
||||
SmoothingDays = tradVol.NumOfSmoothingDays ?? 0,
|
||||
IsFirst = tradVol.IsFromTradeAdd == true
|
||||
};
|
||||
}
|
||||
dic.AddOrUpdate(tradeId, vol, (n, m) => vol);
|
||||
}
|
||||
return vol;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return new { _valueDate, _dic, _dicOld }.ToJson();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据
|
||||
/// </summary>
|
||||
public void UpdateData(IEnumerable<string> updateKeyIds)
|
||||
{
|
||||
var tradeIds = DataConvert.ConvertToInt32Array(updateKeyIds);
|
||||
foreach (var tradeId in tradeIds)
|
||||
{
|
||||
_dic.TryRemove(tradeId, out IOtcTradeVolatility vol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using YLErp.Abstract;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.DataProviderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 标的波动率数据提供
|
||||
/// </summary>
|
||||
class UnderlyingVolProvider : IDataUpdater, IJsonSerializable
|
||||
{
|
||||
const string KeySeparator = "[|]";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime ValueDate { get; }
|
||||
|
||||
//波动率类型+合约代码做为KEY
|
||||
readonly Dictionary<string, InnerVolatility> _dic;
|
||||
|
||||
static readonly InnerVolatility _removed;
|
||||
|
||||
public UnderlyingVolProvider(DateTime valueDate)
|
||||
{
|
||||
ValueDate = valueDate;
|
||||
|
||||
_dic = new Dictionary<string, InnerVolatility>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
static UnderlyingVolProvider()
|
||||
{
|
||||
_removed = new InnerVolatility();
|
||||
}
|
||||
|
||||
public string TableName => nameof(volatility);
|
||||
|
||||
/// <summary>
|
||||
/// 根据请求参数获取波动率
|
||||
/// </summary>
|
||||
public IVolatility GetVolatility(string voltype, string contractCode, string userGroup)
|
||||
{
|
||||
if (!ConsUserGroup.HasGroup)
|
||||
{
|
||||
userGroup = string.Empty;
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userGroup))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(voltype) || string.IsNullOrWhiteSpace(contractCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var keyStr = string.Join(KeySeparator, new[] { contractCode, voltype, userGroup });
|
||||
|
||||
lock (_dic)
|
||||
{
|
||||
if (_dic.TryGetValue(keyStr, out var dicItem) && dicItem != _removed)
|
||||
{
|
||||
return dicItem;
|
||||
}
|
||||
}
|
||||
|
||||
volatility volData = null;
|
||||
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
volData = db.volatility.AsNoTracking()
|
||||
.Where(n => n.UserGroup == userGroup && n.ContractCode == contractCode && n.VolType == voltype && n.QuotationDate <= ValueDate)
|
||||
.OrderByDescending(n => n.QuotationDate).FirstOrDefault();
|
||||
|
||||
if (volData == null)
|
||||
{
|
||||
lock (_dic)
|
||||
{
|
||||
_dic[keyStr] = null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var innerVol = new InnerVolatility
|
||||
{
|
||||
VolSurfaceMode = volData.VolSurfaceMode,
|
||||
InterpolationMethod = volData.InterpolationMethod,
|
||||
VolTable = volData.VolTable ?? new List<SingleVol>(0)
|
||||
};
|
||||
|
||||
lock (_dic)
|
||||
{
|
||||
_dic[keyStr] = innerVol;
|
||||
}
|
||||
|
||||
return innerVol;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
lock (_dic)
|
||||
{
|
||||
return new { ValueDate, _dic }.ToJson();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新数据--使用直接删除的方式
|
||||
/// </summary>
|
||||
public void UpdateData(IEnumerable<string> updateKeyIds)
|
||||
{
|
||||
lock (_dic)
|
||||
{
|
||||
var removeArr = _dic.Where(n => n.Value == _removed);
|
||||
|
||||
foreach (var kv in removeArr)
|
||||
{
|
||||
_dic.Remove(kv.Key);
|
||||
}
|
||||
|
||||
var set = new HashSet<string>(10, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var keyId in updateKeyIds)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(keyId))
|
||||
{
|
||||
var strArr = keyId.Split(','); //id,ContractCode,VolType
|
||||
|
||||
if (strArr.Length > 2)
|
||||
{
|
||||
set.Add(string.Concat(strArr[1], KeySeparator, strArr[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var k in _dic.Keys)
|
||||
{
|
||||
var index = k.LastIndexOf(KeySeparator);
|
||||
|
||||
if (index > 0 && set.Contains(k.Substring(0, index)))
|
||||
{
|
||||
_dic[k] = _removed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InnerVolatility : IVolatility
|
||||
{
|
||||
public string VolSurfaceMode { get; set; }
|
||||
|
||||
public string InterpolationMethod { get; set; }
|
||||
|
||||
public List<SingleVol> VolTable { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user