Files
zszq-trs/YLErpDAL/Modules/UnderlyingModule/UnderlyingMainContractHistoryBLL.cs
T
2024-05-09 14:06:26 +08:00

191 lines
9.0 KiB
C#

using BaseOUDAL;
using YLErp.Model;
using YLErp.Modules.VolatilityModule;
using YLErp.Modules.VolatilityModule.SkewMapVolModule;
using YLErp.QdpModule;
using YLErp.QdpModule.Constants;
namespace YLErp.BLL
{
public class underlying_main_contract_historyBLL
{
public static readonly List<string> ShowExpires;
public static readonly List<string> 有色金属ShowExpires;
static underlying_main_contract_historyBLL()
{
if (!PS.Config.ErpElement.SkewMapVolConstruction)
{
ShowExpires = new List<string> { "2W", "1M", "3M" };
有色金属ShowExpires = new List<string> { "2W", "1M", "2M" };
}
else
{
ShowExpires = new List<string> { "1M", "3M", "6M" };
有色金属ShowExpires = new List<string> { "1M", "3M", "6M" };
}
}
public static List<VolatilityQuotation> GetVolatilityQuotation(int userId, IEnumerable<flat_price_quotation> quotationList, string userGroup = null)
{
var VQ = new List<VolatilityQuotation>();
if (string.IsNullOrEmpty(userGroup))
{
userGroup = UserBLL.GetUserGroup(userId);
}
var vollist = new VolatilityQueryService(OptUserInfo.SystemUser)
.GetVolatilities(new BatchVolatilityRequest
{
QuotationDate = valuedateBLL.ValueDate,
VolTypes = ConsVolInfos.subTradeVolType,
UnderlyingCodes = quotationList.Select(O => O.UnderlyingCode).ToArray(),
UserGroup = userGroup,
TradeVolWithBidAsk = false
}, true);
var exDate = QdpCalendarHelper.GetNonHoliday(valuedateBLL.ValueDate.AddMonths(1).AddDays(-1));
var exerciseDate = exDate;
var quotationUnderlyinglist = underlying_main_contractBLL.GetDefaultAtMoneyQuoteList(exDate);
quotationList = quotationList.Where(q =>
quotationUnderlyinglist.Any(u => string.Equals(u.UnderlyingCode, q.UnderlyingCode, StringComparison.OrdinalIgnoreCase))).OrderBy(o => o.order).ToList();
var activeAsset = underlying_main_contractBLL.GetAllunderlying_main_contractModel().Where(x => x.NeedQuote == 1);
foreach (var qu in quotationList)
{
var singleVQ = new VolatilityQuotation() { MarketName = qu.MarketName, UnderlyingMainCode = qu.UnderlyingCode, UnderlyingType = qu.UnderlyingType };
var underlying = quotationUnderlyinglist.FirstOrDefault(u => string.Equals(u.UnderlyingCode, qu.UnderlyingCode, StringComparison.OrdinalIgnoreCase));
singleVQ.CommodityCode = underlying.CommodityCode;
var checkExpires = ShowExpires;
if (underlying_managerBLL.IsYouSeJinShu(qu.UnderlyingCode))
{
checkExpires = 有色金属ShowExpires;
}
var contractUnder = activeAsset.FirstOrDefault(q => q.UnderlyingType == qu.UnderlyingType);
//var tt = activeAsset.Where(v => v.UnderlyingCode == qu.UnderlyingCode).ToList();
//var ttt = quotationUnderlyinglist.Where(q => q.UnderlyingType == "棕榈油").ToList();
var contractVol = new List<volatility>();
if (contractUnder != null && vollist != null)
{
contractVol = vollist.Where(v => contractUnder.UnderlyingCodeList.Contains(v.ContractCode)).ToList();
}
volatility askVolTable = null;
volatility bidVolTable = null;
if (PS.Config.ErpElement.SkewMapVolConstruction)
{
var req = new SkewVolRequest
{
VolType = null,
valueDate = valuedateBLL.ValueDate,
Strike = qu.SpotPrice ?? 0,
UnderlyingCode = underlying.UnderlyingCode
};
req.VolType = "报价Ask";
askVolTable = SkewVolQueryService.GetVol(userId, req);
req.VolType = "报价Bid";
bidVolTable = SkewVolQueryService.GetVol(userId, req);
}
else
{
askVolTable = SetVolQuotationTable(contractVol, qu, "报价Ask", checkExpires);
bidVolTable = SetVolQuotationTable(contractVol, qu, "报价Bid", checkExpires);
}
var volReq = new InterpolatedVolReq()
{
strike = qu.SpotPrice ?? 0,
isMoneynessOption = false,
exerciseDate = exerciseDate,
valueDate = valuedateBLL.ValueDate,
spot = qu.SpotPrice ?? 0,
volSurfaceType = askVolTable.VolSurfaceMode
};
var askeGroup = new List<ExpireGroup>();
if (askVolTable.VolTable != null)
{
askeGroup = askVolTable.VolTable.GroupBy(v => v.Expire).Select(v => new ExpireGroup { Expire = v.Key, Sv = v.ToList() }).ToList();
}
var bideGroup = new List<ExpireGroup>();
if (bidVolTable.VolTable != null)
{
bideGroup = bidVolTable.VolTable.GroupBy(v => v.Expire).Select(v => new ExpireGroup { Expire = v.Key, Sv = v.ToList() }).ToList();
}
var BidAskMatureData = new List<BidAskMatureData>();
foreach (var expire in checkExpires)
{
var askvol = double.NaN;
var bidvol = double.NaN;
var askGroup = askeGroup.FirstOrDefault(a => a.Expire == expire);
var bidgroup = bideGroup.FirstOrDefault(b => b.Expire == expire);
if (askGroup != null)
{
askvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(askGroup.Sv, volReq, askVolTable.InterpolationMethod);
}
else if (!PS.Config.ErpElement.SkewMapVolConstruction)
{
askvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(askVolTable.VolTable, volReq, askVolTable.InterpolationMethod);
}
if (bidgroup != null)
{
bidvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(bidgroup.Sv, volReq, bidVolTable.InterpolationMethod);
}
else if (!PS.Config.ErpElement.SkewMapVolConstruction)
{
bidvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(bidVolTable.VolTable, volReq, bidVolTable.InterpolationMethod);
}
var md = new BidAskMatureData() { Expire = expire, AskVol = askvol, BidVol = bidvol };
BidAskMatureData.Add(md);
}
singleVQ.BidAskMatureData = BidAskMatureData;
VQ.Add(singleVQ);
}
return VQ;
}
public static volatility SetVolQuotationTable(List<volatility> vollist, flat_price_quotation qu, string voltype, List<string> ShowExpires)
{
var askVolTable = vollist.FirstOrDefault(v => v.ContractCode == qu.UnderlyingCode && v.VolType == voltype);
if (askVolTable == null)
{
askVolTable = vollist.FirstOrDefault(v => v.ContractCode.Contains(underlying_managerBLL.GetCommodityCodeByUnCode(qu.UnderlyingCode)) && v.VolType == voltype);
if (askVolTable == null)
{
askVolTable = new volatility { VolType = voltype, VolSurfaceMode = "MoneynessVol" };
return askVolTable;
}
}
if (string.IsNullOrEmpty(askVolTable.VolSurfaceMode))
{
askVolTable.VolSurfaceMode = "MoneynessVol";
}
//需要检查 ShowExpires 里不存在的
foreach (var expire in ShowExpires)
{
if (!askVolTable.VolTable.Any(v => v.Expire == expire))
{
//不存在则要查找 todo 这边应该找主力合约的波动率
var volTable = vollist.FirstOrDefault(v => v.VolTable.Any(vt => vt.Expire == expire) && v.VolType == voltype);
if (volTable != null && volTable.VolTable != null)
{
var vtInner = volTable.VolTable.Where(vt => vt.Expire == expire).ToList();
if (vtInner != null)
{
var vt = askVolTable.VolTable;
vt.AddRange(vtInner);
askVolTable.Data = vt.ToJson();
}
}
}
}
return askVolTable;
}
}
}