示例#1
0
        /// <summary>
        /// 计算期权持仓的delta值
        /// </summary>
        /// <param name="positionLast">最后持仓状态</param>
        /// <param name="holdingStatus">记录的跨式期权情况</param>
        /// <param name="today">今日日期</param>
        /// <param name="dataToday">今日数据</param>
        /// <param name="index">交易时间对应的下标</param>
        /// <returns></returns>
        private double computeOptionDelta(Dictionary <string, PositionsWithDetail> positionLast, StraddlePair holdingStatus, DateTime today, Dictionary <string, List <KLine> > dataToday, int index)
        {
            double delta = 0;

            foreach (var item in positionLast)
            {
                if (item.Key == holdingStatus.callCodeFront)
                {
                    var callDelta = ImpliedVolatilityUtilities.ComputeOptionDelta(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDate) / 252.0, 0.04, 0, "认购", ImpliedVolatilityUtilities.ComputeImpliedVolatility(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDate) / 252.0, 0.04, 0, "认购", dataToday[item.Key][index].close, dataToday["510050.SH"][index].close), dataToday["510050.SH"][index].close);
                    delta += holdingStatus.callPositionFront * callDelta;
                }
                if (item.Key == holdingStatus.putCodeFront)
                {
                    var putDelta = ImpliedVolatilityUtilities.ComputeOptionDelta(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDate) / 252.0, 0.04, 0, "认沽", ImpliedVolatilityUtilities.ComputeImpliedVolatility(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDate) / 252.0, 0.04, 0, "认沽", dataToday[item.Key][index].close, dataToday["510050.SH"][index].close), dataToday["510050.SH"][index].close);
                    delta += holdingStatus.putPositionFront * putDelta;
                }
                if (item.Key == holdingStatus.callCodeNext)
                {
                    var callDelta = ImpliedVolatilityUtilities.ComputeOptionDelta(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDateNext) / 252.0, 0.04, 0, "认购", ImpliedVolatilityUtilities.ComputeImpliedVolatility(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDateNext) / 252.0, 0.04, 0, "认购", dataToday[item.Key][index].close, dataToday["510050.SH"][index].close), dataToday["510050.SH"][index].close);
                    delta += holdingStatus.callPositionNext * callDelta;
                }
                if (item.Key == holdingStatus.putCodeNext)
                {
                    var putDelta = ImpliedVolatilityUtilities.ComputeOptionDelta(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDateNext) / 252.0, 0.04, 0, "认沽", ImpliedVolatilityUtilities.ComputeImpliedVolatility(holdingStatus.strike, DateUtils.GetSpanOfTradeDays(today, holdingStatus.endDateNext) / 252.0, 0.04, 0, "认沽", dataToday[item.Key][index].close, dataToday["510050.SH"][index].close), dataToday["510050.SH"][index].close);
                    delta += holdingStatus.putPositionNext * putDelta;
                }
            }
            return(delta);
        }
        /// <summary>
        /// 估算未来的期权价格
        /// </summary>
        /// <param name="days"></param>
        /// <param name="code"></param>
        /// <param name="etfPrice"></param>
        /// <returns></returns>
        private double computeFuturePrice(int days, string code, double etfPrice)
        {
            double price  = 0;
            var    option = OptionUtilities.getOptionByCode(optionList, code);
            int    x      = Convert.ToInt32(optionPrice[code].duration - days);
            int    y      = Convert.ToInt32(Math.Round(1000 * Math.Log(option.strike / etfPrice), 0) + 500);
            double vol    = volSurface[x, y];

            price = ImpliedVolatilityUtilities.ComputeOptionPrice(option.strike, (optionPrice[code].duration - days) / 252.0, riskFreeRate, 0, option.optionType, vol, etfPrice);
            return(price);
        }
