从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量标的波动率请求(为了兼容海通API)
|
||||
/// </summary>
|
||||
public class BatchVolatilityRequest2 : BatchVolatilityRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// QuotationDate别名,海通API使用了这个,故保留
|
||||
/// </summary>
|
||||
public DateTime SystemDate
|
||||
{
|
||||
get { return QuotationDate; }
|
||||
set { QuotationDate = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// QuotationDate别名,海通API使用了这个,故保留
|
||||
/// </summary>
|
||||
public DateTime ValueDate
|
||||
{
|
||||
get { return QuotationDate; }
|
||||
set { QuotationDate = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量标的波动率请求V2
|
||||
/// </summary>
|
||||
public class UnderlyingVolQueryApiRequestV2
|
||||
{
|
||||
/// <summary>
|
||||
/// 标的过滤
|
||||
/// </summary>
|
||||
public IEnumerable<string> UnderlyingCodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 必须有值,查看波动率曲面的日期
|
||||
/// </summary>
|
||||
public DateTime ValueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 必须有值,波动率类型
|
||||
/// </summary>
|
||||
public string[] VolTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户组
|
||||
/// </summary>
|
||||
public string UserGroup { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 曲面波动率提供
|
||||
/// </summary>
|
||||
public class UnderlyingVolQueryApiResultV2
|
||||
{
|
||||
/// <summary>
|
||||
/// 波动率类型
|
||||
/// </summary>
|
||||
public string VolType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 波动率报价日期
|
||||
/// </summary>
|
||||
public string QuotationDate
|
||||
{
|
||||
get => InnerQuotationDate.ToString("yyyy-MM-dd");
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标的代码
|
||||
/// </summary>
|
||||
public string UnderlyingCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<SingleVol> VolTable { get; set; }
|
||||
|
||||
//--------内部类----------------
|
||||
|
||||
internal string VolTableJson { get; set; }
|
||||
|
||||
internal DateTime InnerQuotationDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 标的波动率保存请求V2
|
||||
/// </summary>
|
||||
public class UnderlyingVolSaveApiRequestV2
|
||||
{
|
||||
/// <summary>
|
||||
/// 合约代码
|
||||
/// </summary>
|
||||
public string ContractCode { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 波动率类型
|
||||
/// </summary>
|
||||
public string VolType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报价日期
|
||||
/// </summary>
|
||||
public DateTime ValueDate { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 报价日期
|
||||
/// </summary>
|
||||
public DateTime QuotationDate { set => ValueDate = value; get => ValueDate; }
|
||||
|
||||
/// <summary>
|
||||
/// 插值方法
|
||||
/// </summary>
|
||||
public string InterpolationMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 波动率表格
|
||||
/// </summary>
|
||||
public List<SingleVol> VolTable { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属用户组
|
||||
/// </summary>
|
||||
public string UserGroup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果传入的合约代码为连续合约则覆盖同合约其它标的
|
||||
/// </summary>
|
||||
public bool OverridByMainCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using YLErp.BLL;
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 曲面波动率提供(用于API服务)
|
||||
/// </summary>
|
||||
public class UnderlyingVolService : YLBaseService
|
||||
{
|
||||
public UnderlyingVolService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API获取波动率
|
||||
/// </summary>
|
||||
public List<UnderlyingVol> GetUnderlyingVolSurfaces(BatchVolatilityRequest2 request)
|
||||
{
|
||||
request.TradeVolWithBidAsk = true;
|
||||
|
||||
var vols = new VolatilityQueryService(this).GetVolatilities(request, false);
|
||||
|
||||
if (request.VolType != "交易")
|
||||
{
|
||||
return vols.Select(x => new UnderlyingVol()
|
||||
{
|
||||
VolTable = x.VolTable,
|
||||
UnderlyingCode = x.ContractCode
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
return vols.ToLookup(n => n.ContractCode).Select(n => new UnderlyingVol
|
||||
{
|
||||
UnderlyingCode = n.Key,
|
||||
VolTable = n.FirstOrDefault(y => y.VolType == "交易")?.VolTable,
|
||||
VolTableBid = n.FirstOrDefault(y => y.VolType == "报价Bid")?.VolTable,
|
||||
VolTableAsk = n.FirstOrDefault(y => y.VolType == "报价Ask")?.VolTable
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API保存波动率
|
||||
/// </summary>
|
||||
public volatility SaveVolatility(volatility vol)
|
||||
{
|
||||
var targetUnderlying = underlying_managerBLL.GetByCode(vol.ContractCode);
|
||||
if (targetUnderlying != null)
|
||||
{
|
||||
vol.UnderlyingId = targetUnderlying.id;
|
||||
vol.ContractCode = targetUnderlying.UnderlyingCode;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(vol.Data))
|
||||
{
|
||||
throw new ServiceException("缺少VolTable");
|
||||
}
|
||||
|
||||
var vols = new VolatilitySaveService(this).SaveVol(vol);
|
||||
return vols.FirstOrDefault();
|
||||
}
|
||||
|
||||
public class UnderlyingVol
|
||||
{
|
||||
public string UnderlyingCode { get; set; }
|
||||
public List<SingleVol> VolTable { get; set; }
|
||||
public List<SingleVol> VolTableBid { get; set; }
|
||||
public List<SingleVol> VolTableAsk { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
using Newtonsoft.Json;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.Models;
|
||||
using YLErp.QdpModule.Constants;
|
||||
|
||||
namespace YLErp.Modules.VolatilityModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 曲面波动率提供(用于API服务)
|
||||
/// </summary>
|
||||
public partial class UnderlyingVolServiceV2 : YLBaseService
|
||||
{
|
||||
public UnderlyingVolServiceV2(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API获取波动率
|
||||
/// </summary>
|
||||
public IEnumerable<UnderlyingVolQueryApiResultV2> GetVolSurfaces(UnderlyingVolQueryApiRequestV2 request)
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
if (request.VolTypes == null || !request.VolTypes.Any())
|
||||
{
|
||||
throw new ArgumentException("VolTypes不能为空", nameof(request.VolTypes));
|
||||
}
|
||||
|
||||
if (request.UnderlyingCodes == null || !request.UnderlyingCodes.Any())
|
||||
{
|
||||
throw new ArgumentException("UnderlyingCodes不能为空", nameof(request.UnderlyingCodes));
|
||||
}
|
||||
|
||||
if (!ConsUserGroup.HasGroup)
|
||||
{
|
||||
request.UserGroup = string.Empty;
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(request.UserGroup))
|
||||
{
|
||||
throw new ArgumentException("UserGroup不能为空", nameof(request.UserGroup));
|
||||
}
|
||||
|
||||
request.ValueDate = request.ValueDate.Date;
|
||||
|
||||
if (request.ValueDate.Year < 1949)
|
||||
{
|
||||
throw new ArgumentException("ValueDate填写不正确:" + request.ValueDate, nameof(request.ValueDate));
|
||||
}
|
||||
|
||||
//数据量小的表尽量靠前
|
||||
var groupQuery = from v in DbContext.volatility
|
||||
where v.QuotationDate <= request.ValueDate
|
||||
&& request.VolTypes.Contains(v.VolType)
|
||||
&& request.UnderlyingCodes.Contains(v.ContractCode)
|
||||
&& v.UserGroup == request.UserGroup
|
||||
group v by new { v.UserGroup, v.ContractCode, v.VolType } into vg
|
||||
select new
|
||||
{
|
||||
vg.Key.UserGroup,
|
||||
vg.Key.ContractCode,
|
||||
vg.Key.VolType,
|
||||
QuotationDate = vg.Max(n => n.QuotationDate)
|
||||
};
|
||||
|
||||
var volQuery = from vg in groupQuery
|
||||
join v in DbContext.volatility
|
||||
on vg equals new { v.UserGroup, v.ContractCode, v.VolType, v.QuotationDate }
|
||||
orderby v.ContractCode
|
||||
select new UnderlyingVolQueryApiResultV2
|
||||
{
|
||||
VolType = v.VolType,
|
||||
InnerQuotationDate = v.QuotationDate,
|
||||
UnderlyingCode = v.ContractCode,
|
||||
VolTableJson = v.Data
|
||||
};
|
||||
|
||||
var vols = volQuery.ToArray();
|
||||
|
||||
foreach (var item in vols)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item.VolTableJson))
|
||||
{
|
||||
item.VolTable = JsonConvert.DeserializeObject<List<SingleVol>>(item.VolTableJson);
|
||||
}
|
||||
}
|
||||
|
||||
return vols;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API保存波动率
|
||||
/// </summary>
|
||||
public volatility SaveVolSurface(UnderlyingVolSaveApiRequestV2 request)
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(request.ContractCode))
|
||||
{
|
||||
throw new ServiceException("标的代码 必须填写");
|
||||
}
|
||||
|
||||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(request.ContractCode);
|
||||
|
||||
if (underlying == null)
|
||||
{
|
||||
throw new ServiceException("标的信息未存在:" + request.ContractCode);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(request.VolType))
|
||||
{
|
||||
throw new ServiceException("波动率类型 必须填写");
|
||||
}
|
||||
|
||||
request.ValueDate = request.ValueDate.Date;
|
||||
|
||||
if (request.ValueDate.Year < 1949)
|
||||
{
|
||||
throw new ServiceException("ValueDate填写不正确:" + request.ValueDate);
|
||||
}
|
||||
|
||||
if (request.VolTable?.Any() != true)
|
||||
{
|
||||
throw new ServiceException("缺少VolTable");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(request.InterpolationMethod))
|
||||
{
|
||||
request.InterpolationMethod = ConsVolInfos.defInterpolationMethod;
|
||||
}
|
||||
|
||||
if (!ConsUserGroup.HasGroup)
|
||||
{
|
||||
request.UserGroup = string.Empty;
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(request.UserGroup))
|
||||
{
|
||||
throw new ArgumentException("UserGroup不能为空", nameof(request.UserGroup));
|
||||
}
|
||||
|
||||
volatility retVol = null;
|
||||
|
||||
var underlyingList = new List<InnerUnderlying> {
|
||||
new InnerUnderlying{ UnderlyingId = underlying.id,UnderlyingCode = underlying.UnderlyingCode}
|
||||
};
|
||||
|
||||
//波动率上传 以连续合约 覆盖所有标的的 麻烦尽快实现
|
||||
if (request.OverridByMainCode)
|
||||
{
|
||||
int underlyingTypeId = 0;
|
||||
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(request.ContractCode, "^[a-zA-Z]+00$"))
|
||||
{
|
||||
var un = DataCacheProvider.GetUnderlyingDataSource().GetData(request.ContractCode);
|
||||
|
||||
if (un?.IsFutures() == true && un.UnderlyingTypeId > 0)
|
||||
{
|
||||
underlyingTypeId = un.UnderlyingTypeId;
|
||||
}
|
||||
}
|
||||
|
||||
if (underlyingTypeId > 0)
|
||||
{
|
||||
var query = from un in DbContext.underlying_manager
|
||||
where un.UnderlyingTypeId == underlyingTypeId
|
||||
&& (un.MaturityDate >= request.QuotationDate)
|
||||
&& un.UnderlyingCode != request.ContractCode
|
||||
select new InnerUnderlying
|
||||
{
|
||||
UnderlyingId = un.id,
|
||||
UnderlyingCode = un.UnderlyingCode
|
||||
};
|
||||
|
||||
underlyingList.AddRange(query.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var un in underlyingList)
|
||||
{
|
||||
var dbVol = DbContext.volatility.FirstOrDefault(n => n.QuotationDate == request.ValueDate
|
||||
&& n.ContractCode == un.UnderlyingCode && n.VolType == request.VolType && n.UserGroup == request.UserGroup);
|
||||
|
||||
if (dbVol == null)
|
||||
{
|
||||
dbVol = new volatility
|
||||
{
|
||||
UnderlyingId = un.UnderlyingId,
|
||||
ContractCode = un.UnderlyingCode,
|
||||
|
||||
VolType = request.VolType,
|
||||
UserGroup = request.UserGroup,
|
||||
QuotationDate = request.ValueDate,
|
||||
|
||||
VolSurfaceMode = ConsVolInfos.defVolMode
|
||||
};
|
||||
|
||||
DbContext.volatility.Add(dbVol);
|
||||
}
|
||||
|
||||
dbVol.SetOpt(OptUser);
|
||||
dbVol.SetData(request.VolTable);
|
||||
dbVol.InterpolationMethod = request.InterpolationMethod;
|
||||
|
||||
if (retVol == null)
|
||||
{
|
||||
retVol = dbVol;
|
||||
}
|
||||
}
|
||||
|
||||
DbContext.SaveChanges();
|
||||
|
||||
return retVol;
|
||||
}
|
||||
|
||||
class InnerUnderlying
|
||||
{
|
||||
public int UnderlyingId { get; set; }
|
||||
public string UnderlyingCode { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user