예제 #1
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);
        }