Пример #1
0
 // Swap net present value
 object IRate.SwapNPV(string idCode, double Rate, string SwapTenor, bool PayOrRec, double Nominal)
 {
     // Get Fwd Start Swap according to underlying rate floating tenor used in building carve (es 3m or 6m,..)
     if (m_xlApp != null)
     {
         m_xlApp.Volatile(true);
     }
     try
     {
         IMultiRateCurve MultiCurve = null;                    // initialise a multi curve
         if (MCDictionary.TryGetValue(idCode, out MultiCurve)) // is the idCode in dictionary?
         {
             VanillaSwap swap = new VanillaSwap(MultiCurve, Rate, SwapTenor, PayOrRec, Nominal);
             return(swap.NPV());
         }
         else
         {
             return("Curve not found");  // curve not found
         }
     }
     catch (Exception e)
     {
         return((string)e.ToString());
     }
 }
Пример #2
0
 // calculate basis swap spread
 object IRate.FwdBasis(double SwapStartDate, string SwapTenor, string Curve1, string Curve2)
 {
     // Get Fwd Start Swap according to underlying rate floating tenor used in building carve (es 3m or 6m,..)
     if (m_xlApp != null)
     {
         m_xlApp.Volatile(true);
     }
     try
     {
         IMultiRateCurve MCurve1 = null;                    // initialise a multi curve
         IMultiRateCurve MCurve2 = null;                    // initialise a multi curve
         if (MCDictionary.TryGetValue(Curve1, out MCurve1) &&
             MCDictionary.TryGetValue(Curve2, out MCurve2)) // is the idCode in dictionary?
         {
             return((double)Formula.FwdBasis(new Date(SwapStartDate), SwapTenor, MCurve1, MCurve2));
         }
         else
         {
             return("Curve not found");  // curve not found
         }
     }
     catch (Exception e)
     {
         return((string)e.ToString());
     }
 }
Пример #3
0
 // calculate basis swap spread for 6M vs 3M basis swap
 object IRate.FwdBasis6M3M(double SwapStartDate, string SwapTenor, string Curve6M, string Curve3M)
 {
     // Get Fwd Start Swap according to underlying rate floating tenor used in building carve (es 3m or 6m,..)
     if (m_xlApp != null)
     {
         m_xlApp.Volatile(true);
     }
     try
     {
         IMultiRateCurve MultiCurve6m = null;                     // initialise a multi curve
         IMultiRateCurve MultiCurve3m = null;                     // initialise a multi curve
         if (MCDictionary.TryGetValue(Curve6M, out MultiCurve6m) &&
             MCDictionary.TryGetValue(Curve3M, out MultiCurve3m)) // is the idCode in dictionary?
         {
             if (MultiCurve6m.GetSwapStyle().GetType() == typeof(EurSwapVs6m) &&
                 MultiCurve3m.GetSwapStyle().GetType() == typeof(EurSwapVs3m))
             {
                 return((double)Formula.FwdBasis(new Date(SwapStartDate), SwapTenor, MultiCurve6m, MultiCurve3m));
             }
             else
             {
                 return("Curve error");
             }
         }
         else
         {
             return("Curve not found");  // curve not found
         }
     }
     catch (Exception e)
     {
         return((string)e.ToString());
     }
 }
Пример #4
0
 // At the money forward swap using string args
 object IRate.FwdSwapX(string idCode, string StartTenor, string SwapTenor)
 {
     // make it volatile
     if (m_xlApp != null)
     {
         m_xlApp.Volatile(true);
     }
     try
     {
         IMultiRateCurve MultiCurve = null;                    // initialise a multi curve
         if (MCDictionary.TryGetValue(idCode, out MultiCurve)) // is the idCode in dictionary?
         {
             Date StartDate = MultiCurve.RefDate().add_period(StartTenor, true);
             return(MultiCurve.SwapFwd(new Date(StartDate), SwapTenor));
         }
         else
         {
             return("IdCode not found");  // curve not found
         }
     }
     catch (Exception e)
     {
         return((string)e.ToString());
     }
 }