示例#3
0
        public void computeVol()
        {
            var etfPrice = dataList[ETF].last;

            Console.Clear();
            foreach (var code  in dataListKey)
            {
                var option     = dataList[code];
                var optionCode = code;
                if (optionCode != ETF && etfPrice != 0)
                {
                    var info   = optionInfo[optionCode];
                    var ask    = option.ask1;
                    var bid    = option.bid1;
                    var mid    = (ask + bid) / 2;
                    var strike = info.strike;
                    var type   = info.optionType;
                    var vol    = ImpliedVolatilityUtilities.ComputeImpliedVolatility(strike: strike, duration: duartion / 252.0, riskFreeRate: rate, StockRate: 0, optionType: type, optionPrice: mid, underlyingPrice: etfPrice);
                    Console.WriteLine("本地时间:{2},数据时间:{3},期权:{0},波动率:{1}", info.optionName, Math.Round(vol, 3), DateTime.Now.TimeOfDay.ToString("hhmmss"), option.time.ToString("hhmmss"));
                }
            }
        }
 private void computeImpv()
 {
     optionVol = new double[etfDailyData.Count()];
     for (int i = startIndex; i < etfDailyData.Count(); i++)
     {
         DateTime today    = etfDailyData[i].time;
         double   etfPrice = etfDailyData[i].close;
         double   volThisMonth;
         double   volNextMonth;
         double   duration;
         //获取当日期限结构,选取当月合约
         List <double> dateStructure = OptionUtilities.getDurationStructure(optionInfoList, today);
         double        duration0     = dateStructure[0] == 0 ? dateStructure[1] : dateStructure[0];
         duration = duration0;
         var    call      = OptionUtilities.getOptionListByOptionType(OptionUtilities.getOptionListByDuration(optionInfoList, today, duration), "认购").OrderBy(x => Math.Abs(x.strike - etfPrice)).Where(x => x.startDate <= today).ToList();
         var    callATM   = call[0];
         var    callPrice = Platforms.container.Resolve <OptionDailyRepository>().fetchFromLocalCsvOrWindAndSave(callATM.optionCode, today, today);
         double callImpv  = ImpliedVolatilityUtilities.ComputeImpliedVolatility(callATM.strike, duration / 252.0, 0.04, 0, callATM.optionType, callPrice[0].close, etfPrice);
         var    put       = OptionUtilities.getOptionListByOptionType(OptionUtilities.getOptionListByDuration(optionInfoList, today, duration), "认沽").OrderBy(x => Math.Abs(x.strike - callATM.strike)).ToList();
         var    putATM    = put[0];
         var    putPrice  = Platforms.container.Resolve <OptionDailyRepository>().fetchFromLocalCsvOrWindAndSave(putATM.optionCode, today, today);
         double putImpv   = ImpliedVolatilityUtilities.ComputeImpliedVolatility(putATM.strike, duration / 252.0, 0.04, 0, putATM.optionType, putPrice[0].close, etfPrice);
         if (callImpv * putImpv == 0)
         {
             volThisMonth = callImpv + putImpv;
         }
         else
         {
             volThisMonth = (callImpv + putImpv) / 2;
         }
         //获取当日期限结构,选取下月合约,若下月合约不存在,就获取季月合约
         double duration1 = dateStructure[0] == 0 ? dateStructure[2] : dateStructure[1];
         duration  = duration1;
         call      = OptionUtilities.getOptionListByOptionType(OptionUtilities.getOptionListByDuration(optionInfoList, today, duration), "认购").OrderBy(x => Math.Abs(x.strike - etfPrice)).Where(x => x.startDate <= today).ToList();
         callATM   = call[0];
         callPrice = Platforms.container.Resolve <OptionDailyRepository>().fetchFromLocalCsvOrWindAndSave(callATM.optionCode, today, today);
         callImpv  = ImpliedVolatilityUtilities.ComputeImpliedVolatility(callATM.strike, duration / 252.0, 0.04, 0, callATM.optionType, callPrice[0].close, etfPrice);
         put       = OptionUtilities.getOptionListByOptionType(OptionUtilities.getOptionListByDuration(optionInfoList, today, duration), "认沽").OrderBy(x => Math.Abs(x.strike - callATM.strike)).ToList();
         putATM    = put[0];
         putPrice  = Platforms.container.Resolve <OptionDailyRepository>().fetchFromLocalCsvOrWindAndSave(putATM.optionCode, today, today);
         putImpv   = ImpliedVolatilityUtilities.ComputeImpliedVolatility(putATM.strike, duration / 252.0, 0.04, 0, putATM.optionType, putPrice[0].close, etfPrice);
         if (callImpv * putImpv == 0)
         {
             volNextMonth = callImpv + putImpv;
         }
         else
         {
             volNextMonth = (callImpv + putImpv) / 2;
         }
         if (duration0 >= step)
         {
             optionVol[i] = Math.Sqrt(step / duration0) * volThisMonth;
         }
         else if ((duration0 < step && duration1 > step))
         {
             optionVol[i] = Math.Sqrt((duration1 - step) / (duration1 - duration0)) * volThisMonth + Math.Sqrt((step - duration0) / (duration1 - duration0)) * volNextMonth;
         }
         else if (duration1 <= step)
         {
             optionVol[i] = volNextMonth;
         }
     }
 }