189 lines
6.2 KiB
C#
189 lines
6.2 KiB
C#
namespace YLErp.Modules.VolatilityModule
|
|
{
|
|
/// <summary>
|
|
/// 品种波动率数据服务
|
|
/// </summary>
|
|
public class VarietyVolService : YLBaseService
|
|
{
|
|
public VarietyVolService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
public VarietyVolService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取距valueDate最近的品种波动率
|
|
/// </summary>
|
|
public VarietyVol GetVol(long varietyId, DateTime valueDate)
|
|
{
|
|
var query = from volDb in DbContext.variety_vol
|
|
where volDb.VarietyId == varietyId
|
|
&& volDb.ValueDate <= valueDate
|
|
orderby volDb.ValueDate descending
|
|
select volDb;
|
|
return query.FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取距date最近的品种波动率
|
|
/// </summary>
|
|
public List<VarietyVolDto> GetVols(DateTime date, IEnumerable<int> varietyIds)
|
|
{
|
|
if (varietyIds is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(varietyIds));
|
|
}
|
|
|
|
var idSet = varietyIds.ToHashSet();
|
|
|
|
var grpQry = from vol in DbContext.variety_vol
|
|
where vol.ValueDate <= date && idSet.Contains(vol.VarietyId)
|
|
group vol by vol.VarietyId into grp
|
|
select new
|
|
{
|
|
VarietyId = grp.Key,
|
|
ValueDate = grp.Max(n => n.ValueDate)
|
|
};
|
|
|
|
var qry = from gv in grpQry
|
|
join vol in DbContext.variety_vol on gv equals new { vol.VarietyId, vol.ValueDate }
|
|
orderby gv.VarietyId
|
|
select new VarietyVolDto
|
|
{
|
|
VarietyId = vol.VarietyId,
|
|
ValueDate = vol.ValueDate,
|
|
Vol = vol.Vol
|
|
};
|
|
|
|
var list = qry.ToList();
|
|
|
|
foreach (var data in list)
|
|
{
|
|
idSet.Remove(data.VarietyId);
|
|
}
|
|
|
|
var defArr = idSet.Select(n => new VarietyVolDto { VarietyId = n, ValueDate = date, Vol = ConsGlobal.DefaultVol }).ToArray();
|
|
|
|
list.AddRange(defArr);
|
|
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存数据
|
|
/// </summary>
|
|
public void SaveData(int varietyId, DateTime valueDate, double vol)
|
|
{
|
|
if (varietyId == default)
|
|
{
|
|
throw new ArgumentNullException("varietyId");
|
|
}
|
|
|
|
if (valueDate == default)
|
|
{
|
|
throw new ArgumentNullException("valueDate");
|
|
}
|
|
|
|
if (vol == default(int))
|
|
{
|
|
throw new ArgumentNullException("vol");
|
|
}
|
|
|
|
if (!DbContext.variety.Any(n => n.id == varietyId))
|
|
{
|
|
throw new ServiceException("品种不存在");
|
|
}
|
|
|
|
var dbModel = DbContext.variety_vol.FirstOrDefault(n => n.VarietyId == varietyId && n.ValueDate == valueDate);
|
|
|
|
if (dbModel == null)
|
|
{
|
|
DbContext.variety_vol.Add(new VarietyVol
|
|
{
|
|
ValueDate = valueDate,
|
|
VarietyId = varietyId,
|
|
Vol = vol,
|
|
OptDate = DateTime.Now,
|
|
OptId = UserId,
|
|
OptName = UserName
|
|
});
|
|
}
|
|
else
|
|
{
|
|
dbModel.Vol = vol;
|
|
dbModel.OptId = UserId;
|
|
dbModel.OptName = UserName;
|
|
dbModel.OptDate = OptDate;
|
|
}
|
|
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Dictionary<int, double> GetVols(DateTime date, IEnumerable<trade> tradeList)
|
|
{
|
|
var result = new Dictionary<int, double>();
|
|
var codes = tradeList.Select(O => O.UnderlyingCode).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
|
|
var varietyMap = DbContext.underlying_manager
|
|
.Where(underlyingDb => codes.Contains(underlyingDb.UnderlyingCode))
|
|
.ToDictionary(K => K.UnderlyingCode, V => V.UnderlyingTypeId, StringComparer.OrdinalIgnoreCase);
|
|
|
|
var vols = GetVols(date, varietyMap.Values);
|
|
|
|
foreach (var t in tradeList)
|
|
{
|
|
if (varietyMap.TryGetValue(t.UnderlyingCode, out var vid))
|
|
{
|
|
result[t.id] = vols.Find(O => O.VarietyId == vid).Vol;
|
|
}
|
|
else
|
|
{
|
|
throw new Exception($"标的'{t.UnderlyingCode}'找不到光证波动率,因未关联品种");
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static double? GetVarietyVol(DateTime valueDate, int varietyId)
|
|
{
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var query = from v in db.variety_vol
|
|
where v.VarietyId == varietyId && v.ValueDate <= valueDate
|
|
orderby v.ValueDate descending
|
|
select (double?)v.Vol;
|
|
return query.FirstOrDefault();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static double? GetVarietyVol(DateTime valueDate, string underlyingCode)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(underlyingCode))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var query = from un in db.underlying_manager.Where(n => n.UnderlyingCode == underlyingCode)
|
|
join v in db.variety_vol on un.UnderlyingTypeId equals v.VarietyId
|
|
where v.ValueDate <= valueDate
|
|
orderby v.ValueDate descending
|
|
select (double?)v.Vol;
|
|
return query.FirstOrDefault();
|
|
}
|
|
}
|
|
}
|
|
}
|