当前位置: 首页 > 工具软件 > Interest.blog > 使用案例 >

【C#】18.使用Interest Rate SWAP生成interest rate curve

羊渝
2023-12-01
<img src="https://img-blog.csdn.net/20150315041703041?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVpd3VodWl3dQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;


namespace FinMktReverseEngineering
{
    # region 1. 插值数据对象
    //  抽象类 InterpAdapter
    public abstract class InterpAdapter
    {
        //【3/12/2015】变量成员
        public double refSerialDate;
        //构造器
        public InterpAdapter() { }
        public InterpAdapter(double refserialdate)
        {
            this.refSerialDate = refserialdate;
        }
        // Derived class should implement these methods
        // from discount factor (Df) to x (where x can be r, logr, logdf, ... )
        abstract public double FromDfToInterp(double Df, double SerialDate);
        // from x to DF (where x can be r, logr, logdf, ... )
        abstract public double FromInterpToDf(double x, double SerialDate);
    }
    //  Onr类型,继承自refDate
    public class Onr : InterpAdapter
    {
        //构造器
        public Onr() : base() { }
        public Onr(double refserialdate): base(refserialdate) { }
        public override double FromDfToInterp(double Df, double SerialDate)
        {
            return (1.0 / Df - 1.0) / ((SerialDate - refSerialDate)/360.0);
        }
        public override double FromInterpToDf(double x, double SerialDate)
        {
            return 1.0 / (1 + x * (SerialDate - refSerialDate)/360.0);
        }
    }
    //  OnLogr 类型 【3/14】
    public class OnLogr : InterpAdapter
    {
        //构造器
        public OnLogr() : base() { }
        public OnLogr(double refserialdate): base(refserialdate) { }
        //从Df到logR
        public override double FromDfToInterp(double Df, double SerialDate)
        {
            return Math.Log((1.0 / Df - 1.0) / ((SerialDate - refSerialDate)/360.0));
        }
        //从logR到Df
        public override double FromInterpToDf(double x, double SerialDate)
        {
            return 1.0 / (1 + Math.Exp(x) * (SerialDate - refSerialDate)/360.0);
        }
    }
    //  OnDf 类型 【3/14】
    public class OnDf : InterpAdapter
    {
        //构造器
        public OnDf() : base() { }
        public OnDf(double refserialdate)
            : base(refserialdate)
        {
        }
        public override double FromDfToInterp(double Df, double SerialDate)
        {
            return Df;
        }
        public override double FromInterpToDf(double x, double SerialDate)
        {
            return x;
        }
    }
    //  OnLogDF 类型 【3/14】
    public class OnLogDF : InterpAdapter
    {
        //构造器
        public OnLogDF() : base() { }
        public OnLogDF(double refserialdate)
            : base(refserialdate)
        {
        }
        public override double FromDfToInterp(double Df, double SerialDate)
        {
            return Math.Log(Df);
        }
        public override double FromInterpToDf(double x, double SerialDate)
        {
            return Math.Exp(x);
        }
    }
    #endregion


    //2. 结构体Period 
    public struct Period
    {
        public string Tensor;
        public Date startDate;
        public Date endDate;
        public Period(Date startdate,string tensor)
        {
            this.Tensor = tensor;
            this.startDate = startdate;
            this.endDate = startdate.add_period_string(tensor,0);
        }
    }


    // 3. RateSet类型
    public class RateSet : System.Collections.CollectionBase
    {
        public Date refDate;
        public BuildingBlock[] BBList;
        //public ArrayList Bblist;
        //0.    构造器
        public RateSet(Date refdate)
        {
            this.refDate = refdate;
            //Bblist = new ArrayList();
        }
        public RateSet(double Value, Period Maturity, BuildingBlockType Type)
        { 
        
        }
        //1.    增加数据点:Add(1.813e-2, "1Y", BuildingBlockType.EURSWAP3M);
        public void Add(double rate, string maturity, BuildingBlockType bbt)
        {
            if (bbt == BuildingBlockType.EURSWAP6M)
            {
                //  2015/3/13
                this.List.Add(new EurSwapVs6m(rate, refDate.add_period_string(maturity, 0)));
            }
        }
        //2.    返回的数组
        public BuildingBlock[] GetArrayOfBB()
        {
            BBList = new BuildingBlock[List.Count];
            for (int i = 0; i < List.Count; i++)
            {
                BBList[i]=(BuildingBlock)List[i];
            }
            return BBList;
            //Bblist.Sort();
            //return Bblist;
            //for (int i = 0; i < List.Count; i++)
            //{
            //    BB[i]=(BuildingBlock)List[i];  
            //}
            //return  BB;
        }
    }


