165 lines
6.8 KiB
C#
165 lines
6.8 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.Ecosystem.Market;
|
|
using Qdp.Pricing.Ecosystem.Market.BuiltObjects;
|
|
using Qdp.Pricing.Ecosystem.Utilities;
|
|
using Qdp.Pricing.Library.Base.Curves.Interfaces;
|
|
using Qdp.Pricing.Library.Common.Interfaces;
|
|
using Qdp.Pricing.Library.Common.Market;
|
|
|
|
namespace YLErp.Modules.CalcModules
|
|
{
|
|
internal class QdpTestHelper
|
|
{
|
|
/// <summary>
|
|
/// Generate observation dates given start/end date and term
|
|
/// </summary>
|
|
/// <param name="calendar"></param>
|
|
/// <param name="startDate"></param>
|
|
/// <param name="maturityDate"></param>
|
|
/// <param name="term"></param>
|
|
/// <param name="bdc"></param>
|
|
/// <returns></returns>
|
|
public static Date[] GenerateObservationDates(ICalendar calendar, Date startDate, Date maturityDate, Term term = null, BusinessDayConvention bdc = BusinessDayConvention.None)
|
|
{
|
|
if (term == null || (term.Length == 1 && term.Period == Period.Day))
|
|
{
|
|
return calendar.BizDaysBetweenDatesExcluStartDay(startDate, maturityDate).Union(new[] { maturityDate }).ToArray();
|
|
}
|
|
else
|
|
{
|
|
var qdpStart = new Date(startDate);
|
|
var qdpEnd = new Date(maturityDate);
|
|
var dates = new List<Date>();
|
|
|
|
while (qdpEnd > qdpStart)
|
|
{
|
|
dates.Add(qdpEnd);
|
|
qdpEnd = term.Prev(qdpEnd);
|
|
}
|
|
|
|
dates = dates.Select(d => calendar.Adjust(d, bdc)).Distinct().ToList();
|
|
|
|
dates.Reverse();
|
|
return dates.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// create market
|
|
/// </summary>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="vol"></param>
|
|
/// <param name="spot"></param>
|
|
/// <param name="riskFreeRate"></param>
|
|
/// <param name="dividendRate"></param>
|
|
/// <returns></returns>
|
|
public static IMarketCondition CreateMarket(Date valueDate, Double vol = 0.28, Double spot = 1.0,
|
|
double riskFreeRate = 0.035, double dividendRate = 0)
|
|
{
|
|
return CreateMarket(valueDate.ToString(), vol, spot, riskFreeRate, dividendRate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// create market
|
|
/// </summary>
|
|
/// <param name="referenceDate"></param>
|
|
/// <param name="vol"></param>
|
|
/// <param name="spot"></param>
|
|
/// <param name="riskFreeRate"></param>
|
|
/// <param name="dividendRate"></param>
|
|
/// <returns></returns>
|
|
public static IMarketCondition CreateMarket(String referenceDate = "2015-03-19", Double vol = 0.28, Double spot = 1.0,
|
|
double riskFreeRate = 0.035, double dividendRate = 0)
|
|
{
|
|
var historiclIndexRates = HistoricalDataLoadHelper.HistoricalIndexRates;
|
|
|
|
var curveConvention = new CurveConvention("fr007CurveConvention",
|
|
"CNY",
|
|
"ModifiedFollowing",
|
|
"Chn",
|
|
"Act365",
|
|
"Continuous",
|
|
"CubicHermiteMonotic");
|
|
|
|
var fr007CurveName = "Fr007";
|
|
var fr007RateDefinition = new[]
|
|
{
|
|
new RateMktData("1D", riskFreeRate, "Spot", "None", fr007CurveName),
|
|
new RateMktData("5Y", riskFreeRate, "Spot", "None", fr007CurveName),
|
|
};
|
|
|
|
var dividendCurveName = "Dividend";
|
|
var dividendRateDefinition = new[]
|
|
{
|
|
new RateMktData("1D", dividendRate, "Spot", "None", dividendCurveName),
|
|
new RateMktData("5Y", dividendRate, "Spot", "None", dividendCurveName),
|
|
};
|
|
|
|
var curveDefinition = new[]
|
|
{
|
|
new InstrumentCurveDefinition(fr007CurveName, curveConvention, fr007RateDefinition, "SpotCurve"),
|
|
new InstrumentCurveDefinition(dividendCurveName, curveConvention, dividendRateDefinition, "SpotCurve"),
|
|
};
|
|
|
|
var volSurf = new[] { new VolSurfMktData("VolSurf", vol), };
|
|
|
|
var marketInfo = new MarketInfo("tmpMarket", referenceDate, curveDefinition, historiclIndexRates, null, null, volSurf);
|
|
var result = MarketFunctions.BuildMarket(marketInfo, out var market);
|
|
var volsurf = market.GetData<VolSurfMktData>("VolSurf").ToImpliedVolSurface(market.ReferenceDate);
|
|
|
|
|
|
return new MarketCondition(
|
|
x => x.ValuationDate.Value = market.ReferenceDate,
|
|
x => x.DiscountCurve.Value = market.GetData<CurveData>("Fr007").YieldCurve,
|
|
x => x.DividendCurves.Value = new Dictionary<string, IYieldCurve> { { "", market.GetData<CurveData>("Dividend").YieldCurve } },
|
|
x => x.VolSurfaces.Value = new Dictionary<string, IVolSurface> { { "", volsurf } },
|
|
x => x.SpotPrices.Value = new Dictionary<string, double> { { "", spot } }
|
|
);
|
|
}
|
|
}
|
|
|
|
public class HistoricalDataLoadHelper
|
|
{
|
|
public static readonly Dictionary<string, Dictionary<string, double>> HistoricalIndexRates;
|
|
|
|
public static readonly Dictionary<IndexType, SortedDictionary<Date, double>> HistoricalIndexRatesMarket;
|
|
|
|
static HistoricalDataLoadHelper()
|
|
{
|
|
HistoricalIndexRates = new Dictionary<string, Dictionary<string, double>>();
|
|
HistoricalIndexRatesMarket = new Dictionary<IndexType, SortedDictionary<Date, double>>();
|
|
var files = Directory.GetFiles(@".\Data\HistoricalIndexRates");
|
|
|
|
foreach (var file in files)
|
|
{
|
|
var shortName = Path.GetFileNameWithoutExtension(file);
|
|
if (Enum.TryParse(shortName, out IndexType indexType))
|
|
{
|
|
var temp = new Dictionary<string, double>();
|
|
var temp1 = new SortedDictionary<Date, double>();
|
|
var lines = File.ReadAllLines(file);
|
|
foreach (var line in lines)
|
|
{
|
|
var splits = line.Split(',');
|
|
temp[splits[0]] = Convert.ToDouble(splits[1]);
|
|
temp1[splits[0].ToDate()] = Convert.ToDouble(splits[1]);
|
|
}
|
|
HistoricalIndexRates[shortName] = temp;
|
|
HistoricalIndexRatesMarket[shortName.ToIndexType()] = temp1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Dictionary<string, double> GetIndexRates(string indexType)
|
|
{
|
|
return HistoricalIndexRates[indexType];
|
|
}
|
|
}
|
|
}
|