从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
using BaseOUDAL;
|
||||
using Qdp.Pricing.Base.Implementations;
|
||||
using Qdp.Pricing.Library.Equity.Engines.Analytical;
|
||||
using YLErp.BLL;
|
||||
using YLErp.Model;
|
||||
using YLErp.QdpModule;
|
||||
|
||||
namespace YLErp.Modules.VolatilityModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 波动率处理服务
|
||||
/// </summary>
|
||||
public class VolatilityService : YLBaseService
|
||||
{
|
||||
public VolatilityService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public double GetTradeVol(trade trade, DateTime date)
|
||||
{
|
||||
TradeVolatility tradeVol = null;
|
||||
using (YLContext ylDb = new YLContext())
|
||||
{
|
||||
tradeVol = ylDb.TradeVolatility.Where(n => n.TradeId == trade.id && n.ValueDate <= date)
|
||||
.OrderByDescending(O => O.ValueDate).FirstOrDefault();
|
||||
}
|
||||
return GetTradeVol(trade, tradeVol, date);
|
||||
}
|
||||
|
||||
public void GetTradeVol(List<trade> trades, DateTime date)
|
||||
{
|
||||
Dictionary<int, TradeVolatility> volDic = new Dictionary<int, TradeVolatility>();
|
||||
List<int> ids = trades.Where(t => !ConsTrade.TradeTypesForHedge.Contains(t.TradeType) && t.StartDate <= date).Select(O => O.id).ToList();
|
||||
using (YLContext ylDb = new YLContext())
|
||||
{
|
||||
var tempQuery = DbContext.TradeVolatility.Where(O => O.ValueDate <= date && ids.Contains(O.TradeId));
|
||||
if (tempQuery.Any())
|
||||
{
|
||||
var groupQuery = tempQuery.GroupBy(O => O.TradeId).Select(n => new { TradeId = n.Key, ValueDate = n.Max(m => m.ValueDate) });
|
||||
var query = from a in DbContext.TradeVolatility
|
||||
join b in groupQuery on new { a.TradeId, a.ValueDate } equals new { b.TradeId, b.ValueDate }
|
||||
select a;
|
||||
|
||||
volDic = query.ToDictionary(K => K.TradeId);
|
||||
}
|
||||
}
|
||||
foreach (var t in trades)
|
||||
{
|
||||
if (t.StartDate > date || ConsTrade.TradeTypesForHedge.Contains(t.TradeType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
volDic.TryGetValue(t.id, out var tradeVol);
|
||||
t.Vol = GetTradeVol(t, tradeVol, date);
|
||||
}
|
||||
}
|
||||
|
||||
private double GetTradeVol(trade trade, TradeVolatility tradeVol, DateTime date)
|
||||
{
|
||||
var daycountMode = PS.Config.ErpElement.SmoothingDaycountMode == Configuration.Enums.SmoothingDaycountMode.CalendarDay
|
||||
? Qdp.Pricing.Base.Enums.DayCountMode.CalendarDay
|
||||
: Qdp.Pricing.Base.Enums.DayCountMode.TradingDay;
|
||||
|
||||
if (tradeVol == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(
|
||||
new Qdp.Foundation.Implementations.Date(date),
|
||||
trade.TradeOpenVolatility ?? 0,
|
||||
trade.TradeCloseVolatility ?? 0,
|
||||
new Qdp.Foundation.Implementations.Date(trade.StartDate ?? DateTime.Today),
|
||||
new Qdp.Foundation.Implementations.Date(trade.ExerciseDate ?? DateTime.Today),
|
||||
trade.NumOfSmoothingDays ?? 0,
|
||||
daycountMode,
|
||||
CalendarImpl.Get("chn"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return double.NaN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(
|
||||
new Qdp.Foundation.Implementations.Date(date),
|
||||
tradeVol.TradePositionVolatility ?? 0,
|
||||
tradeVol.TradeCloseVolatility ?? 0,
|
||||
new Qdp.Foundation.Implementations.Date(tradeVol.ValueDate),
|
||||
new Qdp.Foundation.Implementations.Date(trade.ExerciseDate ?? DateTime.Today),
|
||||
tradeVol.NumOfSmoothingDays ?? 0,
|
||||
daycountMode,
|
||||
CalendarImpl.Get("chn"),
|
||||
includeStartDate: tradeVol.IsFromTradeAdd);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从数据库中查询波动率信息(此处的userGroup参数允许为NULL)
|
||||
private IQueryable<volatility> _getVolQuery(DateTime date, IEnumerable<string> codes, IEnumerable<string> volTypes = null, string userGroup = null)
|
||||
{
|
||||
codes = codes.ToHashSet();
|
||||
if (volTypes == null)
|
||||
{
|
||||
volTypes = DbContext.volatility.Select(O => O.VolType).GroupBy(O => O).Select(O => O.Key).ToList();
|
||||
}
|
||||
|
||||
var queryGroup = (from vol in DbContext.volatility
|
||||
where vol.QuotationDate <= date
|
||||
&& codes.Contains(vol.ContractCode)
|
||||
&& (userGroup == null || vol.UserGroup == userGroup)
|
||||
&& volTypes.Contains(vol.VolType)
|
||||
group vol by new { vol.QuotationDate, vol.ContractCode, vol.UserGroup, vol.VolType } into grp
|
||||
select grp.Key);
|
||||
var queryKey = queryGroup.GroupBy(O => new { O.ContractCode, O.UserGroup, O.VolType }).Select(O => new { O.Key.ContractCode, O.Key.UserGroup, O.Key.VolType, QuotationDate = O.Max(M => M.QuotationDate) });
|
||||
return from vol in DbContext.volatility.AsNoTracking()
|
||||
join dict in queryKey
|
||||
on new { vol.QuotationDate, vol.ContractCode, vol.UserGroup, vol.VolType } equals new { dict.QuotationDate, dict.ContractCode, dict.UserGroup, dict.VolType }
|
||||
select vol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从数据库中查询波动率信息(此处的userGroup参数允许为NULL)
|
||||
private IQueryable<volatility> _getVolQuery(DateTime startDate, DateTime endDate, IEnumerable<string> codes, IEnumerable<string> volTypes = null, string userGroup = null)
|
||||
{
|
||||
codes = codes.ToHashSet();
|
||||
if (volTypes == null)
|
||||
{
|
||||
volTypes = DbContext.volatility.Select(O => O.VolType).GroupBy(O => O).Select(O => O.Key).ToList();
|
||||
}
|
||||
|
||||
var query = from vol in DbContext.volatility.AsNoTracking()
|
||||
where vol.QuotationDate >= startDate
|
||||
&& vol.QuotationDate <= endDate
|
||||
&& codes.Contains(vol.ContractCode)
|
||||
&& (userGroup == null || vol.UserGroup == userGroup)
|
||||
&& volTypes.Contains(vol.VolType)
|
||||
select vol;
|
||||
return _getVolQuery(startDate, codes, volTypes, userGroup).Union(query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询volatility
|
||||
/// </summary>
|
||||
public SearchListResult<volatility> SearchList(VolatilityReq req)
|
||||
{
|
||||
IEnumerable<string> codes = null;
|
||||
|
||||
if (req.UnderlyingId != null)
|
||||
{
|
||||
codes = new[] { underlying_managerBLL.GetById(req.UnderlyingId.Value).UnderlyingCode };
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(req.UnderlyingName))
|
||||
{
|
||||
codes = new[] { underlying_managerBLL.GetQuery().Where(O => O.UnderlyingName == req.UnderlyingName).FirstOrDefault().UnderlyingCode };
|
||||
}
|
||||
if (!string.IsNullOrEmpty(req.ContractCode))
|
||||
{
|
||||
codes = new[] { req.ContractCode };
|
||||
}
|
||||
if (req.QuotationDate == null || req.QuotationDate?.Year <= 2000)
|
||||
{
|
||||
if ((req.QuotationDateStart == null || req.QuotationDateStart?.Year < 2000) && (req.QuotationDateEnd == null || req.QuotationDateEnd?.Year < 2000))
|
||||
{
|
||||
req.QuotationDate = SystemValueDate;
|
||||
req.QuotationDateStart = SystemValueDate;
|
||||
req.QuotationDateEnd = req.QuotationDateStart;
|
||||
}
|
||||
else if (req.QuotationDateStart == null || req.QuotationDateStart?.Year < 2000)
|
||||
{
|
||||
req.QuotationDateStart = req.QuotationDateEnd;
|
||||
}
|
||||
else if (req.QuotationDateEnd == null || req.QuotationDateEnd?.Year < 2000)
|
||||
{
|
||||
req.QuotationDateEnd = SystemValueDate;
|
||||
}
|
||||
if (req.QuotationDateStart >= req.QuotationDateEnd)
|
||||
{
|
||||
req.QuotationDateEnd = req.QuotationDateStart;
|
||||
}
|
||||
}
|
||||
|
||||
if (codes == null)
|
||||
{
|
||||
codes = (from temp in underlying_managerBLL.GetQuery()
|
||||
where temp.LaunchState == "1"
|
||||
select temp.UnderlyingCode).ToList();
|
||||
}
|
||||
IQueryable<volatility> query = null;
|
||||
if (req.QuotationDate != null && req.QuotationDate.Value > DateTime.MinValue)
|
||||
{
|
||||
query = _getVolQuery(req.QuotationDate.Value, codes, userGroup: req.UserGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = _getVolQuery(req.QuotationDateStart.Value, req.QuotationDateEnd.Value, codes, userGroup: req.UserGroup);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(req.VolType))
|
||||
{
|
||||
query = query.Where(d => d.VolType.Contains(req.VolType));
|
||||
}
|
||||
|
||||
if (req.OptId != null)
|
||||
{
|
||||
query = query.Where(d => d.OptId == req.OptId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(req.OptName))
|
||||
{
|
||||
query = query.Where(d => d.OptName.Contains(req.OptName));
|
||||
}
|
||||
|
||||
req.sidx = "QuotationDate";
|
||||
req.sord = "asc";
|
||||
|
||||
var tempSearchList = query.ToSearchList(req);
|
||||
List<DateTime> dates = QdpCalendarHelper.AllBizDays(req.QuotationDateStart.Value, req.QuotationDateEnd.Value.AddDays(1));
|
||||
List<volatility> vols = new List<volatility>();
|
||||
var firstVol = tempSearchList.rows.FirstOrDefault();
|
||||
if (firstVol != null)
|
||||
{
|
||||
foreach (var item in dates)
|
||||
{
|
||||
var vol = tempSearchList.rows.FirstOrDefault(O => O.QuotationDate == item);
|
||||
if (vol == null && firstVol.QuotationDate < item)
|
||||
{
|
||||
vol = firstVol.Clone(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
firstVol = vol;
|
||||
}
|
||||
vols.Add(vol);
|
||||
}
|
||||
tempSearchList.records = vols.Count;
|
||||
tempSearchList.rows = vols;
|
||||
}
|
||||
return tempSearchList;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user