Ejemplo n.º 1
0
 /// <summary>
 /// 计算器初始化,计算中间变量
 /// </summary>
 /// <param name="info"></param>
 public AmericanOptionCalc(AmericanOptionInfo info)
 {
     try
     {
         #region 期权信息检查
         if (info.OptionType != 1 && info.OptionType != -1)
         {
             throw new Exception("期权类型非法");
         }
         if (info.N < 2)
         {
             throw new Exception("期数(执行步数)非法");
         }
         if (info.AssetPrice < 0)
         {
             throw new Exception("标的当前价格非法");
         }
         if (info.ExercisePrice < 0)
         {
             throw new Exception("执行价格非法");
         }
         if (info.EndDate <= info.StartDate)
         {
             throw new Exception("起始到期日期非法");
         }
         if (info.r < 0)
         {
             throw new Exception("无风险利率r非法");
         }
         if (info.q < 0)
         {
             throw new Exception("股息率q非法");
         }
         if (info.sigma == 0)
         {
             throw new Exception("波动率非法");
         }
         #endregion
         ExpiryDays        = (info.EndDate - info.StartDate).Days;
         AnnualTimePerStep = (double)ExpiryDays / 365 / info.N;
         b            = info.r - info.q;
         a            = Math.Exp(b * AnnualTimePerStep);
         DiscountRate = Math.Exp(-info.r * AnnualTimePerStep);
         OptionType   = info.OptionType;
         Info         = info;
         Calc(info, out u, out d, out p, out pNegative, out TreeAssetPrice, out TreeOptionPrice);
     }
     catch (Exception ex)
     {
         throw ex;
     }
 }