    //子类是single或者multiple Rate Curve
    public interface IRateCurve
    {
        //返回Reference Date
        Date RefDate();


        //返回在TargetDate那天的Discount Factor
        double Df(Date TargetDate);


        //返回指定的Tenor时间段,从StartDate开始的Future Rate
        double Fwd(Date StartDate);


        //返回StartDate开始的swap par rate,期限还是Tenor
        double SwapFwd(Date StartDate, string Tenor);


        //返回用于输入的Swap
        SwapStyle GetSwapStyle();
    }
    // Single Curve接口:继承自IRateCurve
    public interface ISingleRateCurve : IRateCurve
    {
        // Return array of curves, initialized after shifting mktRateSet elements
        ISingleRateCurve[] ShiftedCurveArray(double shift);


        // Return one only curve, initialized after shifting all mktRateSet elements up of 'shift' quantity, once at the same time
        ISingleRateCurve ParallelShift(double shift);


        // Return input rates
        double[] GetInputRates();
    }


    
    //  1. 抽象类SingleCurveBuilder   【更新】2015/3/12
    public abstract class SingleCurveBuilder<DoInterpOn, Interpolation> //: ISingleRateCurve
        where DoInterpOn : InterpAdapter, new()
        where Interpolation : BaseOneDimensionalInterpolator,new()
    {
        public Date refDate; // Reference date of the curve.
        public Interpolation PostProcessInterpo; // The post process interpolator.
        public DoInterpOn interpAdapter; // Adapter to interpolator.
        public IEnumerable<BuildingBlock> BBArray; // Building block array, sorted in ascending order by maturity.
        //【更新】2015/3/13
        public RateSet mktRateSet;
        public LinearInterpolator MRInterp;
        //string FloatTenor;  //有待改正!!!


        //0.    构造器
        public SingleCurveBuilder(RateSet rateSet)
        {
            this.refDate = rateSet.refDate;
            this.mktRateSet = rateSet;
            this.interpAdapter = new DoInterpOn();
            interpAdapter.refSerialDate = rateSet.refDate.SerialValue;
        }
        //Protected Method used in constructor.
        abstract protected void PreProcessInputs(); // Prepare rateSet to be processed from
        //Solve method
        abstract protected void Solve(); // Do calculus.
        abstract protected void PostProcessData(); // Prepare data for interpolators.


        #region 【3/14】 执行接口 IRateCurve
        // 1.   返回 reference date.
        public Date RefDate()
        {
            return refDate;
        }


        // 2.   返回 d 那天的 discount factor,折现时段由给定的swap的float leg决定(例如:6个月)    
        public double DF(Date d)
        {
            //Serial date for which it calculates the discount factor
            double sd = new Date(d).SerialValue;
            //Adapt data to interpolator according to <DoInterpOn>
            return interpAdapter.FromInterpToDf(PostProcessInterpo.Solve(sd), sd);
        } // Calculate discount factor.


        // 3.   返回Forward rate of tenor Period FloatTenor.
        //public double Fwd(Date StartDate)
        //{
        //    Date ed = StartDate.add_period_string(FloatTenor);
        //    double yf = StartDate.YF_30_360(ed);// YF(ed, Dc._Act_360);
        //    double df_ini = DF(StartDate);
        //    double df_end = DF(ed);
        //    return ((df_ini / df_end) - 1) / yf; // equation (15.2).
        //} 


        // 4.   Forward Start IRS rate.
        public double SwapFwd(Date StartDate, string Tenor)
        {
            Date ed = StartDate.add_period_string(Tenor,0);
            double yf = StartDate.YF_30_360(ed);// YF(ed, Dc._Act_360);
            double df_ini = DF(StartDate);
            double df_end = DF(ed);
            return ((df_ini / df_end) - 1) / yf;
        } 
        //public SwapStyle GetSwapStyle() {...} // Return SwapStyle used for bootstrapping, it is swap type used as inputs (i.e. EurSwapVs6m,EurSwapVs3m,
        //public ISingleRateCurve[] ShiftedCurveArray(double shift){..} // Return array of curves, initialized after shifting mktRateSet elements.
        //public ISingleRateCurve ParallelShift(double shift){..}
        //Return one only curve, initialized after shifting all mktRateSet elements up of 'shift'quantity, once at the same time.
        #endregion
        //Derived classes must implement this method.
        public abstract ISingleRateCurve CreateInstance(RateSet newRateSet);
        // Create an instance of class using a new RateSet.}


    }