Пример #5
0
    public VanillaSwap(IMultiRateCurve MultiCurve, double Rate, string SwapTenor, bool PayOrRec, double Nominal)
    {
        // Standard swap
        Type SwapType  = MultiCurve.GetSwapStyle().GetType();
        Date myRefDate = MultiCurve.RefDate();

        // using reflection
        this.mySwap     = (SwapStyle)Activator.CreateInstance(SwapType, myRefDate, Rate, SwapTenor);
        this.payOrRec   = PayOrRec;
        this.multiCurve = MultiCurve;
        this.nominal    = Nominal;
    }
    // return array of curves, initialised after shifting  mktRateSet elements of forwarding curve
    public IMultiRateCurve[] ShiftedCurvesArrayFwdCurveSeq(double shift)
    {
        // i-curve is built using its setup (interpolator,..), but shifting i-element of mktRateSet
        // up of 'shift' quantity
        RateSet[] rsArr = mktRateSet.ShiftedRateSetArray(shift); // array of shifted RateSet (my scenario)
        int       n     = rsArr.Length;                          // number of elements

        IMultiRateCurve[] curves = new IMultiRateCurve[n];       // array of curves
        for (int i = 0; i < n; i++)
        {                                                        // iterate to build all curve needed
            curves[i] = CreateInstance(rsArr[i], DCurve);        // build the correct curve
        }
        return(curves);
    }
    // return array of curves, initialised after shifting  mktRateSet elements of discounting curve
    public IMultiRateCurve[] ShiftedCurvesArrayDCurveSeq(double shift)
    {
        // i-discount curve is built using its setup (interpolator,..), but shifting i-element of mktRateSet of discounting curve
        // up of 'shift' quantity
        ISingleRateCurve[] dC = DCurve.ShiftedCurveArray(shift);
        int n = dC.Length;

        IMultiRateCurve[] outPut = new IMultiRateCurve[n];
        for (int i = 0; i < n; i++)
        {
            outPut[i] = CreateInstance(mktRateSet, dC[i]);
        }

        return(outPut);  // array of curves
    }
Пример #8
0
        // Risk of a vanilla swap with respect discounting and forwarding curves (it works only for multi-curve)
        object IRate.SwapRisk(string idCode, double Rate, string SwapTenor, bool PayOrRec, double Nominal, double shift, int caseSwitch)
        {
            // Get Fwd Start Swap according to underlying rate floating tenor used in building carve (es 3m or 6m,..)
            if (m_xlApp != null)
            {
                m_xlApp.Volatile(true);
            }
            try
            {
                IMultiRateCurve MultiCurve = null;                    // initialise a multi curve
                if (MCDictionary.TryGetValue(idCode, out MultiCurve)) // is the idCode in dictionary?
                {
                    object      OutPut = null;
                    VanillaSwap swap   = new VanillaSwap(MultiCurve, Rate, SwapTenor, PayOrRec, Nominal);
                    switch (caseSwitch)
                    {
                    case 1:
                        OutPut = (double[])swap.BPVShiftedDCurve(shift);
                        break;

                    case 2:
                        OutPut = (double)swap.BPVParallelShiftDCurve(shift);
                        break;

                    case 3:
                        OutPut = (double[])swap.BPVShiftedFwdCurve(shift);
                        break;

                    case 4:
                        OutPut = (double)swap.BPVParallelShiftFwdCurve(shift);
                        break;

                    default:
                        return(0);
                        // break;
                    }
                    return(OutPut);
                }
                else
                {
                    return("Curve not found");  // curve not found
                }
            }
            catch (Exception e)
            {
                return((string)e.ToString());
            }
        }
Пример #9
0
 // Discount factor
 object IRate.Df(string idCode, double DfDate)
 {
     // make it volatile
     if (m_xlApp != null)
     {
         m_xlApp.Volatile(true);
     }
     try
     {
         IMultiRateCurve MultiCurve = null;                    // initialise a multi curve
         if (MCDictionary.TryGetValue(idCode, out MultiCurve)) // is the idCode in dictionary?
         {
             return(MultiCurve.Df(new Date(DfDate)));
         }
         else
         {
             return("IdCode not found");  // curve not found
         }
     }
     catch (Exception e)
     {
         return((string)e.ToString());
     }
 }
Пример #10
0
    // return one only curve, initialised after shifting all mktRateSet elements, of discounting curve, up of 'shift' quantity, once at the same time
    public double BPVParallelShiftDCurve(double shift)
    {
        IMultiRateCurve sCurve = multiCurve.ParallelShiftDCurve(shift);

        return(Formula.NPV(mySwap, sCurve, payOrRec) * nominal - this.NPV());
    }
Пример #11
0
    // 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
    }