Ejemplo n.º 2
0
 private void Calc(AmericanOptionInfo info, out double tu, out double td, out double tp, out double tpNegative, out double[] tTreeAssetPrice, out double[] tTreeOptionPrice)
 {
     tu         = Math.Exp(info.sigma * Math.Sqrt(AnnualTimePerStep));
     td         = Math.Exp(-info.sigma * Math.Sqrt(AnnualTimePerStep));
     tp         = (a - td) / (tu - td);
     tpNegative = 1 - tp;
     #region 生成二叉树
     int numberOfNodes = (info.N + 2) * (info.N + 1) / 2;
     //计算标的价格
     tTreeAssetPrice = new double[numberOfNodes];
     //根节点
     tTreeAssetPrice[0] = info.AssetPrice;
     for (int i = 1; i <= info.N; i++)                              //i为层数,第i层有i+1个点,根节点在0层
     {
         int index  = (i * (i + 1) / 2);                            //第i层第1个点的索引
         int father = index - i;                                    //第i层第1个点父节点的索引
         tTreeAssetPrice[index] = tTreeAssetPrice[father] * tu;     //第i层第1个点由父节点上涨一次所得,乘上涨幅度u
         for (int j = 2; j <= i + 1; j++)                           //j为点数,首个点编号为1
         {
             index  = (i * (i + 1) / 2) + j - 1;                    //第i层第j个点的索引
             father = index - i - 1;                                //父节点的索引
             tTreeAssetPrice[index] = tTreeAssetPrice[father] * td; //由父节点下跌一次所得,乘下跌幅度d
         }
     }
     //计算期权价格
     tTreeOptionPrice = new double[numberOfNodes];
     //首先计算最底层N,共N+1个点
     for (int i = numberOfNodes - info.N - 1; i < numberOfNodes; i++)
     {
         tTreeOptionPrice[i] = Math.Max((tTreeAssetPrice[i] - info.ExercisePrice) * OptionType, 0);
     }
     //倒推
     int level = info.N - 1;                               //当前层数,初始在N-1层
     int cnt   = 0;
     for (int i = numberOfNodes - info.N - 2; i >= 0; i--) //i为索引
     {
         cnt++;                                            //当前为本层倒数第cnt个点
         double tmp1 = tp * tTreeOptionPrice[i + level + 1] + tpNegative * tTreeOptionPrice[i + level + 2];
         double tmp2 = Math.Exp(-info.r * AnnualTimePerStep) * tmp1;
         tTreeOptionPrice[i] = Math.Max((tTreeAssetPrice[i] - info.ExercisePrice) * OptionType, tmp2);
         if (cnt == level + 1) //本层遍历结束
         {
             cnt = 0;
             level--;
         }
     }
     #endregion
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 获取Rho
        /// </summary>
        public double GetRho()
        {
            double             epsilon = 0.00001;
            AmericanOptionInfo info2   = AmericanOptionInfo.Clone(Info);

            info2.r += epsilon;
            double tu = 0, td = 0, tp = 0, tpNegative = 0;

            double[] tTreeAssetPrice = null;
            double[] tTreeOptionPrice = null;
            Calc(info2, out tu, out td, out tp, out tpNegative, out tTreeAssetPrice, out tTreeOptionPrice);
            if (tTreeOptionPrice == null || tTreeOptionPrice.Length < 1)
            {
                throw new Exception("获取Rho失败");
            }
            return((tTreeOptionPrice[0] - TreeOptionPrice[0]) / epsilon * OptionType * 0.01);
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            try
            {
                //double test3 = 40927.52 * 100;
                //double test6 = (double)((decimal)40927.52 * 100);
                //double test9 = (double)((decimal)40927.525 * 100);
                //double test10 = Math.Floor(test9) / 100;
                //double test11 = (double)Math.Floor((decimal)40927.525 * 100) / 100;
                //double test7 = (float)40927.52 * 100;
                //double test2 = -40927.52 * 100;
                //double test1 = -Math.Abs(40927.52) * 100;
                //double test = Math.Ceiling(-Math.Abs(40927.52) * 100) / 100;
                //double test4 = -Math.Ceiling(Math.Abs(40927.52) * 100) / 100;
                //double test8 = -Math.Ceiling(Math.Abs(40927.5199) * 100) / 100;
                double test5  = Math.Floor(40927.52 * 100) / 100;
                double test12 = (double)Math.Floor((decimal)40927.52 * 100) / 100;

                #region 美式期权

                //某美式期权信息
                AmericanOptionInfo americanOptionInfo = new AmericanOptionInfo()
                {
                    OptionType    = -1,
                    N             = 2,
                    AssetPrice    = 3.061,
                    ExercisePrice = 3.12,
                    MarketPrice   = -0.0833,
                    StartDate     = new DateTime(2019, 12, 1),
                    EndDate       = new DateTime(2020, 1, 22),
                    sigma         = 0.1105,
                    r             = 0.0303,
                    q             = 0
                };

                Stopwatch sw1 = Stopwatch.StartNew();

                //美式期权计算器初始化
                AmericanOptionCalc americanOptionCalc = new AmericanOptionCalc(americanOptionInfo);

                sw1.Stop();
                Console.WriteLine(string.Format("初始化用时:{0}秒", sw1.Elapsed.TotalSeconds));

                Stopwatch sw2 = Stopwatch.StartNew();

                //获取理论价格
                double TheoreticalPrice = americanOptionCalc.GetTheoreticalPrice();
                //获取理论价格%
                double TheoreticalPricePer = americanOptionCalc.GetTheoreticalPricePercent();

                double Delta = americanOptionCalc.GetDelta();
                double Gamma = americanOptionCalc.GetGamma();
                double Vega  = americanOptionCalc.GetVega();
                double Theta = americanOptionCalc.GetTheta();
                double Rho   = americanOptionCalc.GetRho();

                double IntriValue    = americanOptionCalc.GetIntriValue();
                double TimeValue     = americanOptionCalc.GetTimeValue();
                double DueProfit     = americanOptionCalc.GetDueProfit();
                double CurrentProfit = americanOptionCalc.GetCurrentProfit();

                sw2.Stop();
                Console.WriteLine(string.Format("获取结果用时:{0}秒\r\n共{1}秒", sw2.Elapsed.TotalSeconds, sw1.Elapsed.TotalSeconds + sw2.Elapsed.TotalSeconds));

                #endregion

                #region 概率图

                Stopwatch sw3 = Stopwatch.StartNew();

                //样本价格序列S0
                List <double> S0 = new List <double>()
                {
                    3, 2, 3, 4, 5, 6, 7, 8, 7
                };
                //当前标的价格
                double AssetPrice = 3;
                //盈亏平衡点
                List <double> BalancePoints = new List <double>()
                {
                    4, 6
                };

                ProbabilityCalc probabilityCalc = new ProbabilityCalc(S0);
                //概率图点集(步骤八)
                List <Node> ProbabilityMap = probabilityCalc.GetProbabilityMap(AssetPrice, BalancePoints);
                //各区间概率大小(步骤七)
                List <double> IntervalProbability = probabilityCalc.GetIntervalProbability(BalancePoints);

                sw3.Stop();
                //各区间概率和越接近1,区间概率结果越精确
                Console.WriteLine(string.Format("概率图用时:{0}秒,各区间概率和:{1}", sw3.Elapsed.TotalSeconds, IntervalProbability.Sum()));

                #endregion

                Console.WriteLine("Hello World!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }