private double getOptionDelta(double strike, double duration, double r, double dividend, double vol, double stockPrice)
        {
            double delta = 0;

            delta = ImpliedVolatilityExtension.ComputeOptionDelta(strike, duration, r, dividend, "认购", vol, stockPrice);
            return(delta);
        }
        private double getOptionDelta(DateTime date, string BondCode, string stockCode)
        {
            double delta          = 0.5;
            var    bondInfo       = getBondDailyInfo(date, BondCode);
            int    days           = DateTimeExtension.DateUtils.GetSpanOfTradeDays(date, bondInfo.conversionEndDate);
            double duration       = (double)days / 252.0;
            var    stockList      = getPreviousStockCloseList(date, stockCode, days);
            var    stockLastClose = stockList[stockList.Count() - 1];
            double volatility     = HistoricalVolatilityExtension.getHistoricalVolatilityByClosePrice(stockList);

            double strike = bondInfo.conversionPrice;

            delta = ImpliedVolatilityExtension.ComputeOptionDelta(strike, duration, 0.04, 0, "认购", volatility, stockLastClose);
            return(delta);
        }
Exemple #3
0
        //计算从开始日期到结束日期的对冲成本
        private double deltaHedgePerDate(DateTime startDate, DateTime endDate, Dictionary <DateTime, double> vol)
        {
            double option     = 0;
            var    tradedays  = dateRepo.GetStockTransactionDate(startDate, endDate);
            int    deltaIndex = 220;
            //计算历史波动率参数
            string hedgeCode = "";
            double deltaNow  = 0;
            double pnl       = 0;
            double cash      = 0;
            //按第一天的开盘价确定期初价格和行权价
            var    stock      = stockDailyRepo.GetStockTransactionWithRedis(indexCode, startDate, endDate);
            double startPrice = stock[0].Open;
            double strike     = startPrice;

            foreach (var date in tradedays)
            {
                //获取当日期货合约代码
                var list = getSpecialFutureList(date);
                //获取当日收盘前标的价格
                // var index = stockMinutelyRepo.GetStockTransactionWithRedis(indexCode, date, date);
                var    index      = allData[date][indexCode];
                var    indexPrice = index[deltaIndex].Close;
                double duration   = (DateUtils.GetSpanOfTradeDays(date, endDate) + 1 / 12) / 252.0;
                //按标的计算收盘前delta值
                double deltaTarget = ImpliedVolatilityExtension.ComputeOptionDelta(strike, duration, 0.04, 0, "认沽", vol[date], indexPrice);

                //对冲未开仓进行开仓
                if (hedgeCode == "")
                {
                    hedgeCode = list.Last().Value.code;
                    double futurePrice = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += -futurePrice * deltaTarget;
                    deltaNow = deltaTarget;
                }
                //如果对冲的合约快到期时,进行移仓操作,移仓到季月合约
                if (list.ContainsKey(hedgeCode) && list[hedgeCode].expireDate.Date.AddDays(-7) <= date.Date)
                {
                    double futurePriceFront = allData[date][hedgeCode][deltaIndex + 1].Close;
                    hedgeCode = list.Last().Value.code;
                    double futurePriceNext = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += futurePriceFront * deltaNow - futurePriceNext * deltaTarget;
                    deltaNow = deltaTarget;
                }
                else if (list.ContainsKey(hedgeCode)) //对冲的合约未到期,继续对冲
                {
                    double futurePrice = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += -futurePrice * (deltaTarget - deltaNow);
                    deltaNow = deltaTarget;
                }
                //错误情况
                if (list.ContainsKey(hedgeCode) == false && hedgeCode != "")
                {
                    throw new ArgumentOutOfRangeException("对冲选取错误!!");
                }
            }
            //计算最后一天的PNL=cash+期货值的钱+付出去的期权收益
            var    lastDate        = tradedays.Last();
            double futureLastPrice = allData[lastDate][hedgeCode][239].Close;
            double indexLastPrice  = stock.Last().Close;

            pnl    = -(cash + deltaNow * futureLastPrice - Math.Max(startPrice - indexLastPrice, 0));
            option = pnl / startPrice;
            return(option);
        }
        private Dictionary <string, optionGreeks> getGreekInformation(DateTime date, StockTransaction underlyingData, Dictionary <string, StockOptionInformationWithModified> optionList, List <StockOptionTransaction> optionData)
        {
            double oneYearDays     = 280;
            double underlyingClose = Math.Round(underlyingData.Close, 3);
            Dictionary <string, optionGreeks>     greeks      = new Dictionary <string, optionGreeks>();
            Dictionary <DateTime, double>         durationDic = new Dictionary <DateTime, double>();
            Dictionary <DateTime, List <double> > strikeDic   = new Dictionary <DateTime, List <double> >();
            Dictionary <DateTime, double>         basisList   = new Dictionary <DateTime, double>();

            //希腊值的处理
            //预处理到期日和行权价
            foreach (var option in optionData)
            {
                var    info       = optionList[option.Code];
                var    expiredate = info.expireDate;
                double strike     = info.strike;
                double unit       = info.unit;
                if (info.existsModified == true && date < info.dividendDate)
                {
                    strike = info.strike;
                    unit   = info.unitBeforeModifed;
                }
                if (durationDic.ContainsKey(expiredate) == false)
                {
                    double modifiedDays = getModifiedDuration(date, expiredate, durationModifiedCoff);
                    oneYearDays = getModifiedDuration(expiredate.AddYears(-1), expiredate, durationModifiedCoff);
                    double duration = modifiedDays / oneYearDays;
                    durationDic.Add(expiredate, duration);
                }
                if (strikeDic.ContainsKey(expiredate) == false)
                {
                    List <double> strikeList = new List <double>();
                    strikeList.Add(strike);
                    strikeDic.Add(expiredate, strikeList);
                }
                else
                {
                    if (strikeDic[expiredate].Contains(strike) == false)
                    {
                        strikeDic[expiredate].Add(strike);
                    }
                }
            }
            //逐月逐行权价,计算基差,同时计算基本信息
            foreach (var list in strikeDic)
            {
                DateTime expireDate = list.Key;
                double   avgBasis   = 0;
                Dictionary <double, double> basisByStrike = new Dictionary <double, double>();
                foreach (var item in list.Value)
                {
                    double strike    = item;
                    double callPrice = 0;
                    double putPrice  = 0;
                    foreach (var option in optionData)
                    {
                        var info = optionList[option.Code];
                        //找出认购期权
                        if (info.type == "认购" && info.expireDate == expireDate)
                        {
                            if (info.existsModified == true && date < info.dividendDate)
                            {
                                if (info.strikeBeforeModified == strike)
                                {
                                    callPrice = option.Close;
                                }
                            }
                            if (info.existsModified == false && info.strike == strike)
                            {
                                callPrice = option.Close;
                            }
                        }
                        //找出认沽期权
                        if (info.type == "认沽" && info.expireDate == expireDate)
                        {
                            if (info.existsModified == true && date < info.dividendDate)
                            {
                                if (info.strikeBeforeModified == strike)
                                {
                                    putPrice = option.Close;
                                }
                            }
                            if (info.existsModified == false && info.strike == strike)
                            {
                                putPrice = option.Close;
                            }
                        }
                    }
                    double durationOfInterest = getInterestDuartion(date, expireDate);
                    double basis = callPrice - putPrice + strike * Math.Exp(-rate * durationOfInterest) - underlyingClose;
                    basisByStrike.Add(strike, basis);
                }
                List <double> strikeOrdered = list.Value.OrderBy(x => Math.Abs(x - underlyingClose)).ToList();
                for (int i = 0; i < 3; i++)
                {
                    avgBasis += basisByStrike[strikeOrdered[i]];
                }
                avgBasis = avgBasis / 3;
                basisList.Add(expireDate, avgBasis);
            }
            //逐合约计算波动率及希腊值
            foreach (var option in optionData)
            {
                optionGreeks greek       = new optionGreeks();
                var          info        = optionList[option.Code];
                double       strike      = info.strike;
                double       optionPrice = option.Close;
                int          unit        = info.unit;
                if (info.existsModified == true && date < info.dividendDate)
                {
                    strike = info.strike;
                    unit   = info.unitBeforeModifed;
                }
                greek.strike           = strike;
                greek.name             = info.name;
                greek.underlying       = info.underlying;
                greek.underlyPrice     = underlyingClose;
                greek.unit             = unit;
                greek.today            = date;
                greek.code             = info.code;
                greek.expireDate       = info.expireDate;
                greek.duration         = getInterestDuartion(date, info.expireDate);
                greek.modifiedDuration = getModifiedDuration(date, info.expireDate, durationModifiedCoff) / getModifiedDuration(info.expireDate.AddYears(-1), info.expireDate, durationModifiedCoff);
                greek.Basis            = basisList[info.expireDate];
                greek.optionPrice      = optionPrice;
                greek.type             = info.type;
                double optionPriceWithBasis = greek.underlyPrice + greek.Basis;
                //计算波动率
                greek.impliedVol = ImpliedVolatilityExtension.ComputeImpliedVolatility(greek.strike, greek.modifiedDuration, rate, 0, greek.type, greek.optionPrice, optionPriceWithBasis);
                greek.delta      = ImpliedVolatilityExtension.ComputeOptionDelta(greek.strike, greek.modifiedDuration, rate, 0, greek.type, greek.impliedVol, optionPriceWithBasis);
                greek.cashDelta  = greek.delta * greek.unit * greek.underlyPrice * 0.01;
                greek.vega       = ImpliedVolatilityExtension.ComputeOptionVega(greek.strike, greek.modifiedDuration, rate, 0, greek.impliedVol, optionPriceWithBasis);
                greek.cashVega   = greek.vega * greek.unit;
                greek.cashGamma  = 0.5 * greek.gamma * Math.Pow((greek.unit * greek.underlyPrice * 0.01), 2);
                greek.cashBasis  = greek.Basis * greek.delta * greek.unit;
                //讲信息写入希腊值列表
                greeks.Add(info.code, greek);
            }
            return(greeks);
        }