Exemplo n.º 1
0
        public override IPricingResult Calculate(BinaryOption trade, IMarketCondition market, PricingRequest request)
        {
            var result = new PricingResult(market.ValuationDate, request);

            if (trade.BinaryOptionPayoffType == BinaryOptionPayoffType.CashOrNothing)
            {
                var factor     = (double)BinaryOptionReplicationStrategy;
                var lowStrike  = trade.Strike + Offset * (factor - 1.0) / 2.0;
                var highStrike = trade.Strike + Offset * (factor + 1.0) / 2.0;

                //if call, replicate by call spreads,
                //if put, replicate by put spreads

                var lowStrikeOption  = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, lowStrike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional);
                var highStrikeOption = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, highStrike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional);
                var engine           = new AnalyticalVanillaEuropeanOptionEngine();
                var lowResult        = engine.Calculate(lowStrikeOption, market, request);
                var highResult       = engine.Calculate(highStrikeOption, market, request);

                var sign = trade.OptionType == OptionType.Call ? 1.0 : -1.0;
                factor = sign * trade.CashOrNothingAmount / Offset;

                //calc basic stuff
                if (result.IsRequested(PricingRequest.Pv))
                {
                    result.Pv = (lowResult.Pv - highResult.Pv) * factor;
                }
                if (AnalyticalOptionPricerUtil.isBasicPricing(result))
                {
                    result.Delta     = (lowResult.Delta - highResult.Delta) * factor;
                    result.DeltaCash = result.Delta * market.SpotPrices.Value.Values.First();
                    result.Gamma     = (lowResult.Gamma - highResult.Gamma) * factor;
                    result.GammaCash = result.Gamma * market.SpotPrices.Value.Values.First() * market.SpotPrices.Value.Values.First() / 100;
                    result.Vega      = (lowResult.Vega - highResult.Vega) * factor;
                    result.Rho       = (lowResult.Rho - highResult.Rho) * factor;
                    result.Theta     = (lowResult.Theta - highResult.Theta) * factor;
                }
                if (AnalyticalOptionPricerUtil.isHighOrderPricing(result))
                {
                    result.DDeltaDvol = (lowResult.DDeltaDvol - highResult.DDeltaDvol) * factor;
                    result.DVegaDvol  = (lowResult.DVegaDvol - highResult.DVegaDvol) * factor;
                    result.DVegaDt    = (lowResult.DVegaDt - highResult.DVegaDt) * factor;
                    result.DDeltaDt   = (lowResult.DDeltaDt - highResult.DDeltaDt) * factor;
                }
            }
            else if (trade.BinaryOptionPayoffType == BinaryOptionPayoffType.AssetOrNothing)
            {
                var binaryCfOption = new BinaryOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType,
                                                      trade.Strike, trade.UnderlyingProductType, BinaryOptionPayoffType.CashOrNothing, 1.0, trade.Calendar,
                                                      trade.DayCount, trade.PayoffCcy,
                                                      trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates);
                var binaryResult  = Calculate(binaryCfOption, market, request);
                var vanillaOption = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType,
                                                      trade.Strike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy,
                                                      trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional);
                var engine        = new AnalyticalVanillaEuropeanOptionEngine();
                var vanillaResult = engine.Calculate(vanillaOption, market, request);
                var sign          = trade.OptionType == OptionType.Call ? 1.0 : -1.0;

                if (result.IsRequested(PricingRequest.Pv))
                {
                    result.Pv = sign * vanillaResult.Pv + trade.Strike * binaryResult.Pv;
                }

                if (AnalyticalOptionPricerUtil.isBasicPricing(result))
                {
                    result.Delta     = sign * vanillaResult.Delta + trade.Strike * binaryResult.Delta;
                    result.DeltaCash = result.Delta * market.SpotPrices.Value.Values.First();
                    result.Gamma     = sign * vanillaResult.Gamma + trade.Strike * binaryResult.Gamma;
                    result.GammaCash = result.Gamma * market.SpotPrices.Value.Values.First() * market.SpotPrices.Value.Values.First() / 100;
                    result.Vega      = sign * vanillaResult.Vega + trade.Strike * binaryResult.Vega;
                    result.Rho       = sign * vanillaResult.Rho + trade.Strike * binaryResult.Rho;
                    result.Theta     = sign * vanillaResult.Theta + trade.Strike * binaryResult.Theta;
                }

                if (AnalyticalOptionPricerUtil.isHighOrderPricing(result))
                {
                    result.DDeltaDvol = sign * vanillaResult.DDeltaDvol + trade.Strike * binaryResult.DDeltaDvol;
                    result.DVegaDvol  = sign * vanillaResult.DVegaDvol + trade.Strike * binaryResult.DVegaDvol;
                    result.DVegaDt    = sign * vanillaResult.DVegaDt + trade.Strike * binaryResult.DVegaDt;
                    result.DDeltaDt   = sign * vanillaResult.DDeltaDt + trade.Strike * binaryResult.DDeltaDt;
                }
            }
            return(result);
        }