    //  2. 类SingleCurveBuilderStandard   【更新】2015/3/12
    public class SingleCurveBuilderStandard<DoInterpOn, Interpolation> :SingleCurveBuilder<DoInterpOn, Interpolation>
        where DoInterpOn : InterpAdapter, new()     //使用何种金融资产?Swap,Deposit?
        where Interpolation : BaseOneDimensionalInterpolator, new()     //插值器
    {
        //枚举型:MissingRateInterp是用来估计未知rate的插值器(例如线性插值器)
        private OneDimensionInterpolation MissingRateInterp; 
        // Used in the constructor
        private IEnumerable<BuildingBlock> PreProcessedData; // Building blocks collection
        //DateDf中Key是SerialDate,Value是DF。
        private SortedList<double, double> DateDf; //SerialDate as Key, DFas value, used in constructor to collect data coming from PreProcessedData
        //private SortedList<double, double> DateR; //自定义
        Vector<double> T; 
        Vector<double> ObvRate;
        // Constructor
        public SingleCurveBuilderStandard(RateSet rateSet, OneDimensionInterpolation missingRateInterp)
            : base(rateSet)
        {
           
            // To Data Member
            MissingRateInterp = missingRateInterp;
            // 1)Prepare data to be used in Solve() (output is: PreProcessedData)
            PreProcessInputs();     //输出PreProcessedData
            // 2)Do Calculus: from PreProcessedData calculate post processed data (output is: DataDF)
            Solve();    //输出DataDF
            // 3)create the instance PostProcessInterpo stored in data member of base class
            PostProcessData();
        }
        //  2015/3/13 预处理输入数据
        protected override void PreProcessInputs()
        {
            //  【3/14】
            PreProcessedData = mktRateSet.GetArrayOfBB();
            PreProcessedData.OrderBy(BuildingBlock =>BuildingBlock.Maturity);   //排序!
            DateDf = new SortedList<double, double>();
            for (int i = 0; i < mktRateSet.Count; i++)
            {
                DateDf.Add(PreProcessedData.ElementAt(i).endDate.SerialValue, PreProcessedData.ElementAt(i).Rate);
            }
        }


        protected override void Solve()
        {
            
            T = new Vector<double>(DateDf.Keys.ToArray(), 0);
            ObvRate = new Vector<double>(DateDf.Values.ToArray(), 0);
            // 对于Discount Factor插值
            if (MissingRateInterp == OneDimensionInterpolation.Linear)
            {
                MRInterp = new LinearInterpolator(T, ObvRate);
            }


            for (int i = 0; i < DateDf.Count - 1; i++)
            {
                Date dt1 = new Date(DateDf.Keys[i]);
                Date dt2 = dt1.add_period_string("6m", 0);
                while (dt2.SerialValue < DateDf.Keys[i + 1])
                {
                    double d = dt2.SerialValue;
                    DateDf.Add(d, MRInterp.Solve(d));   //插值missing
                    dt2 = dt2.add_period_string("6m", 0);
                }
            }                      
        }


        protected override void PostProcessData()
        {
             T = new Vector<double>(DateDf.Keys.ToArray(), 0);
            ObvRate = new Vector<double>(DateDf.Values.ToArray(), 0);
            this.PostProcessInterpo = new Interpolation();
            PostProcessInterpo.t=T;
            PostProcessInterpo.observedRate=ObvRate;


            for (int i = 0; i < 200; i+=10)
            {
                Console.WriteLine("{0}, {1}", new Date( DateDf.Keys[0] + i).ToString(), interpAdapter.FromDfToInterp(PostProcessInterpo.Solve(DateDf.Keys[0] + i), DateDf.Keys[0]+i));
            }


        }
        public override ISingleRateCurve CreateInstance(RateSet newRateSet)
        {
            throw new NotImplementedException();
        }
    }




    
    //4. BuildingBlock类型
    public class BuildingBlock:IComparable
    {
        //  成员变量
        public double Rate;
        public BuildingBlockType BBT;
        public Dc dc;
        public double Maturity;
        public Date startDate;
        public Date endDate;
        public string FloatTernsor; 
        //  构造器
        public BuildingBlock(double rate,Date enddate)
        {
            this.Rate=rate;
            this.endDate = enddate;
        }
        public BuildingBlock(double rate,string floattensor)
        {
            this.Rate=rate;
            this.FloatTernsor=floattensor;
        }
        //CompareTo   
        int  IComparable.CompareTo(object obj)
        {
            if (obj is BuildingBlock)
<span style="white-space:pre">	</span>                {
                        BuildingBlock bb = obj as BuildingBlock;
                return this.endDate.SerialValue>bb.endDate.SerialValue?1:(this.endDate.SerialValue==bb.endDate.SerialValue?0:-1);
<span style="white-space:pre">	</span>                }
                    else 
                    { 
                      throw new ArgumentException( "比较错误" );
                    } 
        }
}


