// return a cloned List of RateSet with shifted value (for example ShiftedRateSet(1, 0.0005) will shift element #1 adding 0.0005 ) public RateSet ShiftedRateSet(int Index, double Shift) { RateSet newRateSet = this.Clone(); // clone the obj newRateSet.ShiftValue(Index, Shift); // shift 'Index' element of newRateSet up of 'Shift' value return(newRateSet); }
public RateSettings() { RateSets = new RateSetCollection(); RateSet set = new RateSet(); set.RateItems = new RateSetItemCollection(); RateSetItem item = new RateSetItem(); item.MaxValue = 50; item.MinValue = -50; item.MaxValueInTime = 100; item.PointType = UserPointType.Point1; item.RoleID = Guid.Empty; set.RateItems.Add(item); item = new RateSetItem(); item.MaxValue = 1000; item.MinValue = -1000; item.MaxValueInTime = 100000; item.PointType = UserPointType.Point1; item.RoleID = Role.Owners.RoleID; item.RoleSortOrder = 0; set.RateItems.Add(item); item = new RateSetItem(); item.MaxValue = 1000; item.MinValue = -1000; item.MaxValueInTime = 100000; item.PointType = UserPointType.Point2; item.RoleID = Role.Owners.RoleID; item.RoleSortOrder = 0; set.RateItems.Add(item); RateSets.Add(set); }
public void Run(string customDataJson) { using (var response = s_client.GetAsync(c_cnbRateLink).Result) { var text = response.Content.ReadAsStringAsync().Result; var rates = new RateSet(text); var currencies = m_currencyRepository.GetAllCurrencies().ToList(); var mainCurrency = currencies.FirstOrDefault(c => c.IsProjectMainCurrency); if (mainCurrency == null) { throw new InvalidOperationException("Project has no default currency defined"); } foreach (var c in currencies.Where(c => !c.IsProjectMainCurrency)) { RateModel model; if (!rates.Rates.TryGetValue(c.Symbol, out model)) { continue; } m_currencyRepository.SetCurrencyRate(c, mainCurrency, model.Rate / model.Amount, rates.RateDt, $"head:{rates.Header} link:{c_cnbRateLink}"); } } }
// Modify the class. Apply a shift in rate value of Shift ( ShiftValue(0,0.01) means 0.01 for first element) public void ShiftValue(int Index, double Shift) { RateSet newRateSet = ((RateSet)List[Index]); // get 'Index' element newRateSet.SetValue(newRateSet.V + Shift); // set new value List[Index] = newRateSet; }
// Members // Add a rate public void Add(double Value, string Maturity, BuildingBlockType Type) { RateSet aRate = new RateSet(Value, Maturity, Type); aRate.refDate = this.refDate; // get the same ref Date. Needed in CompareTo List.Add(aRate); }
protected void PrePorcessData(RateSet rateSetMC, ISingleRateCurve DiscountingCurve) { this.refDate = rateSetMC.refDate; this.DCurve = DiscountingCurve; // my curve used in discounting FWDInterpolator = new Interpolation(); // Interpolator used in fwd this.mktRateSet = rateSetMC; // pass market rate set // Create Building block IEnumerable <BuildingBlock> BB = mktRateSet.GetArrayOfBB(); // Sort ascending end date BBArray = from c in BB orderby c.endDate.SerialValue ascending select c; // Only Given Swap from BBArray OnlyGivenSwap = (from c in BBArray where c.GetType().BaseType == typeof(SwapStyle) select(SwapStyle) c).ToArray(); // validating underlying tenor: swap should be all vs the same tenor string UnderlyingTenor = ((SwapStyle)OnlyGivenSwap.First()).swapLeg2.UnderlyingRateTenor; // Getting the fixing fixing = (from c in BBArray where c.GetType().BaseType == typeof(OnePaymentStyle) where c.endDate == refDate.add_period(UnderlyingTenor) select c.rateValue).Single(); // From date of each fwd rate from longer swap(LS) // FromDatesSerial = Date.GetSerialValue(OnlyGivenSwap.Last().scheduleLeg2.fromDates); List <double> SerialDate = (from c in OnlyGivenSwap select c.scheduleLeg2.fromDates.Last().SerialValue).ToList <double>(); // adding reference date at beginning (this is important since I use the fixing) SerialDate.Insert(0, refDate.SerialValue); FromDatesSerial = SerialDate.ToArray(); // some data validation: swap should be all of same building block // the type of building block BuildingBlockType BBT = OnlyGivenSwap[0].buildingBlockType; // Are all them the same? bool IsSameSwapType = OnlyGivenSwap.All(s => s.buildingBlockType == BBT); if (IsSameSwapType) // if true { // it is swap type used as inputs (i.e. EurSwapVs6m, EurSwapVs3m, ...) SwapType = (SwapStyle) new BuildingBlockFactory().CreateEmptyBuildingBlock(BBT); } else { throw new ArgumentException("error in building blocktype"); // if not throw an exception } }
// return a cloned List of RateSet with parallel shift from starting List (i.e. each element is shifted for same value) public RateSet ParallelShiftRateSet(double Shift) { RateSet newRateSet = this.Clone(); foreach (RateSet r in newRateSet) { r.V += Shift; // parallel shift } return(newRateSet); }
public static void SwaptionSimple() { // Start input // ref date Date refDate = new Date(2012, 3, 16); #region Swap Market Data // RateSet EUR 6m swap RateSet rs = new RateSet(refDate); rs.Add(1.256e-2, "6m", BuildingBlockType.EURDEPO); rs.Add(1.076e-2, "1y", BuildingBlockType.EURSWAP6M); rs.Add(1.017e-2, "2y", BuildingBlockType.EURSWAP6M); rs.Add(1.11e-2, "3y", BuildingBlockType.EURSWAP6M); rs.Add(1.289e-2, "4y", BuildingBlockType.EURSWAP6M); rs.Add(1.489e-2, "5y", BuildingBlockType.EURSWAP6M); rs.Add(1.682e-2, "6y", BuildingBlockType.EURSWAP6M); rs.Add(1.853e-2, "7y", BuildingBlockType.EURSWAP6M); rs.Add(1.995e-2, "8y", BuildingBlockType.EURSWAP6M); rs.Add(2.113e-2, "9y", BuildingBlockType.EURSWAP6M); rs.Add(2.214e-2, "10y", BuildingBlockType.EURSWAP6M); rs.Add(2.301e-2, "11y", BuildingBlockType.EURSWAP6M); rs.Add(2.378e-2, "12y", BuildingBlockType.EURSWAP6M); rs.Add(2.439e-2, "13y", BuildingBlockType.EURSWAP6M); rs.Add(2.488e-2, "14y", BuildingBlockType.EURSWAP6M); rs.Add(2.524e-2, "15y", BuildingBlockType.EURSWAP6M); rs.Add(2.551e-2, "16y", BuildingBlockType.EURSWAP6M); rs.Add(2.567e-2, "17y", BuildingBlockType.EURSWAP6M); rs.Add(2.576e-2, "18y", BuildingBlockType.EURSWAP6M); rs.Add(2.579e-2, "19y", BuildingBlockType.EURSWAP6M); rs.Add(2.577e-2, "20y", BuildingBlockType.EURSWAP6M); rs.Add(2.571e-2, "21y", BuildingBlockType.EURSWAP6M); rs.Add(2.563e-2, "22y", BuildingBlockType.EURSWAP6M); rs.Add(2.554e-2, "23y", BuildingBlockType.EURSWAP6M); rs.Add(2.543e-2, "24y", BuildingBlockType.EURSWAP6M); rs.Add(2.532e-2, "25y", BuildingBlockType.EURSWAP6M); rs.Add(2.52e-2, "26y", BuildingBlockType.EURSWAP6M); rs.Add(2.509e-2, "27y", BuildingBlockType.EURSWAP6M); rs.Add(2.498e-2, "28y", BuildingBlockType.EURSWAP6M); rs.Add(2.488e-2, "29y", BuildingBlockType.EURSWAP6M); rs.Add(2.479e-2, "30y", BuildingBlockType.EURSWAP6M); #endregion // I build curve, SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator> Curve = new SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator>(rs, OneDimensionInterpolation.LogLinear); // discount curve double p = Formula.Swaption(1, 0.01, "1y", "3y", true, 0.50, Curve); Console.WriteLine(p); #region Hull example double[] yf = new double[] { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 }; double[] df = new double[] { Math.Exp(-0.06 * 5.5), Math.Exp(-0.06 * 6), Math.Exp(-0.06 * 6.5), Math.Exp(-0.06 * 7), Math.Exp(-0.06 * 7.5), Math.Exp(-0.06 * 8) }; double pp = Formula.Swaption(100, 0.0609, 0.062, 0.2, 5, true, yf, df); #endregion Console.WriteLine(pp); }
string IRate.AddMultiCurve(string idCode, double RefDate, object DfTenor, object DfRates, string DfType, object FwdTenor, object FwdRates, string FwdType, string FixingTenor, double FixingValue) { #region Market Rates for discounting RateSet dfMktRates = new RateSet(new Date(RefDate)); double[] dfRates = (double[])DfRates; string[] dfTenor = (string[])DfTenor; int MaxDfRates = dfTenor.Count(); BuildingBlockType dfType = (BuildingBlockType)Enum.Parse(typeof(BuildingBlockType), DfType); for (int i = 0; i < MaxDfRates; i++) { dfMktRates.Add(dfRates[i], dfTenor[i], dfType); } #endregion #region Market Rates for forwarding RateSet fwdMktRates = new RateSet(new Date(RefDate)); double[] fwdRates = (double[])FwdRates; string[] fwdTenor = (string[])FwdTenor; int MaxFwdRates = fwdTenor.Count(); BuildingBlockType fwdType = (BuildingBlockType)Enum.Parse(typeof(BuildingBlockType), FwdType); fwdMktRates.Add(FixingValue, FixingTenor, BuildingBlockType.EURDEPO); for (int i = 0; i < MaxFwdRates; i++) { fwdMktRates.Add(fwdRates[i], fwdTenor[i], fwdType); } #endregion #region InizializeMyCurve SingleCurveBuilderStandard <OnDf, LinearInterpolator> DCurve = new SingleCurveBuilderStandard <OnDf, LinearInterpolator>(dfMktRates, OneDimensionInterpolation.Linear); MultiCurveBuilder <SimpleCubicInterpolator> MultiCurve = new MultiCurveBuilder <SimpleCubicInterpolator>(fwdMktRates, DCurve); #endregion #region UpDating Dictionary try { if (MCDictionary.ContainsKey(idCode) == true) // check if idCode is in dictionary { MCDictionary[idCode] = MultiCurve; // if true, updates it } else { MCDictionary.Add(idCode, MultiCurve); // if false, adds it } return("Loaded @ " + DateTime.Now.ToString()); // return time of last load } catch (Exception e) { return((string)e.ToString()); } #endregion }
// To clone rate public RateSet Clone() { RateSet RateC = new RateSet(this.refDate); int i = this.Count; for (int j = 0; j < i; j++) { RateC.Add(this.Item(j).V, this.Item(j).M.GetPeriodStringFormat(), this.Item(j).T); } return(RateC); }
// return array of List of rate set. i-element of output array is a List of rate set shifted @ i element public RateSet[] ShiftedRateSetArray(double shift) { int n = List.Count; RateSet[] rsArr = new RateSet[n]; for (int i = 0; i < n; i++) { rsArr[i] = this.ShiftedRateSet(i, shift); // populate each element (i.e. List of rate set)of output } return(rsArr); }
protected SortedList <double, double> IniGuessData; // serial date as key, df as value coming only from swap. Ini Guess for iterator // protected IEnumerable<BuildingBlock> OnlyGivenSwap; // Only Given Swap from BBArray // Constructor public SingleCurveBuilderInterpBestFit(RateSet rateSet) : base(rateSet) { // Prepare data to be used in Solve() (output is: PreProcessedData) PreProcessInputs(); // Do Calculus: from PreProcessedData inizialises PostProcessInterpo Solve(); // Not needed for this class since Solve()initialised directly PostProcessInterpo // PostProcessData(); }
// Check if the process will match the starting inputs public static void FwdStartSwap() { #region Inputs // Start input Date refDate = new Date(2021, 10, 11); // ref date, this is only an example // I populate market rates set: from file, from real time, ... here not real data RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(1.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(1.720e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(1.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.787e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs // my curve IRateCurve Curve1 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); #region print output Console.WriteLine("Input Rate (1Y): {0}, ReCalc Rate (1Y): {1} \n\n", 1.869e-2, Curve1.SwapFwd(refDate, "1Y")); // Start and Tenor of each point in my fwd matrix (2Y15Y is a 15Y swap starting in 2Y) string[] Start = new string[] { "1Y", "2Y", "3Y", "5Y", "7Y", "10Y" }; string[] Tenor = new string[] { "1Y", "2Y", "5Y", "7Y", "10Y" }; // print fwd swap matrix using multi curve Console.WriteLine("Matrix using {0}\n", Curve1.ToString()); for (int i = 0; i < Start.Length; i++) { for (int t = 0; t < Tenor.Length; t++) { Console.Write("{0}{1}:{2:P3} ", Start[i], Tenor[t], Curve1.SwapFwd(refDate.add_period(Start[i]), Tenor[t])); } Console.Write("\n\n"); } #endregion end print output }
// Constructor public SingleCurveBuilderSmoothingFwd(RateSet rateSet) : base(rateSet) { // 1)Prepare data to be used in Solve() // (outputs are: yfFloatLegLongerSwap,DatesDfLongerSwap,fwdGuessLongerSwap,N and partially DateDf ) PreProcessInputs(); // 2)Do Calculus: from PreProcessedData calculate post processed data (output is: DataDF) Solve(); // 3)Inizialize final Interpolator: from post processed DataDF set up final interpolator (output is: PostProcessInterpo) PostProcessData(); }
// Calculate the time for initialise a SingleCurveBuilderInterpBestFit public static void TimeForBestFitVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate market rates set: from file, from real time, ... here not real data RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.434e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(2.813e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.096e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.322e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.529e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.709e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.862e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.991e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.101e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.197e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.285e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.443e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.614e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.711e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.671e-2, "25Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.589e-2, "30Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs #region building curve DateTime timer; // initialise the timer timer = DateTime.Now; double firstFixing = 1.434e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); Console.WriteLine("\n{0} \nFitted in {1}", C.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); Console.WriteLine("\n{0} \nFitted in {1}", C1.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Console.WriteLine("\n{0} \nFitted in {1}", C2.ToString(), DateTime.Now - timer); #endregion building curve }
// Calculate the time for initialise a SingleCurveBuilderInterpBestFit public static void TimeForBestFitVs6m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate markets rates set: from file, from real time, ... here not real data RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(2.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(2.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(2.620e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(2.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(4.787e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs #region building curve DateTime timer; timer = DateTime.Now; double firstFixing = 1.62e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); Console.WriteLine("\n{0} \nFitted in {1}", C.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); Console.WriteLine("\n{0} \nFitted in {1}", C1.ToString(), DateTime.Now - timer); timer = DateTime.Now; SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Console.WriteLine("\n{0} \nFitted in {1}", C2.ToString(), DateTime.Now - timer); #endregion building curve }
public RateSet GetRateSet() { // Reference date Date refDate = (new Date(DateTime.Now)).mod_foll(); // Date refDate = new Date(2012, 3, 5); #region Swap Market Data // RateSet EUR 6m swap RateSet rs = new RateSet(refDate); rs.Add(1.256e-2, "6m", BuildingBlockType.EURDEPO); rs.Add(1.076e-2, "1y", BuildingBlockType.EURSWAP6M); rs.Add(1.017e-2, "2y", BuildingBlockType.EURSWAP6M); rs.Add(1.11e-2, "3y", BuildingBlockType.EURSWAP6M); rs.Add(1.289e-2, "4y", BuildingBlockType.EURSWAP6M); rs.Add(1.489e-2, "5y", BuildingBlockType.EURSWAP6M); rs.Add(1.682e-2, "6y", BuildingBlockType.EURSWAP6M); rs.Add(1.853e-2, "7y", BuildingBlockType.EURSWAP6M); rs.Add(1.995e-2, "8y", BuildingBlockType.EURSWAP6M); rs.Add(2.113e-2, "9y", BuildingBlockType.EURSWAP6M); rs.Add(2.214e-2, "10y", BuildingBlockType.EURSWAP6M); rs.Add(2.301e-2, "11y", BuildingBlockType.EURSWAP6M); rs.Add(2.378e-2, "12y", BuildingBlockType.EURSWAP6M); rs.Add(2.439e-2, "13y", BuildingBlockType.EURSWAP6M); rs.Add(2.488e-2, "14y", BuildingBlockType.EURSWAP6M); rs.Add(2.524e-2, "15y", BuildingBlockType.EURSWAP6M); rs.Add(2.551e-2, "16y", BuildingBlockType.EURSWAP6M); rs.Add(2.567e-2, "17y", BuildingBlockType.EURSWAP6M); rs.Add(2.576e-2, "18y", BuildingBlockType.EURSWAP6M); rs.Add(2.579e-2, "19y", BuildingBlockType.EURSWAP6M); rs.Add(2.577e-2, "20y", BuildingBlockType.EURSWAP6M); rs.Add(2.571e-2, "21y", BuildingBlockType.EURSWAP6M); rs.Add(2.563e-2, "22y", BuildingBlockType.EURSWAP6M); rs.Add(2.554e-2, "23y", BuildingBlockType.EURSWAP6M); rs.Add(2.543e-2, "24y", BuildingBlockType.EURSWAP6M); rs.Add(2.532e-2, "25y", BuildingBlockType.EURSWAP6M); rs.Add(2.52e-2, "26y", BuildingBlockType.EURSWAP6M); rs.Add(2.509e-2, "27y", BuildingBlockType.EURSWAP6M); rs.Add(2.498e-2, "28y", BuildingBlockType.EURSWAP6M); rs.Add(2.488e-2, "29y", BuildingBlockType.EURSWAP6M); rs.Add(2.479e-2, "30y", BuildingBlockType.EURSWAP6M); #endregion return(rs); }
private SortedList <double, double> DateDf; // SerialDate as Key, DF as value, used in constructor to collect data coming from PreProcessedData // Constructor public SingleCurveBuilderStandard(RateSet rateSet, OneDimensionInterpolation missingRateInterp) : base(rateSet) { // Constructor arguments // RateSet rateSet: market data input // OneDimensionInterpolation missingRateInterp: interpolation used to find missing data // it interpolates directly on markets rate // To Data Member MissingRateInterp = missingRateInterp; // 1)Prepare data to be used in Solve() (output is: PreProcessedData) PreProcessInputs(); // 2)Do Calculus: from PreProcessedData calculate post processed data (output is: DataDF) Solve(); // 3)Inizialize final Interpolator: from post processed DataDF set up final interpolator (output is: PostProcessInterpo) PostProcessData(); }
public RateSet mktRateSet; // market starting data // constructor: RateSet rateSet are market data inputs public SingleCurveBuilder(RateSet rateSet) { // RefDate refDate = rateSet.refDate; PostProcessInterpo = new Interpolation(); // Post process interpolator interpAdapter = new DoInterpOn(); mktRateSet = rateSet; // Create Building block IEnumerable <BuildingBlock> BB = rateSet.GetArrayOfBB(); // Sort ascending end date BBArray = from c in BB orderby c.endDate.SerialValue ascending select c; // Only Given Swap from BBArray OnlyGivenSwap = (from c in BBArray where c.GetType().BaseType == typeof(SwapStyle) select(SwapStyle) c).ToArray(); // some data validation: swap should be all of same building block // the type of building block BuildingBlockType BBT = OnlyGivenSwap[0].buildingBlockType; // Are all them the same? bool IsSameSwapType = OnlyGivenSwap.All(s => s.buildingBlockType == BBT); if (IsSameSwapType) // if true { // it is swap type used as inputs (i.e. EurSwapVs6m, EurSwapVs3m, ...) SwapType = (SwapStyle) new BuildingBlockFactory().CreateEmptyBuildingBlock(BBT); } else { throw new ArgumentException("error in building blocktype"); // if not throw an exception } }
public static void MyDF(object rateSet) { object[] o = (object[])rateSet; RateSet rs = (RateSet)o[0]; RateSet myRateSet = new RateSet((Date)o[1]); foreach (RateSet r in rs) { myRateSet.Add(r.V, r.M.GetPeriodStringFormat(), r.T); } Date dfDate = new Date(2025, 8, 15); double fixing = (double)o[2]; #region building curve SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(myRateSet, fixing); Console.WriteLine("Ref. {0:D}: DF: {1:F5}", myRateSet.refDate.DateValue, C.DF(dfDate)); #endregion building curve }
// Print on excel forward rate using different curve builder for 3m public static void CheckFwdRatesVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(0.434e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(0.813e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.096e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.322e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.529e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.709e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.862e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(1.991e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.101e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.197e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.285e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.443e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.614e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.711e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.671e-2, "25Y", BuildingBlockType.EURSWAP3M); mktRates.Add(2.589e-2, "30Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs #region building curve SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); double firstFixing = 0.434e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> C2 = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates, firstFixing); SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C3 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); #endregion end building curve List <IRateCurve> CurveList = new List <IRateCurve>(); // list containing curve List <string> CurveString = new List <string>(); // list containing labels // populate lists CurveList.Add(C1); CurveString.Add(C1.ToString()); CurveList.Add(C2); CurveString.Add(C2.ToString()); CurveList.Add(C3); CurveString.Add(C3.ToString()); #region printing output // I get the longer swap SwapStyle LS = (SwapStyle)mktRates.GetArrayOfBB().Last(); Dc dc = Dc._Act_360; Date[] FromDate = LS.scheduleLeg2.fromDates; Date[] ToDate = LS.scheduleLeg2.toDates; int N = FromDate.Length; List <Vector <double> > Fwds = new List <Vector <double> >(); double[] dt = new double[N]; for (int i = 0; i < N; i++) { dt[i] = FromDate[0].YF(ToDate[i], Dc._30_360); } foreach (IRateCurve myC in CurveList) { double[] fwd = new double[N]; for (int i = 0; i < N; i++) { double yf = FromDate[i].YF(ToDate[i], dc); double df_ini = myC.Df(FromDate[i]); double df_end = myC.Df(ToDate[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } Fwds.Add(new Vector <double>(fwd)); } ExcelMechanisms exl = new ExcelMechanisms(); exl.printInExcel(new Vector <double>(dt), CurveString, Fwds, "Fwd vs 3M", "time", "rate"); // .printInExcel<T> #endregion end printing output }
private void Delete() { m_Success = false; MessageDisplay msgDisplay = CreateMessageDisplay(); int nodeID = _Request.Get <int>("nodeID", Method.Get, 0); if (CurrentRateSet.NodeID != nodeID) { msgDisplay.AddError("当前版块评分设置继承至上级版块,不能进行删除操作,如要修改请修改上级版块评分设置或者把评分设置设为自定义"); return; } if (PointType == null) { msgDisplay.AddError(new InvalidParamError("pointtype")); return; } int sortOrder = _Request.Get <int>("sortorder", Method.Get, 0); RateSettings setting = new RateSettings(); setting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != nodeID) { setting.RateSets.Add(set); } else { RateSet tempSet = new RateSet(); tempSet.NodeID = nodeID; tempSet.RateItems = new RateSetItemCollection(); for (int i = 0; i < set.RateItems.Count; i++) { RateSetItem item = set.RateItems[i]; if (item.PointType == PointType.Value && sortOrder == item.RoleSortOrder && item.RoleID != Guid.Empty) { } else { tempSet.RateItems.Add(item); } } setting.RateSets.Add(tempSet); } } try { if (!SettingManager.SaveSettings(setting)) { CatchError <ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else { string urlRef = Request.UrlReferrer.ToString(); string query; int index = urlRef.IndexOf('?'); if (index > 0) { query = urlRef.Substring(index + 1); } else { query = string.Empty; } string url = Request.RawUrl; if (url.IndexOf('?') > -1) { url = url.Substring(0, url.IndexOf('?')); } url = url + "?" + query; BbsRouter.JumpToUrl(url, "success=true"); } //Response.Redirect(Request.UrlReferrer.ToString()); } catch (Exception ex) { msgDisplay.AddError(ex.Message); } }
public bool saveSettings() { m_Success = false; MessageDisplay msgDisplay = null; if (_Request.Get("inheritType", Method.Post, "False").ToLower() == "true") { msgDisplay = CreateMessageDisplay(); RateSettings tempSetting = new RateSettings(); tempSetting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != ForumID) { tempSetting.RateSets.Add(set); } } try { if (!SettingManager.SaveSettings(tempSetting)) { CatchError <ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else { BbsRouter.JumpToUrl(Request.RawUrl, "success=true"); } } catch (Exception ex) { msgDisplay.AddError(ex.Message); } return(true); } string[] errorNames = new string[EnabledUserPointList.Count * 2]; int i = 0; foreach (UserPoint point in EnabledUserPointList) { errorNames[i] = point.Type.ToString(); i++; errorNames[i] = "new_" + point.Type.ToString(); i++; } msgDisplay = CreateMessageDisplay(errorNames); RateSetItemCollection tempRankItems = new RateSetItemCollection(); foreach (UserPoint point in EnabledUserPointList) { int[] tempIds = StringUtil.Split <int>(_Request.Get("id_" + point.Type.ToString(), Method.Post, string.Empty)); List <int> sortOrdes = new List <int>(); RateSetItem item; foreach (int id in tempIds) { item = GetRankSetItem(point.Type, id, false, msgDisplay); if (item != null) { if (id != 0 && sortOrdes.Contains(item.RoleSortOrder) && msgDisplay.HasAnyError() == false) { msgDisplay.AddError(point.Type.ToString(), id, "排序数字不能重复"); } else { if (id != 0) { sortOrdes.Add(item.RoleSortOrder); } tempRankItems.Add(item); } } } item = GetRankSetItem(point.Type, 0, true, msgDisplay); if (item != null) { if (sortOrdes.Contains(item.RoleSortOrder) && msgDisplay.HasAnyError() == false) { msgDisplay.AddError("new_" + point.Type.ToString(), "排序数字不能重复"); } tempRankItems.Add(item); } } if (msgDisplay.HasAnyError()) { return(false); } RateSet rateSet = new RateSet(); rateSet.NodeID = ForumID; rateSet.RateItems = tempRankItems; RateSettings setting = new RateSettings(); setting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != ForumID) { setting.RateSets.Add(set); } } setting.RateSets.Add(rateSet); try { if (!SettingManager.SaveSettings(setting)) { CatchError <ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else { BbsRouter.JumpToUrl(Request.RawUrl, "success=true"); } } catch (Exception ex) { msgDisplay.AddError(ex.Message); } return(true); }
// sensitivities/DVO1. ATM swap has no sensitivities with respect to the discount curve public static void SensitivitiesParallel() { #region Inputs // Start input // Start input, reference date. Date refDate = (new Date(DateTime.Now)).mod_foll(); #region Eonia market data // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); mktRates.Add(0.447e-2, "1w", BuildingBlockType.EONIASWAP); mktRates.Add(0.583e-2, "2w", BuildingBlockType.EONIASWAP); mktRates.Add(0.627e-2, "3w", BuildingBlockType.EONIASWAP); mktRates.Add(0.635e-2, "1m", BuildingBlockType.EONIASWAP); mktRates.Add(0.675e-2, "2m", BuildingBlockType.EONIASWAP); mktRates.Add(0.705e-2, "3m", BuildingBlockType.EONIASWAP); mktRates.Add(0.734e-2, "4m", BuildingBlockType.EONIASWAP); mktRates.Add(0.758e-2, "5m", BuildingBlockType.EONIASWAP); mktRates.Add(0.780e-2, "6m", BuildingBlockType.EONIASWAP); mktRates.Add(0.798e-2, "7m", BuildingBlockType.EONIASWAP); mktRates.Add(0.816e-2, "8m", BuildingBlockType.EONIASWAP); mktRates.Add(0.834e-2, "9m", BuildingBlockType.EONIASWAP); mktRates.Add(0.849e-2, "10m", BuildingBlockType.EONIASWAP); mktRates.Add(0.864e-2, "11m", BuildingBlockType.EONIASWAP); mktRates.Add(0.878e-2, "1Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.098e-2, "2Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.36e-2, "3Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.639e-2, "4Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.9e-2, "5Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.122e-2, "6Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.308e-2, "7Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.467e-2, "8Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.599e-2, "9Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.715e-2, "10Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.818e-2, "11Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.908e-2, "12Y", BuildingBlockType.EONIASWAP); // From here interpolation is need mktRates.Add(3.093e-2, "15Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.173e-2, "20Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.114e-2, "25Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.001e-2, "30Y", BuildingBlockType.EONIASWAP); #endregion #region Swap Market Data // RateSet EUR 6m swap RateSet rs = new RateSet(refDate); rs.Add(1.16e-2, "6m", BuildingBlockType.EURDEPO); rs.Add(1.42e-2, "1y", BuildingBlockType.EURSWAP6M); rs.Add(1.635e-2, "2y", BuildingBlockType.EURSWAP6M); rs.Add(1.872e-2, "3y", BuildingBlockType.EURSWAP6M); rs.Add(2.131e-2, "4y", BuildingBlockType.EURSWAP6M); rs.Add(2.372e-2, "5y", BuildingBlockType.EURSWAP6M); rs.Add(2.574e-2, "6y", BuildingBlockType.EURSWAP6M); rs.Add(2.743e-2, "7y", BuildingBlockType.EURSWAP6M); rs.Add(2.886e-2, "8y", BuildingBlockType.EURSWAP6M); rs.Add(3.004e-2, "9y", BuildingBlockType.EURSWAP6M); rs.Add(3.107e-2, "10y", BuildingBlockType.EURSWAP6M); rs.Add(3.198e-2, "11y", BuildingBlockType.EURSWAP6M); rs.Add(3.278e-2, "12y", BuildingBlockType.EURSWAP6M); rs.Add(3.344e-2, "13y", BuildingBlockType.EURSWAP6M); rs.Add(3.398e-2, "14y", BuildingBlockType.EURSWAP6M); rs.Add(3.438e-2, "15y", BuildingBlockType.EURSWAP6M); rs.Add(3.467e-2, "16y", BuildingBlockType.EURSWAP6M); rs.Add(3.484e-2, "17y", BuildingBlockType.EURSWAP6M); rs.Add(3.494e-2, "18y", BuildingBlockType.EURSWAP6M); rs.Add(3.495e-2, "19y", BuildingBlockType.EURSWAP6M); rs.Add(3.491e-2, "20y", BuildingBlockType.EURSWAP6M); rs.Add(3.483e-2, "21y", BuildingBlockType.EURSWAP6M); rs.Add(3.471e-2, "22y", BuildingBlockType.EURSWAP6M); rs.Add(3.455e-2, "23y", BuildingBlockType.EURSWAP6M); rs.Add(3.436e-2, "24y", BuildingBlockType.EURSWAP6M); rs.Add(3.415e-2, "25y", BuildingBlockType.EURSWAP6M); rs.Add(3.391e-2, "26y", BuildingBlockType.EURSWAP6M); rs.Add(3.366e-2, "27y", BuildingBlockType.EURSWAP6M); rs.Add(3.340e-2, "28y", BuildingBlockType.EURSWAP6M); rs.Add(3.314e-2, "29y", BuildingBlockType.EURSWAP6M); rs.Add(3.29e-2, "30y", BuildingBlockType.EURSWAP6M); #endregion #endregion end Inputs #region building curve string swapTenor = "11y"; // you can change it // I build my multi curve, SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator> DCurve = new SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator>(mktRates, OneDimensionInterpolation.LogLinear); // discount curve MultiCurveBuilder <SimpleCubicInterpolator> C = new MultiCurveBuilder <SimpleCubicInterpolator>(rs, DCurve); // multi curve #endregion end building curve #region myFunction // my function to calculate Net Present Value of a Vanilla Swap (receiver swap) Func <SwapStyle, IRateCurve, double> NPV = (BB, c) => { #region FixLeg // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // # of fixed cash flows int n_fix = dfDates.Length; double NPV_fix = 0.0; // calculate df for (int i = 0; i < n_fix; i++) { NPV_fix += c.Df(dfDates[i]) * yfFixLeg[i] * BB.rateValue; // df*yf } // NPV_fix *= BB.rateValue; #endregion #region FloatLeg // fixed leg data double[] yfFloatLeg = BB.scheduleLeg2.GetYFVect(BB.swapLeg2.DayCount); // float is leg 2 // dfs array of fixed lag Date[] dfDatesFloat = BB.scheduleLeg2.payDates; // serial date of float lag (each dates we should find df) Date[] FromDateFloat = BB.scheduleLeg2.fromDates; // # of fixed cash flows int n_float = dfDatesFloat.Length; double[] fwd = new double[n_float]; // fwd rate container // getting fwd rates for (int i = 0; i < n_float; i++) { fwd[i] = c.Fwd(FromDateFloat[i]); } double NPV_float = 0.0; // calculate df for (int i = 0; i < n_float; i++) { NPV_float += c.Df(dfDatesFloat[i]) * yfFloatLeg[i] * fwd[i]; // df*yf } #endregion return(NPV_fix - NPV_float); // NPV }; #endregion #region Print results double atmSwap = C.SwapFwd(refDate, swapTenor); // At The Money swap (i.e. par rate) List <double> swapRateList = new List <double>(); // lists of swap to analyze swapRateList.Add(atmSwap); // it is ATM swapRateList.Add(atmSwap + 0.01); // it has positive mark to market (MtM). It is a receiver swap with a contract rate > than Atm) swapRateList.Add(atmSwap - 0.01); // it has negative MtM // iterate for each swap: // see how change the sign of sensitivities for discount curve and for forwarding curve changing contract rates Console.WriteLine("Executing parallel loop..."); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Parallel.ForEach(swapRateList, swapRate => { Console.WriteLine("Pricing Receiver Swap {0}, Atm Rate: {1:f6}, Contract Rate: {2:f6}", swapTenor, atmSwap, swapRate); IRateCurve[] cs = C.ShiftedCurvesArrayFwdCurve(0.0001); IRateCurve csp = C.ParallelShiftFwdCurve(0.0001); // initialise some variable used in sensitivities double sens = 0.0; double runSum = 0.0; // Standard swap SwapStyle y = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(refDate, swapRate, swapTenor, BuildingBlockType.EURSWAP6M); double iniMTM = NPV(y, C) * 100000000; // initial mark to market for 100ml receiver contract Console.WriteLine("Starting Mark To Market {0:f}", iniMTM); Console.WriteLine("Sensitivities to Curve used for forward rate: "); int nOfRate = rs.Count; // iterate for market input for forwarding curve for (int i = 0; i < nOfRate; i++) { sens = NPV(y, cs[i]) * 100000000 - iniMTM; Console.WriteLine("{0} BPV: {1:f}", rs.Item(i).M.GetPeriodStringFormat(), sens); runSum += sens; } Console.WriteLine("Total: {0:f}", runSum); Console.WriteLine("\nParallel Shift Total: {0:f}", NPV(y, csp) * 100000000 - iniMTM); // parallel shift // reset some variable used in sensitivities sens = 0.0; runSum = 0.0; Console.WriteLine("Sensitivities to Discount Curve:"); // let's consider discounting curve IRateCurve[] DCrvs = C.ShiftedCurvesArrayDCurve(0.0001); // shifting each bucket IMultiRateCurve DCrvp = C.ParallelShiftDCurve(0.0001); // parallel shift nOfRate = mktRates.Count; // iterate for market input for discounting curve for (int i = 0; i < nOfRate; i++) { sens = NPV(y, DCrvs[i]) * 100000000 - iniMTM; Console.WriteLine("{0} BPV: {1:f}", mktRates.Item(i).M.GetPeriodStringFormat(), sens); runSum += sens; } Console.WriteLine("Total: {0:f}", runSum); Console.WriteLine("\nParallel Shift Total: {0:f}", NPV(y, DCrvp) * 100000000 - iniMTM); }); stopwatch.Stop(); Console.WriteLine("Parallel loop time in milliseconds: {0}", stopwatch.ElapsedMilliseconds); #endregion }
private void Delete() { m_Success = false; MessageDisplay msgDisplay = CreateMessageDisplay(); int nodeID = _Request.Get<int>("nodeID", Method.Get, 0); if (CurrentRateSet.NodeID != nodeID) { msgDisplay.AddError("当前版块评分设置继承至上级版块,不能进行删除操作,如要修改请修改上级版块评分设置或者把评分设置设为自定义"); return; } if (PointType == null) { msgDisplay.AddError(new InvalidParamError("pointtype")); return; } int sortOrder = _Request.Get<int>("sortorder", Method.Get, 0); RateSettings setting = new RateSettings(); setting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != nodeID) setting.RateSets.Add(set); else { RateSet tempSet = new RateSet(); tempSet.NodeID = nodeID; tempSet.RateItems = new RateSetItemCollection(); for (int i = 0; i < set.RateItems.Count; i++) { RateSetItem item = set.RateItems[i]; if (item.PointType == PointType.Value && sortOrder == item.RoleSortOrder && item.RoleID != Guid.Empty) { } else tempSet.RateItems.Add(item); } setting.RateSets.Add(tempSet); } } try { if (!SettingManager.SaveSettings(setting)) { CatchError<ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else { string urlRef = Request.UrlReferrer.ToString(); string query; int index = urlRef.IndexOf('?'); if (index > 0) query = urlRef.Substring(index + 1); else query = string.Empty; string url = Request.RawUrl; if (url.IndexOf('?') > -1) url = url.Substring(0, url.IndexOf('?')); url = url + "?" + query; BbsRouter.JumpToUrl(url, "success=true"); } //Response.Redirect(Request.UrlReferrer.ToString()); } catch (Exception ex) { msgDisplay.AddError(ex.Message); } }
public bool saveSettings() { m_Success = false; MessageDisplay msgDisplay = null; if (_Request.Get("inheritType", Method.Post, "False").ToLower() == "true") { msgDisplay = CreateMessageDisplay(); RateSettings tempSetting = new RateSettings(); tempSetting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != ForumID) { tempSetting.RateSets.Add(set); } } try { if (!SettingManager.SaveSettings(tempSetting)) { CatchError<ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else BbsRouter.JumpToUrl(Request.RawUrl, "success=true"); } catch (Exception ex) { msgDisplay.AddError(ex.Message); } return true; } string[] errorNames = new string[EnabledUserPointList.Count * 2]; int i = 0; foreach(UserPoint point in EnabledUserPointList) { errorNames[i] = point.Type.ToString(); i++; errorNames[i] = "new_" + point.Type.ToString(); i++; } msgDisplay = CreateMessageDisplay(errorNames); RateSetItemCollection tempRankItems = new RateSetItemCollection(); foreach (UserPoint point in EnabledUserPointList) { int[] tempIds = StringUtil.Split<int>(_Request.Get("id_" + point.Type.ToString(), Method.Post, string.Empty)); List<int> sortOrdes = new List<int>(); RateSetItem item; foreach (int id in tempIds) { item = GetRankSetItem(point.Type, id, false, msgDisplay); if (item != null) { if (id != 0 && sortOrdes.Contains(item.RoleSortOrder) && msgDisplay.HasAnyError() == false) { msgDisplay.AddError(point.Type.ToString(), id, "排序数字不能重复"); } else { if (id != 0) { sortOrdes.Add(item.RoleSortOrder); } tempRankItems.Add(item); } } } item = GetRankSetItem(point.Type, 0, true, msgDisplay); if (item != null) { if (sortOrdes.Contains(item.RoleSortOrder) && msgDisplay.HasAnyError() == false) { msgDisplay.AddError("new_" + point.Type.ToString(), "排序数字不能重复"); } tempRankItems.Add(item); } } if (msgDisplay.HasAnyError()) return false; RateSet rateSet = new RateSet(); rateSet.NodeID = ForumID; rateSet.RateItems = tempRankItems; RateSettings setting = new RateSettings(); setting.RateSets = new RateSetCollection(); foreach (RateSet set in AllSettings.Current.RateSettings.RateSets) { if (set.NodeID != ForumID) setting.RateSets.Add(set); } setting.RateSets.Add(rateSet); try { if (!SettingManager.SaveSettings(setting)) { CatchError<ErrorInfo>(delegate(ErrorInfo error) { msgDisplay.AddError(error); }); } else BbsRouter.JumpToUrl(Request.RawUrl, "success=true"); } catch (Exception ex) { msgDisplay.AddError(ex.Message); } return true; }
// Check if the process will match the starting inputs public static void CheckInputsVs3m() { #region Inputs // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate markets rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(2.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(2.435e-2, "3m", BuildingBlockType.EURDEPO); // Swap Vs 3M mktRates.Add(2.869e-2, "1Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.316e-2, "2Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.544e-2, "3Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.745e-2, "4Y", BuildingBlockType.EURSWAP3M); mktRates.Add(3.915e-2, "5Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.057e-2, "6Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.175e-2, "7Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.273e-2, "8Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.362e-2, "9Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.442e-2, "10Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.589e-2, "12Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.750e-2, "15Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.835e-2, "20Y", BuildingBlockType.EURSWAP3M); mktRates.Add(4.787e-2, "25Y", BuildingBlockType.EURSWAP3M); #endregion end Inputs // Uncomment to chose the curve // SingleCurveBuilderStandard<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderStandard<OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); double firstFixing = 1.435e-2; SingleCurveBuilderSmoothingFwd <OnLogDf, LinearInterpolator> C = new SingleCurveBuilderSmoothingFwd <OnLogDf, LinearInterpolator>(mktRates, firstFixing); // SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator>(mktRates); #region print output IEnumerable <BuildingBlock> BBArray = mktRates.GetArrayOfBB(); // Only Given Swap from BBArray IEnumerable <BuildingBlock> OnlyGivenDepo = from c in BBArray where c.GetType().BaseType == typeof(OnePaymentStyle) select c; Console.WriteLine(C.ToString()); Console.WriteLine("Recalc Df at Ref Date: {0}", C.DF(refDate)); foreach (OnePaymentStyle BB in OnlyGivenDepo) { double yf = refDate.YF(BB.endDate, BB.dayCount); double df = C.DF(BB.endDate); double CalcRate = ((1 / df) - 1) / yf; Console.WriteLine("{0} Input Rate: {1} Recalc Rate: {2}", BB.Tenor.GetPeriodStringFormat(), BB.rateValue, CalcRate); } // Only Given Swap from BBArray IEnumerable <BuildingBlock> OnlyGivenSwap = from c in BBArray where c.GetType().BaseType == typeof(SwapStyle) select c; foreach (SwapStyle BB in OnlyGivenSwap) { // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // initialise array for df double[] dfFixLeg = new double[dfDates.Length]; // calculate df for (int i = 0; i < dfDates.Length; i++) { dfFixLeg[i] = C.DF(dfDates[i]); } // Interpolation Methods for Curve Construction PATRICK S. HAGAN & GRAEME WEST Applied Mathematical Finance,Vol. 13, No. 2, 89–129, June 2006 // Formula 2) page 4 double CalcRate = Formula.ParRate(yfFixLeg, dfFixLeg); // Calculate par rate Console.WriteLine("{0} Input Rate: {1} Recalc Rate: {2}", BB.Tenor.GetPeriodStringFormat(), BB.rateValue, CalcRate); } #endregion end print output }
// Calculating net present value of the floating leg of a swap public static void TestVanillaSwapFloatingLegNPV() { // In Single Curve World // NPV of floating leg of a swap con be calculated // as 1-DF(T) or // as sum of present value of each expected cash flows // for details see Paul Wilmott introduces Quantitative Finance par 15.5 or // "Swap and other Derivatives" R.Flavell page 57 (sum Fwd(i)*Yf(i)*DF(i) = 1-DF(T)) // We calculate the NPV of float leg using both method ands we check that they are the same #region Inputs - not real data // Start input Date refDate = (new Date(DateTime.Now)).mod_foll(); // Random date // Populate markets rates set: from file, from real time, ... here made up numbers RateSet mktRates = new RateSet(refDate); // Deposits mktRates.Add(0.742e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(0.952e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(1.201e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(1.287e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(1.465e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(1.652e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(1.819e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(1.922e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.102e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.425e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.225e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.556e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.794e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.968e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.9895e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.879e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs #region start SingleCurve building SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> C = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); // SingleCurveBuilderSmoothingFwd<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderSmoothingFwd<OnLogDf, LinearInterpolator>(mktRates, firstFixing);double firstFixing = 1.201e-2; // SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator> C = new SingleCurveBuilderInterpBestFit<OnLogDf, LinearInterpolator>(mktRates); #endregion end SingleCurve building // Create a schedule of a swap floating leg Schedule s = new Schedule(refDate, refDate.add_period("12Y", false), "6m", Rule.Backward, BusinessDayAdjustment.ModifiedFollowing, "0d", BusinessDayAdjustment.ModifiedFollowing); s.PrintSchedule(); // print it // NPV of floating leg as 1-DF(T) double FloatingLagPV = 1.0 - C.DF(s.payDates.Last()); Console.WriteLine("1-DF(T): {0}", FloatingLagPV); // NPV of floating as sum of PV of each cash flow double CalcFloatingLagPV = 0.00; double[] YearFraction = s.GetYFVect(Dc._Act_360); for (int j = 0; j < YearFraction.GetLength(0); j++) { // formula 11.1.1 Option Pricing Formulas Espen Haug second edition // "Swap and Other Derivatives" R.Flavell page 53 double df_ini = C.DF(s.fromDates[j]); double df_end = C.DF(s.toDates[j]); double fwd = (df_ini / df_end - 1) / YearFraction[j]; CalcFloatingLagPV += fwd * YearFraction[j] * C.DF(s.payDates[j]); } Console.WriteLine("CalcFloatingLagPV: {0}", CalcFloatingLagPV); }
public static void MatrixCapletWithRateCurve() { #region Inputs // We load a set of data (not real) DataForCapletExample2 d = new DataForCapletExample2(); RateSet rs = d.GetRateSet(); double[] T = d.T(); string[] avT = d.avTString(); List <double[]> VolArr = d.VolArr(); double[] strike = d.strike(); // We build our multi curve SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator> Curve = new SingleCurveBuilderStandard <OnLogDf, SimpleCubicInterpolator>(rs, OneDimensionInterpolation.LogLinear); // discount curve #endregion #region Testing all available MonoStrikeCapletVolBuilder // Uncomment one of these CapletMatrixVolBuilder <MonoStrikeCapletVolBuilderInputInterpLinear> B = new CapletMatrixVolBuilder <MonoStrikeCapletVolBuilderInputInterpLinear>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderInputInterpCubic> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderInputInterpCubic>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitStd> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitStd>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitSmooth> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitSmooth>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitPWL> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitPWL>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitCubic> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitCubic>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitFunct> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderBestFitFunct>(avT, Curve, strike, VolArr); // CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderPWC> B = // new CapletMatrixVolBuilder<MonoStrikeCapletVolBuilderPWC>(avT, Curve, strike, VolArr); #endregion List <double[]> VolSilos = B.CapletVolMatrix; #region print results ExcelMechanisms exl = new ExcelMechanisms(); Vector <double> xarr = new Vector <double>(T, 1); List <string> labels = new List <string>(); foreach (double myD in strike) { labels.Add(myD.ToString()); } ; List <Vector <double> > yarrs = new List <Vector <double> >(); foreach (double[] arr in VolSilos) { yarrs.Add(new Vector <double>(arr, 1)); } exl.printInExcel <double>(xarr, labels, yarrs, "Caplet Vol Input Interpolation", "Term", "Volatility"); #endregion }
public static void UsingTPLinImplementation() { // ref date, you should use the one you need Date refDate = (new Date(DateTime.Now)).mod_foll(); #region eonia market data // I populate markets rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); mktRates.Add(0.447e-2, "1w", BuildingBlockType.EONIASWAP); mktRates.Add(0.583e-2, "2w", BuildingBlockType.EONIASWAP); mktRates.Add(0.627e-2, "3w", BuildingBlockType.EONIASWAP); mktRates.Add(0.635e-2, "1m", BuildingBlockType.EONIASWAP); mktRates.Add(0.675e-2, "2m", BuildingBlockType.EONIASWAP); mktRates.Add(0.705e-2, "3m", BuildingBlockType.EONIASWAP); mktRates.Add(0.734e-2, "4m", BuildingBlockType.EONIASWAP); mktRates.Add(0.758e-2, "5m", BuildingBlockType.EONIASWAP); mktRates.Add(0.780e-2, "6m", BuildingBlockType.EONIASWAP); mktRates.Add(0.798e-2, "7m", BuildingBlockType.EONIASWAP); mktRates.Add(0.816e-2, "8m", BuildingBlockType.EONIASWAP); mktRates.Add(0.834e-2, "9m", BuildingBlockType.EONIASWAP); mktRates.Add(0.849e-2, "10m", BuildingBlockType.EONIASWAP); mktRates.Add(0.864e-2, "11m", BuildingBlockType.EONIASWAP); mktRates.Add(0.878e-2, "1Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.098e-2, "2Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.36e-2, "3Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.639e-2, "4Y", BuildingBlockType.EONIASWAP); mktRates.Add(1.9e-2, "5Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.122e-2, "6Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.308e-2, "7Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.467e-2, "8Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.599e-2, "9Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.715e-2, "10Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.818e-2, "11Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.908e-2, "12Y", BuildingBlockType.EONIASWAP); // From here interpolation is need mktRates.Add(3.093e-2, "15Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.173e-2, "20Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.114e-2, "25Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.001e-2, "30Y", BuildingBlockType.EONIASWAP); #endregion #region Swap Market Data // RateSet EUR 6m swap RateSet rs = new RateSet(refDate); rs.Add(1.123e-2, "6m", BuildingBlockType.EURDEPO); rs.Add(1.42e-2, "1y", BuildingBlockType.EURSWAP6M); rs.Add(1.635e-2, "2y", BuildingBlockType.EURSWAP6M); rs.Add(1.872e-2, "3y", BuildingBlockType.EURSWAP6M); rs.Add(2.131e-2, "4y", BuildingBlockType.EURSWAP6M); rs.Add(2.372e-2, "5y", BuildingBlockType.EURSWAP6M); rs.Add(2.574e-2, "6y", BuildingBlockType.EURSWAP6M); rs.Add(2.743e-2, "7y", BuildingBlockType.EURSWAP6M); rs.Add(2.886e-2, "8y", BuildingBlockType.EURSWAP6M); rs.Add(3.004e-2, "9y", BuildingBlockType.EURSWAP6M); rs.Add(3.107e-2, "10y", BuildingBlockType.EURSWAP6M); rs.Add(3.198e-2, "11y", BuildingBlockType.EURSWAP6M); rs.Add(3.278e-2, "12y", BuildingBlockType.EURSWAP6M); rs.Add(3.344e-2, "13y", BuildingBlockType.EURSWAP6M); rs.Add(3.398e-2, "14y", BuildingBlockType.EURSWAP6M); rs.Add(3.438e-2, "15y", BuildingBlockType.EURSWAP6M); rs.Add(3.467e-2, "16y", BuildingBlockType.EURSWAP6M); rs.Add(3.484e-2, "17y", BuildingBlockType.EURSWAP6M); rs.Add(3.494e-2, "18y", BuildingBlockType.EURSWAP6M); rs.Add(3.495e-2, "19y", BuildingBlockType.EURSWAP6M); rs.Add(3.491e-2, "20y", BuildingBlockType.EURSWAP6M); rs.Add(3.483e-2, "21y", BuildingBlockType.EURSWAP6M); rs.Add(3.471e-2, "22y", BuildingBlockType.EURSWAP6M); rs.Add(3.455e-2, "23y", BuildingBlockType.EURSWAP6M); rs.Add(3.436e-2, "24y", BuildingBlockType.EURSWAP6M); rs.Add(3.415e-2, "25y", BuildingBlockType.EURSWAP6M); rs.Add(3.391e-2, "26y", BuildingBlockType.EURSWAP6M); rs.Add(3.366e-2, "27y", BuildingBlockType.EURSWAP6M); rs.Add(3.340e-2, "28y", BuildingBlockType.EURSWAP6M); rs.Add(3.314e-2, "29y", BuildingBlockType.EURSWAP6M); rs.Add(3.29e-2, "30y", BuildingBlockType.EURSWAP6M); #endregion // initialise discount curve - it is the same for both forwarding curve SingleCurveBuilderStandard <OnDf, LinearInterpolator> DCurve = new SingleCurveBuilderStandard <OnDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); // initializing the stopwatch Stopwatch stopwatch = new Stopwatch(); MultiCurveBuilder <SimpleCubicInterpolator> MC = new MultiCurveBuilder <SimpleCubicInterpolator>(rs, DCurve); Console.WriteLine("ProcessorCount: {0}", Environment.ProcessorCount); // number of processor #region MultiCurveBuilder sequential Console.WriteLine("Implementing shift sequential..."); stopwatch.Start(); IMultiRateCurve[] MCArrayFwdSeq = MC.ShiftedCurvesArrayFwdCurveSeq(0.01); IMultiRateCurve[] MCArrayDfSeq = MC.ShiftedCurvesArrayDCurveSeq(0.01); stopwatch.Stop(); Console.WriteLine("Done. Time in milliseconds: {0}", stopwatch.ElapsedMilliseconds); #endregion stopwatch.Reset(); // resetting the stopwatch #region MultiCurveBuilder2 Console.WriteLine("Implementing shift parallel ..."); stopwatch.Start(); IMultiRateCurve[] MCArrayFwd = MC.ShiftedCurvesArrayFwdCurve(0.01); IMultiRateCurve[] MCArrayDf = MC.ShiftedCurvesArrayDCurve(0.01); stopwatch.Stop(); Console.WriteLine("Done. Time in milliseconds: {0}", stopwatch.ElapsedMilliseconds); #endregion }
// More on sensitivities calc public static void MoreOnSensitivities() { #region Inputs // Start input Date refDate = new Date(2010, 10, 11); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(1.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(1.720e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(1.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.787e-2, "25Y", BuildingBlockType.EURSWAP6M); #endregion end Inputs #region building curve List <ISingleRateCurve> Curves = new List <ISingleRateCurve>(); // initialised each class and add to list. You can add more curves // Setup (a) in Table 15.3 SingleCurveBuilderStandard <OnLogDf, LinearInterpolator> c2 = new SingleCurveBuilderStandard <OnLogDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); Curves.Add(c2); // Setup (b) in Table 15.3 SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator> c1 = new SingleCurveBuilderSmoothingFwd <OnLogDf, SimpleCubicInterpolator>(mktRates); Curves.Add(c1); string swapTenor = "11y"; // you can change it #endregion end building curve #region myFunction Func <SwapStyle, IRateCurve, double> NPV = (BB, c) => { #region FixLeg // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // # of fixed cash flows int n_fix = dfDates.Length; double NPV_fix = 0.0; // calculate df for (int i = 0; i < n_fix; i++) { NPV_fix += c.Df(dfDates[i]) * yfFixLeg[i] * BB.rateValue; // df*yf } // NPV_fix *= BB.rateValue; #endregion #region FloatLeg // fixed leg data double[] yfFloatLeg = BB.scheduleLeg2.GetYFVect(BB.swapLeg2.DayCount); // float is leg 2 // dfs array of fixed lag Date[] dfDatesFloat = BB.scheduleLeg2.payDates; // serial date of float lag (each dates we should find df) Date[] toDateFloat = BB.scheduleLeg2.toDates; // # of fixed cash flows int n_float = dfDatesFloat.Length; double[] fwd = new double[n_float]; fwd[0] = ((1 / c.Df(toDateFloat[0])) - 1) / refDate.YF(toDateFloat[0], Dc._Act_360);; for (int i = 1; i < n_float; i++) { double yf = toDateFloat[i - 1].YF(toDateFloat[i], Dc._Act_360); double df_ini = c.Df(toDateFloat[i - 1]); double df_end = c.Df(toDateFloat[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } double NPV_float = 0.0; // calculate df for (int i = 0; i < n_float; i++) { NPV_float += c.Df(dfDatesFloat[i]) * yfFloatLeg[i] * fwd[i]; // df*yf } #endregion return(NPV_fix - NPV_float); }; #endregion #region Print results foreach (ISingleRateCurve C in Curves) { double swapRate = C.SwapFwd(refDate, swapTenor); IRateCurve[] cs = C.ShiftedCurveArray(0.0001); IRateCurve csp = C.ParallelShift(0.0001); // initialise some variable used in sensitivities double sens = 0.0; double runSum = 0.0; // standard Console.WriteLine(C.ToString()); SwapStyle y = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(refDate, swapRate, swapTenor, BuildingBlockType.EURSWAP6M); double iniMTM = NPV(y, C) * 100000000; Console.WriteLine("{0} swap ATM fwd: {1:f5}", swapTenor, swapRate); Console.WriteLine("Starting P&L {0:f}", iniMTM); int nOfRate = mktRates.Count; for (int i = 0; i < nOfRate; i++) { sens = NPV(y, cs[i]) * 100000000 - iniMTM; Console.WriteLine("{0} BPV: {1:f}", mktRates.Item(i).M.GetPeriodStringFormat(), sens); runSum += sens; } Console.WriteLine("Total: {0:f}", runSum); Console.WriteLine("Parallel Total: {0:f}", NPV(y, csp) * 100000000 - iniMTM); Console.WriteLine("Press a key to continue"); Console.ReadLine(); } #endregion }
// Calculate sensitivities public static void Sensitivities() { #region Inputs // Start input Date refDate = new Date(2019, 2, 25); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); // Depos mktRates.Add(1.243e-2, "1m", BuildingBlockType.EURDEPO); mktRates.Add(1.435e-2, "3m", BuildingBlockType.EURDEPO); mktRates.Add(1.720e-2, "6m", BuildingBlockType.EURDEPO); // Swap Vs 6M mktRates.Add(1.869e-2, "1Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.316e-2, "2Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.544e-2, "3Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.745e-2, "4Y", BuildingBlockType.EURSWAP6M); mktRates.Add(2.915e-2, "5Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.057e-2, "6Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.175e-2, "7Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.273e-2, "8Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.362e-2, "9Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.442e-2, "10Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.589e-2, "12Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.750e-2, "15Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.835e-2, "20Y", BuildingBlockType.EURSWAP6M); mktRates.Add(3.787e-2, "25Y", BuildingBlockType.EURSWAP6M); // I shift 1bp up 10y swap input rate int IndexShifted = 12; RateSet mktRates2 = mktRates.ShiftedRateSet(IndexShifted, 0.0001); // print out first and second market input rates for (int i = 0; i < mktRates.Count; i++) { Console.WriteLine("First: {0} {1} Second: {2} {3}", mktRates.Item(i).M.GetPeriodStringFormat(), mktRates.Item(i).V, mktRates2.Item(i).M.GetPeriodStringFormat(), mktRates2.Item(i).V); } #endregion end Inputs #region building curve // First curve: using markets rates SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> c1 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); // Second curve: like c1 but 10Y input rate is shifted SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> c2 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates2); string swapTenor = "10y"; // you can change it #endregion end building curve #region myFunction Func <SwapStyle, IRateCurve, double> NPV = (BB, c) => { #region FixLeg // fixed leg data double[] yfFixLeg = BB.scheduleLeg1.GetYFVect(BB.swapLeg1.DayCount); // fixed is leg 1 // dfs array of fixed lag Date[] dfDates = BB.scheduleLeg1.payDates; // serial date of fixed lag (each dates we should find df) // # of fixed cash flows int n_fix = dfDates.Length; double NPV_fix = 0.0; // calculate df for (int i = 0; i < n_fix; i++) { NPV_fix += c.Df(dfDates[i]) * yfFixLeg[i] * BB.rateValue; // df*yf } // NPV_fix *= BB.rateValue; #endregion #region FloatLeg // fixed leg data double[] yfFloatLeg = BB.scheduleLeg2.GetYFVect(BB.swapLeg2.DayCount); // float is leg 2 // dfs array of fixed lag Date[] dfDatesFloat = BB.scheduleLeg2.payDates; // serial date of float lag (each dates we should find df) Date[] toDateFloat = BB.scheduleLeg2.toDates; // # of fixed cash flows int n_float = dfDatesFloat.Length; double[] fwd = new double[n_float]; fwd[0] = ((1 / c.Df(toDateFloat[0])) - 1) / refDate.YF(toDateFloat[0], Dc._Act_360);; for (int i = 1; i < n_float; i++) { double yf = toDateFloat[i - 1].YF(toDateFloat[i], Dc._Act_360); double df_ini = c.Df(toDateFloat[i - 1]); double df_end = c.Df(toDateFloat[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } double NPV_float = 0.0; // calculate df for (int i = 0; i < n_float; i++) { NPV_float += c.Df(dfDatesFloat[i]) * yfFloatLeg[i] * fwd[i]; // df*yf } #endregion return(NPV_fix - NPV_float); }; #endregion #region Print results // test forward swap starting in ref date (it should be like simple spot swap) double swapRate = c1.SwapFwd(refDate, swapTenor); // I create the swap according to standard convention SwapStyle y = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(refDate, swapRate, swapTenor, BuildingBlockType.EURSWAP6M); // initial NPV double iniMTM = NPV(y, c1) * 100000000; // print out Console.WriteLine("IRS to be priced tenor: {0}. IRS to be priced rate: {1:f5}", swapTenor, swapRate); Console.WriteLine("{0} swap ATM fwd according the starting curve: {1:f5}. Starting P&L {2:f}", swapTenor, swapRate, iniMTM); Console.WriteLine("Let's shift {0} rate from {1:f5} to {2:f5}", mktRates.Item(IndexShifted).M.GetPeriodStringFormat(), mktRates.Item(IndexShifted).V, mktRates2.Item(IndexShifted).V); // NPV after shift double endMTM = NPV(y, c2) * 100000000; Console.WriteLine("{0} swap ATM fwd after shifting: {1:f5}. P&L after shifting {2:f}", swapTenor, c2.SwapFwd(refDate, swapTenor), endMTM); Console.WriteLine("Press a key to continue"); Console.ReadLine(); #endregion }
// Print on excel forward rate using different curve builder for OIS fwd 3m public static void CheckFwdRatesOIS3m() { #region Inputs // ref date Date refDate = (new Date(DateTime.Now)).mod_foll(); // I populate market rates set: from file, from real time, ... RateSet mktRates = new RateSet(refDate); mktRates.Add(2.338e-2, "1d", BuildingBlockType.EURDEPO); // mktRates.Add(2.272e-2, "1w", BuildingBlockType.EONIASWAP); // mktRates.Add(2.241e-2, "2w", BuildingBlockType.EONIASWAP); // mktRates.Add(2.16e-2, "3w", BuildingBlockType.EONIASWAP); // mktRates.Add(2.226e-2, "1m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.299e-2, "2m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.323e-2, "3m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.344e-2, "4m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.371e-2, "5m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.39e-2, "6m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.41e-2, "7m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.4316e-2, "8m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.449e-2, "9m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.466e-2, "10m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.48e-2, "11m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.529e-2, "15m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.565e-2, "18m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.603e-2, "21m", BuildingBlockType.EONIASWAP); // mktRates.Add(2.493e-2, "1Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.644e-2, "2Y", BuildingBlockType.EONIASWAP); mktRates.Add(2.849e-2, "3Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.08e-2, "4Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.292e-2, "5Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.471e-2, "6Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.621e-2, "7Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.748e-2, "8Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.86e-2, "9Y", BuildingBlockType.EONIASWAP); mktRates.Add(3.965e-2, "10Y", BuildingBlockType.EONIASWAP); mktRates.Add(4.064e-2, "11Y", BuildingBlockType.EONIASWAP); mktRates.Add(4.155e-2, "12Y", BuildingBlockType.EONIASWAP); // From here interpolation is need mktRates.Add(4.358e-2, "15Y", BuildingBlockType.EONIASWAP); mktRates.Add(4.48e-2, "20Y", BuildingBlockType.EONIASWAP); mktRates.Add(4.465e-2, "25Y", BuildingBlockType.EONIASWAP); mktRates.Add(4.415e-2, "30Y", BuildingBlockType.EONIASWAP); List <IRateCurve> CurveList = new List <IRateCurve>(); // list containing curve List <string> CurveString = new List <string>(); // list containing labels #endregion end Inputs #region building curve SingleCurveBuilderStandard <OnDf, LinearInterpolator> C1 = new SingleCurveBuilderStandard <OnDf, LinearInterpolator>(mktRates, OneDimensionInterpolation.Linear); SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator> C2 = new SingleCurveBuilderInterpBestFit <OnLogDf, SimpleCubicInterpolator>(mktRates); #endregion end building curve // populate lists CurveList.Add(C1); CurveString.Add(C1.ToString()); CurveList.Add(C2); CurveString.Add(C2.ToString()); #region printing output // I get the longer eonia swap available from the input data SwapStyle LS = (SwapStyle)mktRates.GetArrayOfBB().Last(); Schedule s = new Schedule(refDate, LS.endDate, "3m", Rule.Backward, LS.swapLeg1.SwapBusDayRollsAdj, "0d", LS.swapLeg1.SwapBusDayPayAdj); Dc dc = Dc._Act_360; Date[] FromDate = s.fromDates; Date[] ToDate = s.toDates; int N = FromDate.Length; List <Vector <double> > Fwds = new List <Vector <double> >(); double[] dt = new double[N]; for (int i = 0; i < N; i++) { dt[i] = FromDate[0].YF(ToDate[i], Dc._30_360); } foreach (IRateCurve myC in CurveList) { double[] fwd = new double[N]; for (int i = 0; i < N; i++) { double yf = FromDate[i].YF(ToDate[i], dc); double df_ini = myC.Df(FromDate[i]); double df_end = myC.Df(ToDate[i]); fwd[i] = ((df_ini / df_end) - 1) / yf; } Fwds.Add(new Vector <double>(fwd)); } ExcelMechanisms exl = new ExcelMechanisms(); exl.printInExcel(new Vector <double>(dt), CurveString, Fwds, "Fwd 3M", "time", "rate"); // .printInExcel<T> #endregion end printing output }