Exemplo n.º 2
0
        public override IPricingResult Calculate(RainbowOption trade, IMarketCondition market, PricingRequest request)
        {
            var result = new PricingResult(market.ValuationDate, request);

            var exerciseDate = trade.ExerciseDates.Last();
            var maturityDate = trade.UnderlyingMaturityDate;

            //TODO:  support timeIncrement
            var exerciseInYears = AnalyticalOptionPricerUtil.timeToMaturityFraction(market.ValuationDate, exerciseDate, trade);
            var maturityInYears = AnalyticalOptionPricerUtil.timeToMaturityFraction(market.ValuationDate, maturityDate, trade);

            var riskFreeRate = market.DiscountCurve.Value.ZeroRate(market.ValuationDate, exerciseDate);
            var ticker1      = trade.UnderlyingTickers[0];
            var ticker2      = trade.UnderlyingTickers[1];

            double dividendRate1, dividendRate2;

            if (AnalyticalOptionPricerUtil.isForwardFuturesOption(trade.UnderlyingProductType))
            {
                dividendRate1 = riskFreeRate;
                dividendRate2 = riskFreeRate;
            }
            else
            {
                dividendRate1 = market.DividendCurves.Value[ticker1].ZeroRate(market.ValuationDate, exerciseDate);
                dividendRate2 = market.DividendCurves.Value[ticker2].ZeroRate(market.ValuationDate, exerciseDate);
            }

            var spot1 = market.SpotPrices.Value[ticker1];
            var spot2 = market.SpotPrices.Value[ticker2];

            var sigma1 = market.VolSurfaces.Value[ticker1].GetValue(exerciseDate, trade.Strikes[0], spot1);
            var sigma2 = market.VolSurfaces.Value[ticker2].GetValue(exerciseDate, trade.Strikes[0], spot2);

            var strike1 = trade.Strikes[0];

            var strike2 = 0.0;

            if (trade.Strikes.Length > 1)
            {
                strike2 = trade.Strikes[1];
            }

            //Note: correlation here is a scala number.  can be a grid for multi-asset option
            var rho = market.Correlations.Value[ticker1].GetValue(exerciseDate, strike1);

            var calculator = new RainbowOptionCalculator(trade.OptionType,
                                                         trade.RainbowType,
                                                         strike1, strike2, trade.CashAmount,
                                                         spot1, spot2, rho,
                                                         sigma1, sigma2,
                                                         exerciseInYears,
                                                         riskFreeRate,
                                                         dividendRate1, dividendRate2,
                                                         trade.Notional);

            bool isExpired         = trade.ExerciseDates.Last() < market.ValuationDate;
            bool isExpiredforTheta = trade.ExerciseDates.Last() <= market.ValuationDate;

            if (isExpired)
            {
                result.Pv                 = 0.0;
                result.Theta              = 0.0;
                result.asset1Delta        = 0.0;
                result.asset1DeltaCash    = 0.0;
                result.asset2Delta        = 0.0;
                result.asset2DeltaCash    = 0.0;
                result.asset1PartialDelta = 0.0;
                result.asset2PartialDelta = 0.0;
                result.asset1Gamma        = 0.0;
                result.asset1GammaCash    = 0.0;
                result.asset2Gamma        = 0.0;
                result.asset2GammaCash    = 0.0;
                result.asset1Vega         = 0.0;
                result.asset2Vega         = 0.0;
                result.Rho                = 0.0;
                result.Theta              = 0.0;
                result.asset1DDeltaDt     = 0.0;
                result.asset2DDeltaDt     = 0.0;
                result.asset1DVegaDvol    = 0.0;
                result.asset2DVegaDvol    = 0.0;
                result.asset1DDeltaDvol   = 0.0;
                result.asset2DDeltaDvol   = 0.0;
                result.asset1DVegaDt      = 0.0;
                result.asset2DVegaDt      = 0.0;
                result.crossGamma         = 0.0;
                result.crossVomma         = 0.0;
                result.crossVanna1        = 0.0;
                result.crossVanna2        = 0.0;
                result.correlationVega    = 0.0;
            }

            else
            {
                if (result.IsRequested(PricingRequest.Pv))
                {
                    result.Pv = calculator.Pv;
                }

                if (AnalyticalOptionPricerUtil.isBasicPricing(result))
                {
                    result.asset1Delta        = calculator.asset1Delta;
                    result.asset2Delta        = calculator.asset2Delta;
                    result.asset1DeltaCash    = calculator.asset1Delta * spot1;
                    result.asset2DeltaCash    = calculator.asset2Delta * spot2;
                    result.asset1PartialDelta = calculator.asset1PartialDelta;
                    result.asset2PartialDelta = calculator.asset2PartialDelta;
                    result.asset1Gamma        = calculator.asset1Gamma;
                    result.asset2Gamma        = calculator.asset2Gamma;
                    result.asset1GammaCash    = calculator.asset1Gamma * spot1 * spot1 / 100;
                    result.asset2GammaCash    = calculator.asset2Gamma * spot2 * spot2 / 100;
                    result.asset1Vega         = calculator.asset1Vega;
                    result.asset2Vega         = calculator.asset2Vega;
                    result.Rho = calculator.Rho;

                    result.Theta = (isExpiredforTheta) ? 0.0 : calculator.Theta;
                }

                if (AnalyticalOptionPricerUtil.isHighOrderPricing(result))
                {
                    result.asset1DVegaDvol  = calculator.asset1DVegaDvol;
                    result.asset2DVegaDvol  = calculator.asset2DVegaDvol;
                    result.asset1DDeltaDvol = calculator.asset1DDeltaDvol;
                    result.asset2DDeltaDvol = calculator.asset2DDeltaDvol;
                    result.crossGamma       = calculator.crossGamma;
                    result.crossVomma       = calculator.crossVomma;
                    result.crossVanna1      = calculator.crossVanna1;
                    result.crossVanna2      = calculator.crossVanna2;
                    result.correlationVega  = calculator.correlationVega;
                }


                if (isExpiredforTheta)
                {
                    result.asset1DDeltaDt = result.asset2DDeltaDt = 0.0;
                    result.asset1DVegaDt  = result.asset2DVegaDt = 0.0;
                }
                else
                {
                    result.asset1DDeltaDt = calculator.asset1DDeltaDt;
                    result.asset2DDeltaDt = calculator.asset2DDeltaDt;
                    result.asset1DVegaDt  = calculator.asset1DVegaDt;
                    result.asset2DVegaDt  = calculator.asset2DVegaDt;
                }
            }
            return(result);
        }