    public enum OneDimensionInterpolation
    {
        Linear,
        Cubine
    }




    //Swap类型,继承自BuildingBlock类型
    public class SwapStyle : BuildingBlock
    {
        //  成员变量
        public string FixLegInterval;
        //  构造器
        public SwapStyle(double rate, Date enddate)
            : base(rate, enddate)
        {
            dc=Dc._30_360;
        }
    }
    public class EurSwapVs6m : SwapStyle
    {
        public EurSwapVs6m(double rate,Date enddate):base(rate,enddate)
        {
            BBT=BuildingBlockType.EURSWAP6M;
            FixLegInterval="6m";
            dc = Dc._30_360;
            //endDate=startDate.add_period(maturity);
        }
    }


    //5. 枚举型
    public enum BuildingBlockType
    {
        EURSWAP3M,
        EURSWAP6M,
        EONIASWAP,
        EURDEPO
    }


   
    


    


   












    public abstract class BaseOneDimensionalInterpolator 
    {
        public Vector<double> t;
        public Vector<double> observedRate;
        public BaseOneDimensionalInterpolator(Vector<double> t, Vector<double> ObservedRate)
        {
            this.t = t;
            this.observedRate = ObservedRate;
        }
        public BaseOneDimensionalInterpolator() 
        { }
        public abstract double Solve(double DateSerial);
        public abstract Vector<double> Curve(Vector<double> term);
    }




   


}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Globalization;


namespace FinMktReverseEngineering
{


    class test
    {


     
            static void Main(string[] args)  
       {  
                Date dt = new Date (new DateTime(2015,3,11));
                RateSet rateSet=new RateSet(dt);
                rateSet.Add(0.998, "6m", BuildingBlockType.EURSWAP6M);
                rateSet.Add(0.989, "1y", BuildingBlockType.EURSWAP6M);
                rateSet.Add(0.95, "2y", BuildingBlockType.EURSWAP6M);
                rateSet.Add(0.934, "4y", BuildingBlockType.EURSWAP6M);
                LinearInterpolator missingRateInterp;
                SingleCurveBuilderStandard<Onr, LinearInterpolator> sb = new SingleCurveBuilderStandard<Onr, LinearInterpolator>(rateSet,OneDimensionInterpolation.Linear);
                 
           Console.Read();  
       }  
        }


      
    }




 类似资料: