Files
zszq-trs/YLErpDAL/QdpModule/QDPHelper.cs
2024-05-09 14:06:26 +08:00

767 lines
30 KiB
C#

using Qdp.ComputeService.Data.CommonModels.MarketInfos;
using Qdp.ComputeService.Data.CommonModels.MarketInfos.CurveDefinitions;
using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Enums;
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Base.Interfaces;
using Qdp.Pricing.Base.Utilities;
using Qdp.Pricing.Library.Options.Utilities;
using YLErp.Configuration;
namespace YLErp.QdpModule
{
/// <summary>
/// QDP类库帮助类
/// </summary>
public static class QdpHelper
{
/// <summary>
/// 默认到期日计算
/// </summary>
/// <param name="contractCode"></param>
/// <returns></returns>
public static DateTime defaultMaturityDateFromContract(string contractCode)
{
//上海规则
//合约交割月份的15日(遇法定假日顺延)
var shCodes = new string[] { "CU", "AL", "ZN", "PB", "NI", "AU", "AG", "RB", "WR", "HC", "BU", "RU" };
//合约交割月份前一月份的最后一个交易日,
var shPreMonthLastDay = new string[] { "FU", "SC" };
var shPreMonthFifthLastDay = new string[] { "IM" };
//大连规则
//合约月份第10个交易日
var dalianCodes = new string[] { "M", "Y", "A", "B", "P", "C", "CS", "JD", "BB", "FB", "L", "V", "PP", "J", "JM", "I" };
//special dalian rule, EGG
//合约交割月份前一月份的倒数第4个交易日
var dalianEggCodes = new string[] { "JD" };
//zhenzhou rule
//合约月份第10个交易日
var zhenzhouCodes = new string[] { "SR", "CF", "ZC", "FG", "TA", "MA", "WH", "PM", "SM", "RM", "RI", "LR", "JR", "RS", "OI", "SF", "CY", "AP" };
var calendar = CalendarImpl.Get("chn");
Date adjsuted;
if (strStartWith(contractCode, shCodes, out var estimate))
{
//SH rule: 15th of delivery date, modified following
var unAdjusted = new Date(estimate.Year, estimate.Month, 15);
adjsuted = calendar.Adjust(unAdjusted, BusinessDayConvention.ModifiedFollowing);
}
else if (strStartWith(contractCode, shPreMonthLastDay, out estimate))
{
//SH special rule, last biz day of previous month;
var unAdjusted = new Date(estimate.Year, estimate.Month, 1);
adjsuted = calendar.Adjust(unAdjusted, BusinessDayConvention.Previous);
}
else if (strStartWith(contractCode, shPreMonthFifthLastDay, out estimate))
{
//SH rule, 5th last biz day of previous month
var unAdjusted = new Date(estimate.Year, estimate.Month, 1);
for (var i = 1; i <= 5; i++)
{
unAdjusted = calendar.Adjust(unAdjusted.AddDays(-1), BusinessDayConvention.Previous);
}
adjsuted = unAdjusted;
}
else if (strStartWith(contractCode, dalianCodes, out estimate) || strStartWith(contractCode, zhenzhouCodes, out estimate))
{
//Dalian rule, 10th biz day of contract maturity month
var unAdjusted = new Date(estimate.Year, estimate.Month, 1);
for (var i = 1; i <= 10; i++)
{
unAdjusted = calendar.Adjust(unAdjusted.AddDays(1), BusinessDayConvention.ModifiedFollowing);
}
adjsuted = unAdjusted;
}
else if (strStartWith(contractCode, dalianEggCodes, out estimate))
{
//Dalian Egg rule, 4th last biz day of previous month
var unAdjusted = new Date(estimate.Year, estimate.Month, 1);
for (var i = 1; i <= 4; i++)
{
unAdjusted = calendar.Adjust(unAdjusted.AddDays(-1), BusinessDayConvention.Previous);
}
adjsuted = unAdjusted;
}
else
{
adjsuted = calendar.NextBizDay(new Term("1Y").Next(new Date(DateTime.Now)));
}
return adjsuted.DateTime;
}
private static bool strStartWith(string str, string[] InThisSet, out Date estimate)
{
var found = InThisSet.Where(x => str.StartsWith(x));
//default
estimate = new Date(DateTime.Today);
//locate delivery day from delivery code
//RB1803 => 20180301
if (found.Count() > 0)
{
try
{
var head = InThisSet.First(x => str.StartsWith(x));
var yearDates = "";
string[] zhenzhouCodes = { "SR", "CF", "ZC", "FGM", "TA", "MA", "WH", "PM" };
if (zhenzhouCodes.Contains(head)) // 郑州商品交易所的默认到期日做特殊处理
{
yearDates = "1" + str.Remove(0, head.Length);
}
else
{
yearDates = str.Remove(0, head.Length);
}
//var yearDates = str.Split(head)[1];
var year = Convert.ToInt32("20" + yearDates[0] + yearDates[1]);
try
{
var month = Convert.ToInt32(yearDates[2].ToString() + yearDates[3].ToString());
estimate = new Date(year, month, 1);
}
catch (Exception)
{
estimate = new Date(year, 1, 1);
}
}
catch (Exception)
{ }
}
return found.Count() > 0;
}
/// <summary>
/// 根据term和valueDate计算到期日
/// </summary>
/// <param name="valueDate"></param>
/// <param name="term"></param>
/// <returns></returns>
public static DateTime getMaturityDate(DateTime valueDate, string term)
{
return new Term(term).Next(new Date(valueDate)).DateTime;
}
/// <summary>
/// 从字符串中解析观察日列表
/// 如:2019-07-16,2019-08-16
/// </summary>
public static Date[] ParseObservationDate(string observationDateStr)
{
if (string.IsNullOrWhiteSpace(observationDateStr))
{
return null;
}
var fields = observationDateStr.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
var dateStrs = fields[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (dateStrs == null || dateStrs.Length == 0)
{
return null;
}
return dateStrs.Select(x => new Date(DateTime.Parse(x))).ToArray();
}
public static DateTime[] GetObservationDatesFromString(string str)
{
var dates = ParseObservationDate(str);
if (dates == null)
{
return null;
}
return dates.Select(x => x.DateTime).ToArray();
}
/// <summary>
/// 解析凤凰、雪球的自定义信息字符串,其格式为
/// {自定义敲出观察日序列};{敲出障碍价格序列};{票息序列}
/// 每个序列内部都以逗号分隔多个元素
/// </summary>
/// <param name="str"></param>
/// <returns>返回的元组,第一个元素为敲出观察日列表,第二个元素为敲出障碍价格列表,第三个元素为票息列表</returns>
public static Tuple<Date[], double[], double[]> ParseAutocallCustomizedInfo(string str)
{
Date[] dates = null;
double[] customizedKOBarriers = null;
double[] customizedCoupons = null;
if (!string.IsNullOrWhiteSpace(str))
{
//if (!str.Contains(";"))
//{
// str = ConvertObservationFromTableToString(str);
//}
var fields = str.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (fields != null && fields.Length > 0)
{
dates = ParseObservationDate(fields[0]);
}
if (fields != null && fields.Length > 1)
{
customizedKOBarriers = ParseDoubleNumbers(fields[1]);
}
if (fields != null && fields.Length > 2)
{
customizedCoupons = ParseDoubleNumbers(fields[2]);
}
}
return Tuple.Create(dates, customizedKOBarriers, customizedCoupons);
}
/// <summary>
/// 用于qdp 凤凰期权 看涨时,障碍价格为空,该障碍价格等于期初价格的100倍;看跌时,障碍价格为空,该障碍价格等于期初价格的百分之一
/// </summary>
public static Tuple<Date[], double[], double[]> ParseAutocallCustomizedInfoV2(string str, OptionType callput, double spotPrice, bool isMoneynessOption)
{
Date[] dates = null;
double[] customizedKOBarriers = null;
double[] customizedCoupons = null;
if (!string.IsNullOrWhiteSpace(str))
{
var fields = str.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (fields != null && fields.Length > 0)
{
dates = ParseObservationDate(fields[0]);
}
if (fields != null && fields.Length > 1)
{
customizedKOBarriers = ParseDoubleNumbersV2(fields[1], callput, spotPrice, isMoneynessOption);
}
if (fields != null && fields.Length > 2)
{
customizedCoupons = ParseDoubleNumbers(fields[2]);
}
}
return Tuple.Create(dates, customizedKOBarriers, customizedCoupons);
}
/// <summary>
/// 不用于用于qdp 凤凰期权
/// {自定义敲出观察日序列};{敲出障碍价格序列}; 只有解析两列
/// </summary>
/// <param name="str"></param>
/// <returns>返回的元组,第一个元素为敲出观察日列表,第二个元素为敲出障碍价格列表</returns>
public static Tuple<Date[], double[]> ParseAutocallCustomizedInfoV3(string str)
{
Date[] dates = null;
double[] customizedKOBarriers = null;
if (!string.IsNullOrWhiteSpace(str))
{
//if (!str.Contains(";"))
//{
// str = ConvertObservationFromTableToString(str);
//}
var fields = str.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (fields != null && fields.Length > 0)
{
dates = ParseObservationDate(fields[0]);
}
if (fields != null && fields.Length > 1)
{
customizedKOBarriers = ParseDoubleNumbers(fields[1]);
}
}
return Tuple.Create(dates, customizedKOBarriers);
}
private static double[] ParseDoubleNumbers(string str)
{
var values = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (values == null || values.Length == 0)
{
return null;
}
//try
//{
// return values.Select(x => double.Parse(x)).ToArray();
//}
//catch
//{
// return null;
//}
var dvalues = new double[values.Length];
for (var i = 0; i < values.Length; i++)
{
if (double.TryParse(values[i], out var d))
{
dvalues[i] = d;
}
else
{
return null;
}
}
return dvalues;
}
/// <summary>
/// 凤凰期权 看涨时,障碍价格为空,该障碍价格等于期初价格的100倍;看跌时,障碍价格为空,该障碍价格等于期初价格的百分之一
/// </summary>
private static double[] ParseDoubleNumbersV2(string str, OptionType callput, double spotPrice, bool isMoneynessOption)
{
var values = str.Split(new char[] { ',' });
if (values == null || values.Length == 0)
{
return null;
}
double[] newVs = new double[values.Length];
int i = 0;
foreach (var v in values)
{
double newV = 0;
if (string.IsNullOrEmpty(v))
{
switch (callput)
{
case OptionType.Call:
newV = isMoneynessOption ? 100 : (spotPrice * 100);
break;
case OptionType.Put:
newV = isMoneynessOption ? 0.01 : (spotPrice / 100);
break;
default: break;
}
}
else
{
newV = double.Parse(v);
}
newVs[i] = newV;
i++;
}
return newVs;
}
/// <summary>
/// 解析亚式期权的Fixing价格序列
/// </summary>
/// <param name="fixings"></param>
/// <returns></returns>
public static Dictionary<Date, double> ParseFixingsFromString(string fixings)
{
return string.IsNullOrWhiteSpace(fixings)
? new Dictionary<Date, double>() :
fixings.Split(QdpConsts.Semilicon)
.Select(x =>
{
var splits = x.Split(QdpConsts.Comma);
return Tuple.Create(splits[0].ToDate(), double.Parse(splits[1]));
}).ToDictionary(x => x.Item1, x => x.Item2);
}
/// <summary>
/// 将期限字符串,转换成一组日期
/// </summary>
/// <param name="valueDate"></param>
/// <param name="expireTenors"></param>
/// <param name="volSurfaceKeyDateShift"></param>
/// <param name="excludeEndDate"></param>
/// <returns></returns>
public static List<Date> ConvertTenorsToDates(Date valueDate, string[] expireTenors, VolSurfaceKeyDateShiftEnum volSurfaceKeyDateShift, bool excludeEndDate)
{
var dates = new List<Date>();
var calendar = CalendarImpl.Get("chn");
//解析到期日
for (var i = 0; i < expireTenors.Length; ++i)
{
var expectedTermString = expireTenors[i];
if (Term.IsTerm(expectedTermString))
{
var keyPointDate = new Term(expectedTermString).Next(valueDate);
if (excludeEndDate)
{
keyPointDate = keyPointDate.AddDays(-1);
}
if (calendar.IsHoliday(keyPointDate))
{
switch (volSurfaceKeyDateShift)
{
case VolSurfaceKeyDateShiftEnum.NextBizDay:
keyPointDate = calendar.NextBizDay(keyPointDate);
break;
case VolSurfaceKeyDateShiftEnum.PrevBizDay:
keyPointDate = calendar.PrevBizDay(keyPointDate);
break;
default:
break;
}
}
dates.Add(keyPointDate);
}
}
return dates;
}
/// <summary>
///
/// </summary>
public static bool IsCall(string callPut)
{
if (string.IsNullOrEmpty(callPut))
{
return false;
}
return (OptionType)Enum.Parse(typeof(OptionType), callPut) == OptionType.Call;
}
public static double AnnualizeFactor(DateTime startDate, DateTime endDate, IDayCount dayCount)
{
return dayCount.CalcDayCountFraction(new Date(startDate), new Date(endDate));
}
public static double AnnualizeFactor(double ttmDays, IDayCount dayCount)
{
return ttmDays / dayCount.DaysInYear();
}
/// <summary>
/// 计算精确的TTM
/// </summary>
/// <param name="from">开始日期</param>
/// <param name="to">结束日期</param>
/// <param name="systemDate">当前系统交易日</param>
/// <param name="serverDateTime">当前服务器时间</param>
/// <param name="dayCount">使用的DayCount</param>
/// <param name="hasNightMarket">是否有夜盘</param>
/// <param name="precisionOfMinute">是否精确到分钟</param>
/// <returns></returns>
public static double CalculateTTMDays(DateTime from, DateTime to, DateTime systemDate, DateTime serverDateTime, IDayCount dayCount, bool hasNightMarket, bool precisionOfMinute)
{
var tempFrom = new Date(from);
var tempTo = new Date(to);
var days = dayCount.DaysInPeriod(tempFrom, tempTo);
//当交易日期不等于系统日期时,或者系统日期小于服务器日期时,默认加一天
double addDays = 1;
if (PS.Config.Is润和)
{
//东证润和
addDays = GetAddDaysWithPhysicalPrecisionOfMinute(serverDateTime);
}
else
{
//当交易日期等于系统日期时,算出当天剩余的小数天数,然后加上去
if (from.Date == systemDate && systemDate.Date >= serverDateTime.Date)
{
addDays = GetAddDays(serverDateTime, hasNightMarket, precisionOfMinute);
//如果系统日期大于服务器日期(自然日期),而时间大于收盘时间(15点)且小于夜盘开盘时间(21点)
//说明系统在夜盘开始前切换了交易日,此时应将TTM增加完整的一个交易日
if (systemDate.Date > serverDateTime.Date
&& serverDateTime.Hour >= 15 && serverDateTime.Hour < 21)
{
addDays += 1;
}
}
}
var ttmDays = days + addDays;
return ttmDays < 0 ? 0 : ttmDays;
}
/// <summary>
/// 计算精确的TTM
/// </summary>
/// <param name="from">开始日期</param>
/// <param name="to">结束日期</param>
/// <param name="systemDate">当前系统交易日</param>
/// <param name="serverDateTime">当前服务器时间</param>
/// <param name="dayCount">使用的DayCount</param>
/// <param name="hasNightMarket">是否有夜盘</param>
/// <param name="precisionOfMinute">是否精确到分钟</param>
/// <returns></returns>
public static double CalculateTTMDaysForXiangYu(DateTime from, DateTime to, DateTime systemDate, DateTime serverDateTime, IDayCount dayCount, bool hasNightMarket, bool precisionOfMinute)
{
//最后一天平仓时,ttm按分钟算
//平仓日和系统交易日相等时,服务器时间的判断才有意义
if (from == to && from <= systemDate)
{
if (serverDateTime.TimeOfDay < new TimeSpan(10, 15, 0))//判断当前时间是否是十点十五分前
{
//计算从前一天21点到现在经过的时间;
double Secondsum = (serverDateTime.Hour + 3) * 60 + serverDateTime.Minute;
var value = (795 - Secondsum) / 795d;
return value;
}
else if (systemDate.Date > serverDateTime.Date && serverDateTime.Hour >= 15)//当系统交易日大于当前服务器时间且系统时间大于15点时,说明系统切过日期,且最后一个交易日的夜盘开始了.
{
//夜盘时段计算从21点到现在经过的分钟;
double Secondsum = serverDateTime.Hour < 21 ? 0 : ((serverDateTime.Hour - 21) * 60 + serverDateTime.Minute);
//795 = 13 * 60 + 15
var value = (795 - Secondsum) / 795d;
return value;
}
else//否则就是已经过期了;
{
return 0;
}
}
return CalculateTTMDays(from, to, systemDate, serverDateTime, dayCount, hasNightMarket, precisionOfMinute);
}
/// <summary>
/// 获取交易当天需要添加的小数天数
/// </summary>
/// <param name="variety">品种</param>
/// <param name="precisionOfMinute">是否要精确到分钟级别</param>
/// <returns></returns>
public static double GetAddDays(DateTime now, bool hasNightMarket, bool precisionOfMinute = false)
{
return precisionOfMinute
? GetAddDaysWithPrecisionOfMinute(now, hasNightMarket)
: GetAddDaysWithPrecisionOfHalfDay(now, hasNightMarket);
}
/// <summary>
/// 获取交易当天需要添加的小数天数,精确到半天,夜盘精确到三分之一天
/// </summary>
/// <param name="variety">品种</param>
/// <returns></returns>
private static double GetAddDaysWithPrecisionOfHalfDay(DateTime now, bool hasNightMarket)
{
if (hasNightMarket)
{
if (now.Hour >= 21)
{
return 1;
}
else if (now.Hour >= 0 && now.Hour < 12)
{
return 0.6666;
}
else if (now.Hour >= 12 && now.Hour < 15)
{
return 0.3333;
}
else
{
return 0;
}
}
else
{
if (now.Hour >= 21 || (now.Hour >= 0 && now.Hour < 12))
{
return 1;
}
else if (now.Hour >= 12 && now.Hour < 15)
{
return 0.5;
}
else
{
return 0;
}
}
}
/// <summary>
/// 在日内计算精确到分钟级别的TTM调整
/// 假设所有夜盘交易时间都为2小时
/// 上午交易时间为2.5小时,下午为1.5小时
///
/// 单元测试: GetAddDaysWithPrecisionOfMinuteTest
/// </summary>
/// <param name="hasNightMarket"></param>
/// <returns></returns>
private static double GetAddDaysWithPrecisionOfMinute(DateTime now, bool hasNightMarket)
{
return AnalyticalOptionPricerUtil.timeToMaturityFractionOnMaturityDate(now.TimeOfDay, hasNightMarket, false);
//double past;
//var totalTradingMiniutes = hasNightMarket ? (2 + 2.5 + 1.5) * 60 : (2.5 + 1.5) * 60;
//if (hasNightMarket)
//{
// if (now.Hour >= 21 && now.Hour < 23)
// {
// past = (now.Hour - 21) * 60 + now.Minute;
// }
// else if (now.Hour >= 23)
// {
// past = 2 * 60;
// }
// else if (now.Hour < 9)
// {
// past = 2 * 60;
// }
// else if ((now.Hour >= 9 && now.Hour <= 10) || (now.Hour == 11 && now.Minute <= 30))
// {
// past = 2 * 60 + (now.Hour - 9) * 60 + now.Minute;
// }
// else if ((now.Hour > 11 || (now.Hour == 11 && now.Minute > 30)) && (now.Hour < 13 || (now.Hour == 13 && now.Minute < 30)))
// {
// past = (2 + 2.5) * 60;
// }
// else if (((now.Hour == 13 && now.Minute >= 30) || now.Hour > 13) && (now.Hour < 15))
// {
// past = (2 + 2.5) * 60 + (now.Hour - 13.5) * 60 + now.Minute;
// }
// else if (now.Hour >= 15 && now.Hour < 21)
// {
// past = (2 + 2.5 + 1.5) * 60;
// }
// else
// {
// //should never be here
// throw new Exception("精确到分钟级别的TTM计算错误");
// }
//}
//else
//{
// if ((now.Hour >= 9 && now.Hour <= 10) || (now.Hour == 11 && now.Minute <= 30))
// {
// past = (now.Hour - 9) * 60 + now.Minute;
// }
// else if ((now.Hour > 11 || (now.Hour == 11 && now.Minute > 30)) && (now.Hour < 13 || (now.Hour == 13 && now.Minute < 30)))
// {
// past = 2.5 * 60;
// }
// else if (((now.Hour == 13 && now.Minute >= 30) || now.Hour > 13) && (now.Hour < 15))
// {
// past = 2.5 * 60 + (now.Hour - 13.5) * 60 + now.Minute;
// }
// else if (now.Hour >= 15 && now.Hour < 21)
// {
// past = (2.5 + 1.5) * 60;
// }
// else if (now.Hour >= 21 || now.Hour < 9)
// {
// past = 0;
// }
// else
// {
// //should never be here
// throw new Exception("精确到分钟级别的TTM计算错误");
// }
//}
//if (hasNightMarket)
//{
// if (now.Hour >= 21 && now.Hour < 23)
// {
// past = (now.Hour - 21) * 60 + now.Minute;
// }
// else if (now.Hour >= 23)
// {
// past = 2 * 60;
// }
// else if (now.Hour < 9)
// {
// past = 2 * 60;
// }
// else if (now.Hour >= 9 && (now.Hour <= 11 && now.Minute <= 30))
// {
// past = 2 * 60 + (now.Hour - 9) * 60 + now.Minute;
// }
// else if ((now.Hour >= 11 || (now.Hour == 11 && now.Minute > 30)) && (now.Hour <= 13 || (now.Hour == 13 && now.Minute < 30)))
// {
// past = (2 + 2.5) * 60;
// }
// else if ((now.Hour >= 13 && now.Minute >= 30) && now.Hour < 15)
// {
// past = (2 + 2.5) * 60 + (now.Hour - 13.5) * 60 + now.Minute;
// }
// else if (now.Hour >= 15 && now.Hour < 21)
// {
// past = (2 + 2.5 + 1.5) * 60;
// }
// else
// {
// //should never be here
// throw new Exception("精确到分钟级别的TTM计算错误");
// }
//}
//else
//{
// if (now.Hour >= 9 && (now.Hour <= 11 && now.Minute <= 30))
// {
// past = (now.Hour - 9) * 60 + now.Minute;
// }
// else if ((now.Hour >= 11 || (now.Hour == 11 && now.Minute > 30)) && (now.Hour <= 13 || (now.Hour == 13 && now.Minute < 30)))
// {
// past = 2.5 * 60;
// }
// else if ((now.Hour >= 13 && now.Minute >= 30) && (now.Hour < 15))
// {
// past = 2.5 * 60 + (now.Hour - 13.5) * 60 + now.Minute;
// }
// else if (now.Hour >= 15 && now.Hour < 21)
// {
// past = (2.5 + 1.5) * 60;
// }
// else if (now.Hour >= 21 || now.Hour < 9)
// {
// past = 0;
// }
// else
// {
// //should never be here
// throw new Exception("精确到分钟级别的TTM计算错误");
// }
//}
//return (totalTradingMiniutes - past) / totalTradingMiniutes;
}
/// <summary>
/// 当天剩余的分钟数 / 一天总的分钟数
/// </summary>
/// <param name="now"></param>
/// <returns></returns>
private static double GetAddDaysWithPhysicalPrecisionOfMinute(DateTime now)
{
double totalTradingMiniutes = 24 * 60;
double past = now.Hour * 60 + now.Minute;
//到期日按照3点来算,所以需要把剩余的9个小时扣除
double minusNineHour = 9 * 60;
return (totalTradingMiniutes - past - minusNineHour) / totalTradingMiniutes;
}
/// <summary>
/// 创建一个无风险利率曲线
/// </summary>
public static InstrumentCurveDefinition CreateRiskFreeCurve(string curveName, double riskFreeRate, string curveDayCount = "Act365")
{
//创建一个Flat curve
var rateMktDataList = new List<RateMktData>
{
new RateMktData("1D", riskFreeRate, "Spot", "None", curveName),
new RateMktData("3Y", riskFreeRate, "Spot", "None", curveName)
};
if (string.IsNullOrWhiteSpace(curveDayCount))
{
curveDayCount = "Act365";
}
var curveConvention = new CurveConvention(Guid.NewGuid().ToString(), "CNY", "ModifiedFollowing", "chn", curveDayCount, "Continuous", "Linear");
return new InstrumentCurveDefinition(curveName, curveConvention, rateMktDataList.ToArray(), "SpotCurve");
}
}
}