public static Greeks GetOptionOnFutureGreeks(double underlyingPrice, double strike, double riskFreeRate,
                                                     DateTime expirationDate, DateTime calculationDate, string optionType, string exerciseType,
                                                     double optionPrice = double.NaN, double impliedVol = 0.15, string engineName = "baw")
        {
            QLNet.Date ExpirationDateObj  = new QLNet.Date(expirationDate.Day, expirationDate.Month, expirationDate.Year);
            QLNet.Date CalculationDateObj = new QLNet.Date(calculationDate.Day, calculationDate.Month, calculationDate.Year);

            QLNet.DayCounter DayCountObj = new QLNet.Actual365Fixed();
            QLNet.Calendar   CalendarObj = new QLNet.UnitedStates();

            Greeks GreeksOutput = new Greeks();

            QLNet.Option.Type OptionTypeObj;
            QLNet.Exercise    ExerciseObj;
            double            ImpliedVol;
            double            OptionPrice;

            int CalDte = DayCountObj.dayCount(CalculationDateObj, ExpirationDateObj);

            GreeksOutput.CalDte = CalDte;

            if (!double.IsNaN(optionPrice))
            {
                if (optionType.ToUpper() == "C")
                {
                    if (optionPrice + strike - underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = 1;
                        return(GreeksOutput);
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (optionPrice - strike + underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = -1;
                        return(GreeksOutput);
                    }
                }
            }

            if (CalDte == 0)
            {
                if (optionType.ToUpper() == "C")
                {
                    if (strike <= underlyingPrice)
                    {
                        GreeksOutput.Delta = 1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (strike >= underlyingPrice)
                    {
                        GreeksOutput.Delta = -1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                return(GreeksOutput);
            }

            if (optionType.ToUpper() == "C")
            {
                OptionTypeObj = QLNet.Option.Type.Call;
            }
            else if (optionType.ToUpper() == "P")
            {
                OptionTypeObj = QLNet.Option.Type.Put;
            }
            else
            {
                return(GreeksOutput);
            }

            if (exerciseType.ToUpper() == "E")
            {
                ExerciseObj = new QLNet.EuropeanExercise(ExpirationDateObj);
            }
            else if (exerciseType.ToUpper() == "A")
            {
                ExerciseObj = new QLNet.AmericanExercise(CalculationDateObj, ExpirationDateObj);
            }
            else
            {
                return(GreeksOutput);
            }

            QLNet.Settings.setEvaluationDate(CalculationDateObj);

            QLNet.Handle <Quote> UnderlyingObj = new QLNet.Handle <Quote>(new QLNet.SimpleQuote(underlyingPrice));
            QLNet.Handle <YieldTermStructure>    FlatRateObj  = new QLNet.Handle <YieldTermStructure>(new QLNet.FlatForward(CalculationDateObj, riskFreeRate, DayCountObj));
            QLNet.Handle <BlackVolTermStructure> FlatVolTsObj = new QLNet.Handle <BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, impliedVol, DayCountObj));

            QLNet.BlackProcess       BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);
            QLNet.PlainVanillaPayoff PayoffObj = new QLNet.PlainVanillaPayoff(OptionTypeObj, strike);

            QLNet.VanillaOption OptionObj = new QLNet.VanillaOption(PayoffObj, ExerciseObj);

            if (engineName == "baw")
            {
                OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
            }
            else if (engineName == "fda")
            {
                OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
            }
            else
            {
                return(GreeksOutput);
            }


            if (!double.IsNaN(optionPrice))
            {
                try
                {
                    ImpliedVol = OptionObj.impliedVolatility(targetValue: optionPrice, process: BlackProc, accuracy: 1e-5);
                }
                catch
                {
                    return(GreeksOutput);
                }

                FlatVolTsObj = new QLNet.Handle <BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, ImpliedVol, DayCountObj));
                BlackProc    = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);

                if (engineName == "baw")
                {
                    OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
                }
                else if (engineName == "fda")
                {
                    OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
                }
                OptionPrice = optionPrice;
            }
            else
            {
                OptionPrice = OptionObj.NPV();
                ImpliedVol  = impliedVol;
            }

            OptionObj = new QLNet.VanillaOption(PayoffObj, new QLNet.EuropeanExercise(ExpirationDateObj));
            OptionObj.setPricingEngine(new QLNet.AnalyticEuropeanEngine(BlackProc));

            GreeksOutput.Delta       = OptionObj.delta();
            GreeksOutput.Vega        = OptionObj.vega();
            GreeksOutput.Theta       = OptionObj.thetaPerDay();
            GreeksOutput.Gamma       = OptionObj.gamma();
            GreeksOutput.OptionPrice = OptionPrice;
            GreeksOutput.ImpliedVol  = ImpliedVol;

            return(GreeksOutput);
        }
Ejemplo n.º 2
0
      public  SwaptionHelper(Period maturity,
                       Period length,
                       Handle<Quote> volatility,
                       IborIndex index,
                       Period fixedLegTenor,
                       DayCounter fixedLegDayCounter,
                       DayCounter floatingLegDayCounter,
                       Handle<YieldTermStructure> termStructure,
                       bool calibrateVolatility /*= false*/)
       : base(volatility,termStructure, calibrateVolatility) {

        Calendar calendar = index.fixingCalendar();
        Period indexTenor = index.tenor();
        int fixingDays = index.fixingDays();

        Date exerciseDate   = calendar.advance(termStructure.link.referenceDate(),
                                                maturity,
                                                index.businessDayConvention());
        Date startDate      = calendar.advance(exerciseDate,
                                                fixingDays, TimeUnit.Days,
                                                index.businessDayConvention());
        Date endDate        = calendar.advance(startDate, length,
                                                index.businessDayConvention());

        Schedule fixedSchedule=new Schedule(startDate, endDate, fixedLegTenor, calendar,
                                            index.businessDayConvention(),
                                            index.businessDayConvention(),
                                            DateGeneration.Rule.Forward, false);
        Schedule floatSchedule=new Schedule(startDate, endDate, index.tenor(), calendar,
                                            index.businessDayConvention(),
                                            index.businessDayConvention(),
                                            DateGeneration.Rule.Forward, false);

        IPricingEngine swapEngine=new DiscountingSwapEngine(termStructure);

        VanillaSwap temp=new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                        fixedSchedule, 0.0, fixedLegDayCounter,
                                        floatSchedule, index, 0.0, floatingLegDayCounter);
        temp.setPricingEngine(swapEngine);
        exerciseRate_ = temp.fairRate();
        swap_ = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                            fixedSchedule, exerciseRate_, fixedLegDayCounter,
                            floatSchedule, index, 0.0, floatingLegDayCounter);
        swap_.setPricingEngine(swapEngine);

        Exercise exercise=new EuropeanExercise(exerciseDate);
        swaption_ = new Swaption(swap_, exercise);
        marketValue_ = blackPrice(volatility_.link.value());
}
        static void Main(string[] args)
        {
            Calendar calendar = new TARGET();

            Date todaysDate = new Date(22, 7, 2014);
            Date settlementDate = new Date(3, 6, 2014);
            Settings.setEvaluationDate(todaysDate);

            DayCounter dayCounter = new Actual365Fixed();
            double dividendYield = 0.0117;
            double volatility = 0.15517;

            Barrier.Type type = Barrier.Type.UpOut;
            QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call,261.4);
            QLNet.EuropeanExercise ex = new EuropeanExercise(new Date(30,11,2015));

            //QLNet.BarrierOption barrierOption = new BarrierOption(type, 1.2,1.0, 0.0, payoff, ex);
            //QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.0, payoff, ex);
            QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.32,0.0, payoff, ex);

            double underlying = 262.86;
            double riskFreeRate = 0.0243;
            
            Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying));

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);
            barrierOption.setPricingEngine(engine);

            double kk = barrierOption.NPV();

            Console.WriteLine(kk);
            Console.WriteLine(kk / 261.4);
        }
Ejemplo n.º 4
0
        //void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Dictionary<string,double> tolerance,
        //                           bool testGreeks = false) {
        void testEngineConsistency(EngineType engine, int binomialSteps, int samples, Dictionary<string, double> tolerance,
            bool testGreeks)
        {
            //QL_TEST_START_TIMING

             Dictionary<string, double> calculated = new Dictionary<string, double>(), expected = new Dictionary<string, double>();

             // test options
             Option.Type[] types = { Option.Type.Call, Option.Type.Put };
             double[] strikes = { 75.0, 100.0, 125.0 };
             int[] lengths = { 1 };

             // test data
             double[] underlyings = { 100.0 };
             double[] qRates = { 0.00, 0.05 };
             double[] rRates = { 0.01, 0.05, 0.15 };
             double[] vols = { 0.11, 0.50, 1.20 };

             DayCounter dc = new Actual360();
             Date today = Date.Today;

             SimpleQuote spot = new SimpleQuote(0.0);
             SimpleQuote vol = new SimpleQuote(0.0);
             BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc);
             SimpleQuote qRate = new SimpleQuote(0.0);
             YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc);
             SimpleQuote rRate = new SimpleQuote(0.0);
             YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);

             for (int i = 0; i < types.Length; i++)
             {
            for (int j = 0; j < strikes.Length; j++)
            {
               for (int k = 0; k < lengths.Length; k++)
               {
                  Date exDate = today + lengths[k] * 360;
                  Exercise exercise = new EuropeanExercise(exDate);
                  StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]);
                  // reference option
                  VanillaOption refOption = makeOption(payoff, exercise, spot, qTS, rTS, volTS,
                                            EngineType.Analytic, 0, 0);
                  // option to check
                  VanillaOption option = makeOption(payoff, exercise, spot, qTS, rTS, volTS,
                                 engine, binomialSteps, samples);

                  for (int l = 0; l < underlyings.Length; l++)
                  {
                     for (int m = 0; m < qRates.Length; m++)
                     {
                        for (int n = 0; n < rRates.Length; n++)
                        {
                           for (int p = 0; p < vols.Length; p++)
                           {
                              double u = underlyings[l];
                              double q = qRates[m],
                                   r = rRates[n];
                              double v = vols[p];
                              spot.setValue(u);
                              qRate.setValue(q);
                              rRate.setValue(r);
                              vol.setValue(v);

                              expected.Clear();
                              calculated.Clear();

                              // FLOATING_POINT_EXCEPTION
                              expected.Add("value", refOption.NPV());
                              calculated.Add("value", option.NPV());

                              if (testGreeks && option.NPV() > spot.value() * 1.0e-5)
                              {
                                 expected.Add("delta", refOption.delta());
                                 expected.Add("gamma", refOption.gamma());
                                 expected.Add("theta", refOption.theta());
                                 calculated.Add("delta", option.delta());
                                 calculated.Add("gamma", option.gamma());
                                 calculated.Add("theta", option.theta());
                              }
                              foreach (string greek in calculated.Keys)
                              {
                                 double expct = expected[greek],
                                      calcl = calculated[greek],
                                      tol = tolerance[greek];
                                 double error = Utilities.relativeError(expct, calcl, u);
                                 if (error > tol)
                                 {
                                    REPORT_FAILURE(greek, payoff, exercise,
                                                   u, q, r, today, v,
                                                   expct, calcl, error, tol);
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
             }
        }
        public override void calculate()
        {
            if (arguments_.barrierType == DoubleBarrier.Type.KIKO ||
                arguments_.barrierType == DoubleBarrier.Type.KOKI)
            {
                AmericanExercise ex = arguments_.exercise as AmericanExercise;
                Utils.QL_REQUIRE(ex != null, () => "KIKO/KOKI options must have American exercise");
                Utils.QL_REQUIRE(ex.dates()[0] <=
                                 process_.blackVolatility().currentLink().referenceDate(),
                                 () => "American option with window exercise not handled yet");
            }
            else
            {
                EuropeanExercise ex = arguments_.exercise as EuropeanExercise;
                Utils.QL_REQUIRE(ex != null, () => "non-European exercise given");
            }
            CashOrNothingPayoff payoff = arguments_.payoff as CashOrNothingPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "a cash-or-nothing payoff must be given");

            double spot = process_.stateVariable().currentLink().value();

            Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given");

            double variance =
                process_.blackVolatility().currentLink().blackVariance(
                    arguments_.exercise.lastDate(),
                    payoff.strike());
            double barrier_lo = arguments_.barrier_lo.Value;
            double barrier_hi = arguments_.barrier_hi.Value;

            DoubleBarrier.Type barrierType = arguments_.barrierType;
            Utils.QL_REQUIRE(barrier_lo > 0.0,
                             () => "positive low barrier value required");
            Utils.QL_REQUIRE(barrier_hi > 0.0,
                             () => "positive high barrier value required");
            Utils.QL_REQUIRE(barrier_lo < barrier_hi,
                             () => "barrier_lo must be < barrier_hi");
            Utils.QL_REQUIRE(barrierType == DoubleBarrier.Type.KnockIn ||
                             barrierType == DoubleBarrier.Type.KnockOut ||
                             barrierType == DoubleBarrier.Type.KIKO ||
                             barrierType == DoubleBarrier.Type.KOKI,
                             () => "Unsupported barrier type");

            // degenerate cases
            switch (barrierType)
            {
            case DoubleBarrier.Type.KnockOut:
                if (spot <= barrier_lo || spot >= barrier_hi)
                {
                    // knocked out, no value
                    results_.value = 0;
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                break;

            case DoubleBarrier.Type.KnockIn:
                if (spot <= barrier_lo || spot >= barrier_hi)
                {
                    // knocked in - pays
                    results_.value = payoff.cashPayoff();
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                break;

            case DoubleBarrier.Type.KIKO:
                if (spot >= barrier_hi)
                {
                    // knocked out, no value
                    results_.value = 0;
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                else if (spot <= barrier_lo)
                {
                    // knocked in, pays
                    results_.value = payoff.cashPayoff();
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                break;

            case DoubleBarrier.Type.KOKI:
                if (spot <= barrier_lo)
                {
                    // knocked out, no value
                    results_.value = 0;
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                else if (spot >= barrier_hi)
                {
                    // knocked in, pays
                    results_.value = payoff.cashPayoff();
                    results_.delta = 0;
                    results_.gamma = 0;
                    results_.vega  = 0;
                    results_.rho   = 0;
                    return;
                }
                break;
            }

            AnalyticDoubleBarrierBinaryEngineHelper helper = new AnalyticDoubleBarrierBinaryEngineHelper(process_,
                                                                                                         payoff, arguments_);

            switch (barrierType)
            {
            case DoubleBarrier.Type.KnockOut:
            case DoubleBarrier.Type.KnockIn:
                results_.value = helper.payoffAtExpiry(spot, variance, barrierType);
                break;

            case DoubleBarrier.Type.KIKO:
            case DoubleBarrier.Type.KOKI:
                results_.value = helper.payoffKIKO(spot, variance, barrierType);
                break;

            default:
                results_.value = null;
                break;
            }
        }
Ejemplo n.º 6
0
        public void testAnalyticContinuousGeometricAveragePrice()
        {
            //("Testing analytic continuous geometric average-price Asians...");
            // data from "Option Pricing Formulas", Haug, pag.96-97

            DayCounter dc = new Actual360();
            Date today = Date.Today;

            SimpleQuote spot = new SimpleQuote(80.0);
            SimpleQuote qRate = new SimpleQuote(-0.03);
            YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc);
            SimpleQuote rRate = new SimpleQuote(0.05);
            YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);
            SimpleQuote vol = new SimpleQuote(0.20);
            BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc);

            BlackScholesMertonProcess stochProcess = new
                BlackScholesMertonProcess(new Handle<Quote>(spot),
                                          new Handle<YieldTermStructure>(qTS),
                                          new Handle<YieldTermStructure>(rTS),
                                          new Handle<BlackVolTermStructure>(volTS));

            IPricingEngine engine = new
                AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess);

            Average.Type averageType = Average.Type.Geometric;
            Option.Type type = Option.Type.Put;
            double strike = 85.0;
            Date exerciseDate = today + 90;

            int pastFixings = 0; //Null<int>();
            double runningAccumulator = 0.0; //Null<Real>();

            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);

            Exercise exercise = new EuropeanExercise(exerciseDate);

            ContinuousAveragingAsianOption option =
                new ContinuousAveragingAsianOption(averageType, payoff, exercise);
            option.setPricingEngine(engine);

            double calculated = option.NPV();
            double expected = 4.6922;
            double tolerance = 1.0e-4;
            if (Math.Abs(calculated - expected) > tolerance)
            {
                REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings,
                               new List<Date>(), payoff, exercise, spot.value(),
                               qRate.value(), rRate.value(), today,
                               vol.value(), expected, calculated, tolerance);
            }

            // trying to approximate the continuous version with the discrete version
            runningAccumulator = 1.0;
            pastFixings = 0;
            List<Date> fixingDates = new InitializedList<Date>(exerciseDate - today + 1);
            for (int i = 0; i < fixingDates.Count; i++)
            {
                fixingDates[i] = today + i;
            }
            IPricingEngine engine2 = new
                AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess);

            DiscreteAveragingAsianOption option2 =
                new DiscreteAveragingAsianOption(averageType,
                                                 runningAccumulator, pastFixings,
                                                 fixingDates,
                                                 payoff,
                                                 exercise);
            option2.setPricingEngine(engine2);

            calculated = option2.NPV();
            tolerance = 3.0e-3;
            /*if (Math.Abs(calculated - expected) > tolerance)
            {
                REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings,
                               fixingDates, payoff, exercise, spot.value(),
                               qRate.value(), rRate.value(), today,
                               vol.value(), expected, calculated, tolerance);
            }*/
        }
        //public override void calculate(Excel_instrumentViewModel excel_inst)
        //{
        //    //#region Setting
		 
        //    //Excel_compositeOptionViewModel compOptionVM = excel_interface as Excel_compositeOptionViewModel;

        //    //if (compOptionVM == null)
        //    //{
        //    //    //error
        //    //}

        //    //Calendar calendar = new TARGET();

        //    //Date todaysDate = todaysDate = ProgramVariable.ReferenceDate_;

        //    //Date settlementDate = todaysDate;
            
        //    //Settings.setEvaluationDate(todaysDate);

        //    //DayCounter dayCounter = new Actual365Fixed();

        //    //if (this.Excel_underlyingCalcInfo_paraViewModel_.Excel_underlyingInfo_paraViewModel_.Count == 0)
        //    //{ 
        //    //    //error
        //    //}

        //    //Excel_geometricBMViewModel gbm = this.Excel_underlyingCalcInfo_paraViewModel_.Excel_underlyingInfo_paraViewModel_[0].Excel_underlyingModel_paraViewModel_ as Excel_geometricBMViewModel;

        //    //double currentValue = Convert.ToDouble(gbm.CurrentValue_);

        //    //SimpleQuote quote = new SimpleQuote(currentValue);
        //    //Handle<Quote> underlyingH = new Handle<Quote>(quote);

        //    //double drift = Convert.ToDouble(gbm.Drift_);
        //    //double dividendYield = Convert.ToDouble(gbm.Dividend_);

        //    //double volatility = Convert.ToDouble(gbm.Volatility_);

        //    //SimpleQuote volQuote = new SimpleQuote(volatility);
        //    //Handle<Quote> volH = new Handle<Quote>(volQuote);

        //    //var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, drift, dayCounter));
        //    //var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
        //    //Handle<BlackVolTermStructure> flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volH, dayCounter));

        //    //BlackScholesMertonProcess bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

        //    //double value = 0.0;

        //    //DateTime exDate = compOptionVM.ExerciseDate_;

        //    //List<QLNet.OneAssetOption> optionList = new List<QLNet.OneAssetOption>();

        //    //foreach (Excel_compositeOption_subtypeViewModel item in compOptionVM.Excel_compositeOption_subtypeViewModelList_)
        //    //{
        //    //    optionList.Add(this.option(item, bsmProcess, exDate));
        //    //}
            
        //    ////------------------------------------------------

        //    //foreach (var item in optionList)
        //    //{
        //    //    value = value + item.NPV();
        //    //}

        //    //if (this.Separable_)
        //    //{
        //    //    double matrutiryPayAmt = 0.0;

        //    //    Excel_yieldCurveViewModel e_ycvm
        //    //        = this.Excel_discountCurve_paraViewModel_.discountYieldCurve("KRW");

        //    //    QLNet.YieldTermStructure yts = e_ycvm.yieldCurve();

        //    //    value += matrutiryPayAmt;
        //    //}
            
        //    //#endregion
            
        //    //#region Calculation

        //    //quote.setValue(currentValue*1.01);
        //    //double sup = optionList[0].NPV();

        //    //quote.setValue(currentValue * 0.99);
        //    //double sdown = optionList[0].NPV();

        //    //double delta = (sup - sdown) / (currentValue * 0.02);

        //    //double gamma = (sup * sup - 2 * value + sdown * sdown) / (currentValue * 0.01 * currentValue * 0.01);

        //    //quote.setValue(currentValue);

        //    //volQuote.setValue(volatility - 0.01);
        //    //double voldown = optionList[0].NPV();

        //    //volQuote.setValue(volatility + 0.01);
        //    //double volup = optionList[0].NPV();

        //    //double vega = (volup - voldown) / 2;

        //    //#endregion

        //    //#region Result

        //    //this.Excel_resultViewModel_.Price_ = value.ToString();

        //    //double baseUnderlyingValue = Convert.ToDouble(
        //    //    excel_interface.Excel_underlyingCalcInfoViewModel_.Excel_underlyingInfoViewModel_[0].BasePrice_);

        //    //this.Excel_resultViewModel_.PercentPrice_ = (100 * value / baseUnderlyingValue).ToString();

        //    //double notional = Convert.ToDouble(excel_interface.Excel_issueInfoViewModel_.Notional_);

        //    //this.Excel_resultViewModel_.EvalAmount_ = ( notional * ( value / baseUnderlyingValue) ).ToString();

        //    //#endregion

        //    //double gamma = optionList[0].gamma();
        //    //double vega = optionList[0].vega();
            
        //}

        private QLNet.OneAssetOption option(Excel_compositeOption_subtypeViewModel compositeOptionVM, 
                                        BlackScholesMertonProcess bsmProcess, 
                                        DateTime exDate)
        {

            Date exerciseDate = new Date(exDate);

            if (compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_VANILLACALLPUT")
            {
                Excel_vanillaCallPutViewModel e_vcpvm = compositeOptionVM as Excel_vanillaCallPutViewModel;

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, e_vcpvm.StrikeValue_);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.VanillaOption vanillaOption = new VanillaOption(payoff, ex);
                
                return vanillaOption;

            }
            else if (compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_UPINOUTCALL" ||
                     compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_DOWNINOUTCALL" )
            {
                Excel_upInOutCallViewModel e_uiocvm = compositeOptionVM as Excel_upInOutCallViewModel;

                Barrier.Type type = Barrier.Type.UpOut;

                if (e_uiocvm.InOut_.ToString() == "IN")
                {
                    type = Barrier.Type.UpIn;
                }

                double strikeValue = e_uiocvm.StrikeValue_;
                double barrierValue = e_uiocvm.BarrierValue_;
                double partiRate = Convert.ToDouble(e_uiocvm.PartiRate_)/100.0;
                double rebateValue = Convert.ToDouble(e_uiocvm.RebateCouponValue_);

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, strikeValue);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.BarrierOption barrierOption = new QLNet.BarrierOption(type, barrierValue, partiRate, rebateValue, payoff, ex);

                QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);

                barrierOption.setPricingEngine(engine);

                return barrierOption;
            }
            else if (compositeOptionVM.Excel_Type_.ToUpper() == "")
            {
                Barrier.Type type = Barrier.Type.DownOut;

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 261.4);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.BarrierOption barrierOption = new QLNet.BarrierOption(type, 313.68, 0.32, 0.0, payoff, ex);

                QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);

                barrierOption.setPricingEngine(engine);

                return barrierOption;
            }
            else
            {
                throw new Exception("unknown compositeOptionType");
            }
            

        }
Ejemplo n.º 8
0
        protected override void performCalculations()
        {
            Calendar calendar   = index_.fixingCalendar();
            int      fixingDays = index_.fixingDays();

            Date exerciseDate = exerciseDate_;

            if (exerciseDate == null)
            {
                exerciseDate = calendar.advance(termStructure_.link.referenceDate(),
                                                maturity_,
                                                index_.businessDayConvention());
            }

            Date startDate = calendar.advance(exerciseDate,
                                              fixingDays, TimeUnit.Days,
                                              index_.businessDayConvention());

            Date endDate = endDate_;

            if (endDate == null)
            {
                endDate = calendar.advance(startDate, length_,
                                           index_.businessDayConvention());
            }

            Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar,
                                                  index_.businessDayConvention(),
                                                  index_.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar,
                                                  index_.businessDayConvention(),
                                                  index_.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);

            IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false);

            VanillaSwap.Type type = VanillaSwap.Type.Receiver;

            VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_,
                                               fixedSchedule, 0.0, fixedLegDayCounter_,
                                               floatSchedule, index_, 0.0, floatingLegDayCounter_);

            temp.setPricingEngine(swapEngine);
            double forward = temp.fairRate();

            if (!strike_.HasValue)
            {
                exerciseRate_ = forward;
            }
            else
            {
                exerciseRate_ = strike_.Value;
                type          = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer;
                // ensure that calibration instrument is out of the money
            }
            swap_ = new VanillaSwap(type, nominal_,
                                    fixedSchedule, exerciseRate_, fixedLegDayCounter_,
                                    floatSchedule, index_, 0.0, floatingLegDayCounter_);
            swap_.setPricingEngine(swapEngine);

            Exercise exercise = new EuropeanExercise(exerciseDate);

            swaption_ = new Swaption(swap_, exercise);

            base.performCalculations();
        }
Ejemplo n.º 9
0
        public void testSwaptionPricing()
        {
            //"Testing forward swap and swaption pricing...");

            //SavedSettings backup;

            const int size  = 10;
            const int steps = 8*size;
            #if QL_USE_INDEXED_COUPON
            const double tolerance = 1e-6;
            #else
            const double tolerance = 1e-12;
            #endif

            List<Date> dates = new List<Date>();
            List<double> rates = new List<double>();
            dates.Add(new Date(4,9,2005));
            dates.Add(new Date(4,9,2011));
            rates.Add(0.04);
            rates.Add(0.08);

            IborIndex index = makeIndex(dates, rates);

            LiborForwardModelProcess process = new LiborForwardModelProcess(size, index);

            LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.5);

            LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(process.fixingTimes(),
                                                                                0.291, 1.483, 0.116, 0.00001);

               // set-up pricing engine
            process.setCovarParam((LfmCovarianceParameterization)
                                       new LfmCovarianceProxy(volaModel, corrModel));

            // set-up a small Monte-Carlo simulation to price swations
            List<double> tmp = process.fixingTimes();

            TimeGrid grid=new TimeGrid(tmp ,steps);

            List<int> location=new List<int>();
            for (int i=0; i < tmp.Count; ++i) {
                location.Add(grid.index(tmp[i])) ;
            }

            ulong seed=42;
            const int nrTrails = 5000;
            LowDiscrepancy.icInstance = new InverseCumulativeNormal();

            IRNG rsg = (InverseCumulativeRsg<RandomSequenceGenerator<MersenneTwisterUniformRng>
                                                                    ,InverseCumulativeNormal>)
            new PseudoRandom().make_sequence_generator(process.factors()*(grid.size()-1),seed);

            MultiPathGenerator<IRNG> generator=new MultiPathGenerator<IRNG>(process,
                                                                            grid,
                                                                            rsg, false);

            LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel);

            Calendar calendar = index.fixingCalendar();
            DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter();
            BusinessDayConvention convention = index.businessDayConvention();

            Date settlement = index.forwardingTermStructure().link.referenceDate();

            SwaptionVolatilityMatrix m = liborModel.getSwaptionVolatilityMatrix();

            for (int i=1; i < size; ++i) {
                for (int j=1; j <= size-i; ++j) {
                    Date fwdStart    = settlement + new Period(6*i, TimeUnit.Months);
                    Date fwdMaturity = fwdStart + new Period(6*j, TimeUnit.Months);

                    Schedule schedule =new Schedule(fwdStart, fwdMaturity, index.tenor(), calendar,
                                       convention, convention, DateGeneration.Rule.Forward, false);

                    double swapRate  = 0.0404;
                    VanillaSwap forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                                                schedule, swapRate, dayCounter,
                                                                schedule, index, 0.0, index.dayCounter());
                    forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure()));

                    // check forward pricing first
                    double expected = forwardSwap.fairRate();
                    double calculated = liborModel.S_0(i-1,i+j-1);

                    if (Math.Abs(expected - calculated) > tolerance)
                        Assert.Fail("Failed to reproduce fair forward swap rate"
                                    + "\n    calculated: " + calculated
                                    + "\n    expected:   " + expected);

                    swapRate = forwardSwap.fairRate();
                    forwardSwap =
                        new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                        schedule, swapRate, dayCounter,
                                        schedule, index, 0.0, index.dayCounter());
                    forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure()));

                    if (i == j && i<=size/2) {
                        IPricingEngine engine =
                            new LfmSwaptionEngine(liborModel, index.forwardingTermStructure());
                        Exercise exercise =
                            new EuropeanExercise(process.fixingDates()[i]);

                        Swaption swaption =
                            new Swaption(forwardSwap, exercise);
                        swaption.setPricingEngine(engine);

                        GeneralStatistics stat = new GeneralStatistics();

                        for (int n=0; n<nrTrails; ++n) {
                            Sample<MultiPath> path = (n%2!=0) ? generator.antithetic()
                                                     : generator.next();

                            //Sample<MultiPath> path = generator.next();
                            List<double> rates_ = new InitializedList<double>(size);
                            for (int k=0; k<process.size(); ++k) {
                                rates_[k] = path.value[k][location[i]];
                            }
                            List<double> dis = process.discountBond(rates_);

                            double npv=0.0;
                            for (int k=i; k < i+j; ++k) {
                                npv += (swapRate - rates_[k])
                                       * (  process.accrualEndTimes()[k]
                                          - process.accrualStartTimes()[k])*dis[k];
                            }
                            stat.add(Math.Max(npv, 0.0));
                        }

                        if (Math.Abs(swaption.NPV() - stat.mean())
                            > stat.errorEstimate()*2.35)
                            Assert.Fail("Failed to reproduce swaption npv"
                                        + "\n    calculated: " + stat.mean()
                                        + "\n    expected:   " + swaption.NPV());
                    }
                }
            }
        }
Ejemplo n.º 10
0
        public override void calculate()
        {
            AmericanExercise ex = arguments_.exercise as AmericanExercise;

            Utils.QL_REQUIRE(ex != null, () => "non-American exercise given");
            Utils.QL_REQUIRE(ex.payoffAtExpiry(), () => "payoff must be at expiry");
            Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(), () =>
                             "American option with window exercise not handled yet");

            StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given");

            double spot = process_.stateVariable().link.value();

            Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given");

            double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike());
            double?barrier  = arguments_.barrier;

            Utils.QL_REQUIRE(barrier > 0.0, () => "positive barrier value required");
            Barrier.Type barrierType = arguments_.barrierType;

            // KO degenerate cases
            if ((barrierType == Barrier.Type.DownOut && spot <= barrier) ||
                (barrierType == Barrier.Type.UpOut && spot >= barrier))
            {
                // knocked out, no value
                results_.value       = 0;
                results_.delta       = 0;
                results_.gamma       = 0;
                results_.vega        = 0;
                results_.theta       = 0;
                results_.rho         = 0;
                results_.dividendRho = 0;
                return;
            }

            // KI degenerate cases
            if ((barrierType == Barrier.Type.DownIn && spot <= barrier) ||
                (barrierType == Barrier.Type.UpIn && spot >= barrier))
            {
                // knocked in - is a digital european
                Exercise exercise = new EuropeanExercise(arguments_.exercise.lastDate());

                IPricingEngine engine = new AnalyticEuropeanEngine(process_);

                VanillaOption opt = new VanillaOption(payoff, exercise);
                opt.setPricingEngine(engine);
                results_.value       = opt.NPV();
                results_.delta       = opt.delta();
                results_.gamma       = opt.gamma();
                results_.vega        = opt.vega();
                results_.theta       = opt.theta();
                results_.rho         = opt.rho();
                results_.dividendRho = opt.dividendRho();
                return;
            }

            double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate());

            AnalyticBinaryBarrierEngine_helper helper = new AnalyticBinaryBarrierEngine_helper(
                process_, payoff, ex, arguments_);

            results_.value = helper.payoffAtExpiry(spot, variance, riskFreeDiscount);
        }
Ejemplo n.º 11
0
        public void testAnalyticDiscreteGeometricAveragePriceGreeks()
        {
            //BOOST_MESSAGE("Testing discrete-averaging geometric Asian greeks...");

             //SavedSettings backup;

             Dictionary<string,double> calculated, expected, tolerance;
             calculated = new Dictionary<string, double>(6);
             expected = new Dictionary<string, double>(6);
             tolerance = new Dictionary<string, double>(6);
             tolerance["delta"]  = 1.0e-5;
             tolerance["gamma"]  = 1.0e-5;
             tolerance["theta"]  = 1.0e-5;
             tolerance["rho"]    = 1.0e-5;
             tolerance["divRho"] = 1.0e-5;
             tolerance["vega"]   = 1.0e-5;

             Option.Type[] types = { Option.Type.Call, Option.Type.Put };
             double[] underlyings = { 100.0 };
             double[] strikes = { 90.0, 100.0, 110.0 };
             double[] qRates = { 0.04, 0.05, 0.06 };
             double[] rRates = { 0.01, 0.05, 0.15 };
             int[] lengths = { 1, 2 };
             double[] vols = { 0.11, 0.50, 1.20 };

             DayCounter dc = new Actual360();
             Date today = Date.Today;
             Settings.setEvaluationDate(today);

             SimpleQuote spot = new SimpleQuote(0.0);
             SimpleQuote qRate = new SimpleQuote(0.0);
             Handle<YieldTermStructure> qTS = new Handle<YieldTermStructure>
                                                    (Utilities.flatRate(qRate, dc));
             SimpleQuote rRate = new SimpleQuote(0.0);
             Handle<YieldTermStructure> rTS = new Handle<YieldTermStructure>
                                                    (Utilities.flatRate(rRate, dc));
             SimpleQuote vol = new SimpleQuote(0.0);
             Handle<BlackVolTermStructure> volTS = new Handle<BlackVolTermStructure>
                                                    (Utilities.flatVol(vol, dc));

             BlackScholesMertonProcess process =
                  new BlackScholesMertonProcess(new Handle<Quote>(spot), qTS, rTS, volTS);

             for (int i=0; i<types.Length ; i++) {
               for (int j=0; j<strikes.Length ; j++) {
                 for (int k=0; k<lengths.Length ; k++) {

                     EuropeanExercise maturity =
                                       new EuropeanExercise(
                                           today + new Period(lengths[k],TimeUnit.Years));

                     PlainVanillaPayoff payoff =
                                         new PlainVanillaPayoff(types[i], strikes[j]);

                     double runningAverage = 120;
                     int pastFixings = 1;

                     List<Date> fixingDates = new List<Date>();
                     for (Date d = today + new Period(3, TimeUnit.Months);
                               d <= maturity.lastDate();
                               d += new Period(3, TimeUnit.Months))
                         fixingDates.Add(d);

                     IPricingEngine engine =
                        new AnalyticDiscreteGeometricAveragePriceAsianEngine(process);

                     DiscreteAveragingAsianOption option =
                         new DiscreteAveragingAsianOption(Average.Type.Geometric,
                                                         runningAverage, pastFixings,
                                                         fixingDates, payoff, maturity);
                     option.setPricingEngine(engine);

                     for (int l=0; l<underlyings.Length ; l++) {
                       for (int m=0; m<qRates.Length ; m++) {
                         for (int n=0; n<rRates.Length ; n++) {
                           for (int p=0; p<vols.Length ; p++) {

                               double u = underlyings[l];
                               double q = qRates[m],
                                    r = rRates[n];
                               double v = vols[p];
                               spot.setValue(u);
                               qRate.setValue(q);
                               rRate.setValue(r);
                               vol.setValue(v);

                               double value = option.NPV();
                               calculated["delta"]  = option.delta();
                               calculated["gamma"]  = option.gamma();
                               calculated["theta"]  = option.theta();
                               calculated["rho"]    = option.rho();
                               calculated["divRho"] = option.dividendRho();
                               calculated["vega"]   = option.vega();

                               if (value > spot.value()*1.0e-5) {
                                   // perturb spot and get delta and gamma
                                   double du = u*1.0e-4;
                                   spot.setValue(u+du);
                                   double value_p = option.NPV(),
                                        delta_p = option.delta();
                                   spot.setValue(u-du);
                                   double value_m = option.NPV(),
                                        delta_m = option.delta();
                                   spot.setValue(u);
                                   expected["delta"] = (value_p - value_m)/(2*du);
                                   expected["gamma"] = (delta_p - delta_m)/(2*du);

                                   // perturb rates and get rho and dividend rho
                                   double dr = r*1.0e-4;
                                   rRate.setValue(r+dr);
                                   value_p = option.NPV();
                                   rRate.setValue(r-dr);
                                   value_m = option.NPV();
                                   rRate.setValue(r);
                                   expected["rho"] = (value_p - value_m)/(2*dr);

                                   double dq = q*1.0e-4;
                                   qRate.setValue(q+dq);
                                   value_p = option.NPV();
                                   qRate.setValue(q-dq);
                                   value_m = option.NPV();
                                   qRate.setValue(q);
                                   expected["divRho"] = (value_p - value_m)/(2*dq);

                                   // perturb volatility and get vega
                                   double dv = v*1.0e-4;
                                   vol.setValue(v+dv);
                                   value_p = option.NPV();
                                   vol.setValue(v-dv);
                                   value_m = option.NPV();
                                   vol.setValue(v);
                                   expected["vega"] = (value_p - value_m)/(2*dv);

                                   // perturb date and get theta
                                   double dT = dc.yearFraction(today-1, today+1);
                                   Settings.setEvaluationDate(today-1);
                                   value_m = option.NPV();
                                   Settings.setEvaluationDate(today+1);
                                   value_p = option.NPV();
                                   Settings.setEvaluationDate(today);
                                   expected["theta"] = (value_p - value_m)/dT;

                                   // compare
                                   foreach (KeyValuePair<string, double> kvp in calculated){
                                       string greek = kvp.Key;
                                       double expct = expected[greek],
                                            calcl = calculated[greek],
                                            tol   = tolerance [greek];
                                       double error =Utilities.relativeError(expct,calcl,u);
                                       if (error>tol) {
                                           REPORT_FAILURE(greek, Average.Type.Geometric,
                                                          runningAverage, pastFixings,
                                                          new List<Date>(),
                                                          payoff, maturity,
                                                          u, q, r, today, v,
                                                          expct, calcl, tol);
                                       }
                                   }
                               }
                           }
                         }
                       }
                     }
                 }
               }
             }
        }
Ejemplo n.º 12
0
        public override void calculate(DateTime calcDate, FP_Parameter fp_parameter)
        {
            // master data load

            this.indexOptionDAO_.SelectOwn();

            // market data load
            
            // index data
            clsHDAT_MARKETDATA_TB clstb = new clsHDAT_MARKETDATA_TB();

            string calcDateStr = calcDate.ToString("yyyyMMdd");
            QLNet.Settings.setEvaluationDate(calcDate);

            clstb.REF_DT = calcDateStr;
            clstb.INDEX_CD = this.indexOptionDAO_.UNDERLYING_INDEX_CD;

            int checkNum = clstb.SelectOwn();

            if (checkNum == 0) { throw new Exception("market data does not exist : " + calcDateStr + " " + clstb.INDEX_CD); }

            double indexData = clstb.LAST;

            // curveData --------------------------------------------------

            string curve_cd = "IRSKRW";
            
            YieldCurve curveManager = new YieldCurve();

            curveManager.loadCurveData(calcDate,curve_cd,clsHDAT_CURVEDATA_TB.RATE_TYP_Type.YTM);
            QLNet.YieldTermStructure yield_ts = curveManager.yieldCurve();

            // calculate

            string maturityDateStr = this.indexOptionDAO_.MATURITY_DT;

            System.Globalization.CultureInfo us
                = new System.Globalization.CultureInfo("en-US");

            DateTime maturityDate = DateTime.ParseExact(maturityDateStr, "yyyyMMdd", us);

            DayCounter dc = new Actual365Fixed();
            Calendar cal = new NullCalendar();

            double vol = 0.3;

            double strike = this.indexOptionDAO_.STRIKE;
            PlainVanillaPayoff strikePayoff = new PlainVanillaPayoff(Option.Type.
                Call, strike);

            Exercise exercise = new EuropeanExercise(maturityDate);

            VanillaOption q_option = new VanillaOption(strikePayoff,exercise);

            Handle<Quote> x0 = new Handle<Quote>(new SimpleQuote(indexData));
            FlatForward flatForward = new FlatForward(calcDate,0.01,dc);
            Handle<YieldTermStructure> dividendTS = new Handle<YieldTermStructure>(flatForward);
            Handle<YieldTermStructure> riskFreeTS = new Handle<YieldTermStructure>(yield_ts);
            BlackConstantVol blackConstVol = new BlackConstantVol(calcDate,cal,vol,dc);
            Handle<BlackVolTermStructure> blackVolTS = new Handle<BlackVolTermStructure>(blackConstVol);

            GeneralizedBlackScholesProcess process =new GeneralizedBlackScholesProcess(x0 ,dividendTS,riskFreeTS,blackVolTS);
            
            AnalyticEuropeanEngine europeanEngine = new AnalyticEuropeanEngine(process);

            q_option.setPricingEngine(europeanEngine);

            double value = q_option.NPV(); 
            double indexMultiplier = this.indexOptionDAO_.INDEX_MULTIPLIER;
            int quantity = this.indexOptionDAO_.QUANTITY;

            clsHITM_FP_GREEKRESULT_TB result_tb = new clsHITM_FP_GREEKRESULT_TB();

            result_tb.FP_GREEKRESULT_ID = IDGenerator.getNewGreekResultID(this.indexOptionDAO_.INSTRUMENT_ID,calcDateStr);
            result_tb.CALC_DT = calcDateStr;
            result_tb.INSTRUMENT_ID = this.indexOptionDAO_.INSTRUMENT_ID;
            result_tb.INSTRUMENT_TYP = this.indexOptionDAO_.INSTRUMENT_TYP;
            result_tb.UNDERLYING_ID = "KOSPI200";
            result_tb.UNDERLYING_VALUE = indexData;
            //result_tb.SEQ = 1;
            result_tb.DELTA = (q_option.delta() * indexData / 100) * indexMultiplier * quantity; // 1% Delta
            result_tb.GAMMA = 0.5 * (q_option.gamma() * indexData / 100) * indexMultiplier * quantity; // 1% Gamma
            result_tb.VEGA = q_option.vega() / 100 * indexMultiplier * quantity; // 1% point Vega
            result_tb.CALC_PRICE = value * indexMultiplier * quantity;
            result_tb.CALCULATED_FLAG = (int)clsHITM_FP_GREEKRESULT_TB.CALCULATED_FLAG_Type.CALCULATED;
            result_tb.CALCULATED_TIME = DateTime.Now.ToString("HHmmss"); ;
            result_tb.CALCULATE_TYP = (int)clsHITM_FP_GREEKRESULT_TB.CALCULATE_TYP_Type.ANALYTICS;

            // price

            if (result_tb.UpdateDateResult() == 0)
            { throw new Exception("update result fail. no exist , calcDate : " + calcDate.ToString("yyyyMMdd") + " , inst_id : " + result_tb.INSTRUMENT_ID); }

            // delta

            // gamma and others : no exist ?


        }
        //static void Main(string[] args) 
        //{
        //    List<double> xGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList();
        //    List<double> yGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList();

        //    //List<double> xGrid = Enumerable.Range(0, 100);
        //    CubicInterpolation cubic = new CubicInterpolation(xGrid, xGrid.Count, yGrid, 
        //                                                      CubicInterpolation.DerivativeApprox.Kruger, true,
        //                                                      CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0,
        //                                                      CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0);

            
        //}

        static void Main(string[] args)
        {

            DateTime timer = DateTime.Now;

            // set up dates
            Calendar calendar = new TARGET();
            Date todaysDate = new Date(15, Month.May, 1998);
            Date settlementDate = new Date(17, Month.May, 1998);
            Settings.setEvaluationDate(todaysDate);

            // our options
            Option.Type type = Option.Type.Put;
            double underlying = 36;
            double strike = 40;
            double dividendYield = 0.00;
            double riskFreeRate = 0.06;
            double volatility = 0.20;
            Date maturity = new Date(17, Month.May, 1999);
            DayCounter dayCounter = new Actual365Fixed();

            Console.WriteLine("Option type = " + type);
            Console.WriteLine("Maturity = " + maturity);
            Console.WriteLine("Underlying price = " + underlying);
            Console.WriteLine("Strike = " + strike);
            Console.WriteLine("Risk-free interest rate = {0:0.000000%}", riskFreeRate);
            Console.WriteLine("Dividend yield = {0:0.000000%}", dividendYield);
            Console.WriteLine("Volatility = {0:0.000000%}", volatility);
            Console.Write("\n");

            string method;

            Console.Write("\n");

            // write column headings
            int[] widths = new int[] { 35, 14, 14, 14 };
            Console.Write("{0,-" + widths[0] + "}", "Method");
            Console.Write("{0,-" + widths[1] + "}", "European");
            Console.Write("{0,-" + widths[2] + "}", "Bermudan");
            Console.WriteLine("{0,-" + widths[3] + "}", "American");

            List<Date> exerciseDates = new List<Date>(); ;
            for (int i = 1; i <= 4; i++)
                exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months));

            Exercise europeanExercise = new EuropeanExercise(maturity);
            Exercise bermudanExercise = new BermudanExercise(exerciseDates);
            Exercise americanExercise = new AmericanExercise(settlementDate, maturity);

            Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying));

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);
            var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            // options
            VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise);
            VanillaOption bermudanOption = new VanillaOption(payoff, bermudanExercise);
            VanillaOption americanOption = new VanillaOption(payoff, americanExercise);


            // Analytic formulas:

            // Black-Scholes for European
            method = "Black-Scholes";
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + "}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + "}", "N/A");

            europeanOption.theta();

            // Barone-Adesi and Whaley approximation for American
            method = "Barone-Adesi/Whaley";
            americanOption.setPricingEngine(new BaroneAdesiWhaleyApproximationEngine(bsmProcess));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + "}", "N/A");
            Console.Write("{0,-" + widths[2] + "}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());


            // Bjerksund and Stensland approximation for American
            method = "Bjerksund/Stensland";
            americanOption.setPricingEngine(new BjerksundStenslandApproximationEngine(bsmProcess));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + "}", "N/A");
            Console.Write("{0,-" + widths[2] + "}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Integral
            method = "Integral";
            europeanOption.setPricingEngine(new IntegralEngine(bsmProcess));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + "}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + "}", "N/A");


            // Finite differences
            int timeSteps = 801;
            method = "Finite differences";
            europeanOption.setPricingEngine(new FDEuropeanEngine(bsmProcess, timeSteps, timeSteps - 1));
            bermudanOption.setPricingEngine(new FDBermudanEngine(bsmProcess, timeSteps, timeSteps - 1));
            americanOption.setPricingEngine(new FDAmericanEngine(bsmProcess, timeSteps, timeSteps - 1));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Jarrow-Rudd
            method = "Binomial Jarrow-Rudd";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());


            method = "Binomial Cox-Ross-Rubinstein";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Additive equiprobabilities
            method = "Additive equiprobabilities";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Binomial Trigeorgis
            method = "Binomial Trigeorgis";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Binomial Tian
            method = "Binomial Tian";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Binomial Leisen-Reimer
            method = "Binomial Leisen-Reimer";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // Binomial method: Binomial Joshi
            method = "Binomial Joshi";
            europeanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps));
            bermudanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps));
            americanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps));

            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV());
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());


            // Monte Carlo Method: MC (crude)
            timeSteps = 1;
            method = "MC (crude)";
            ulong mcSeed = 42;
            IPricingEngine mcengine1 = new MakeMCEuropeanEngine<PseudoRandom>(bsmProcess)
                                            .withSteps(timeSteps)
                                            .withAbsoluteTolerance(0.02)
                                            .withSeed(mcSeed)
                                            .value();
            europeanOption.setPricingEngine(mcengine1);
            // Real errorEstimate = europeanOption.errorEstimate();
            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A");


            // Monte Carlo Method: QMC (Sobol)
            method = "QMC (Sobol)";
            int nSamples = 32768;  // 2^15

            IPricingEngine mcengine2 = new MakeMCEuropeanEngine<LowDiscrepancy>(bsmProcess)
                                            .withSteps(timeSteps)
                                            .withSamples(nSamples)
                                            .value();
            europeanOption.setPricingEngine(mcengine2);
            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV());
            Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A");

            // Monte Carlo Method: MC (Longstaff Schwartz)
            method = "MC (Longstaff Schwartz)";
            IPricingEngine mcengine3 = new MakeMCAmericanEngine<PseudoRandom>(bsmProcess)
                                        .withSteps(100)
                                        .withAntitheticVariate()
                                        .withCalibrationSamples(4096)
                                        .withAbsoluteTolerance(0.02)
                                        .withSeed(mcSeed)
                                        .value();
            americanOption.setPricingEngine(mcengine3);
            Console.Write("{0,-" + widths[0] + "}", method);
            Console.Write("{0,-" + widths[1] + ":0.000000}", "N/A");
            Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A");
            Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV());

            // End test
            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
        public void calculate(GBMParaViewModel para)
        {
            // set up dates
            Calendar calendar = new TARGET();
            //Date todaysDate = new Date(DateTime.Now);
            Date settlementDate = new Date(para.ReferenceDate_);
            Settings.setEvaluationDate(settlementDate);

            // our options
            Option.Type type = this.callPutEnum_;

            double underlying = para.CurrentPrice_;
            double strike = this.strike_;
            double dividendYield = para.Dividend_ / 100;
            double riskFreeRate = para.Drift_ / 100;
            double volatility = 0.0;

            if (this.callPutEnum_ == Option.Type.Call)
            {
                try
                {
                    volatility = para.Call_Interpolation_.value(this.strike_) / 100;
                    this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_), 1);
                }
                catch (Exception)
                {
                    volatility = para.Call_Interpolation_.value(this.strike_, true) / 100;
                    this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_,true), 1);
                }
                
            }
            else if (this.callPutEnum_ == Option.Type.Put)
            {
                try
                {
                    volatility = para.Call_Interpolation_.value(this.strike_) / 100;
                    this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_), 1);
                }
                catch (Exception)
                {
                    volatility = para.Call_Interpolation_.value(this.strike_, true) / 100;
                    this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_,true), 1);
                }
                
            }

            

            Date maturity = new Date(this.maturiry_);

            DayCounter dayCounter = new Actual365Fixed();

            //// write column headings
            //int[] widths = new int[] { 35, 14, 14, 14 };
            //Console.Write("{0,-" + widths[0] + "}", "Method");
            //Console.Write("{0,-" + widths[1] + "}", "European");
            //Console.Write("{0,-" + widths[2] + "}", "Bermudan");
            //Console.WriteLine("{0,-" + widths[3] + "}", "American");

            //List<Date> exerciseDates = new List<Date>(); ;
            //for (int i = 1; i <= 4; i++)
            //    exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months));

            Exercise europeanExercise = new EuropeanExercise(maturity);
            //Exercise bermudanExercise = new BermudanExercise(exerciseDates);
            //Exercise americanExercise = new AmericanExercise(settlementDate, maturity);

            Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying));

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);
            var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            // options
            VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise);

            // Analytic formulas:
            // Black-Scholes for European
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));
            
            this.npv_ = Math.Round(europeanOption.NPV(),6);
            this.deltaCal_ = Math.Round(europeanOption.delta(),6);
            this.gammaCal_= Math.Round(europeanOption.gamma(),6);
            this.vegaCal_ = Math.Round(europeanOption.vega()/ 100, 6);
            this.thetaCal_= Math.Round(europeanOption.theta()/ 365,6) ;
            this.rhoCal_ = Math.Round(europeanOption.rho() / 100, 6);

        }
Ejemplo n.º 15
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option");

            EuropeanExercise exercise = arguments_.exercise as EuropeanExercise;

            Utils.QL_REQUIRE(exercise != null, () => "not an European Option");

            BasketPayoff basket_payoff = arguments_.payoff as BasketPayoff;

            MinBasketPayoff min_basket = arguments_.payoff as MinBasketPayoff;

            MaxBasketPayoff max_basket = arguments_.payoff as MaxBasketPayoff;

            Utils.QL_REQUIRE(min_basket != null || max_basket != null, () => "unknown basket type");

            PlainVanillaPayoff payoff = basket_payoff.basePayoff() as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");

            double strike = payoff.strike();

            double variance1 = process1_.blackVolatility().link.blackVariance(exercise.lastDate(), strike);
            double variance2 = process2_.blackVolatility().link.blackVariance(exercise.lastDate(), strike);

            double riskFreeDiscount = process1_.riskFreeRate().link.discount(exercise.lastDate());

            // cannot handle non zero dividends, so don't believe this...
            double dividendDiscount1 = process1_.dividendYield().link.discount(exercise.lastDate());
            double dividendDiscount2 = process2_.dividendYield().link.discount(exercise.lastDate());

            double forward1 = process1_.stateVariable().link.value() * dividendDiscount1 / riskFreeDiscount;
            double forward2 = process2_.stateVariable().link.value() * dividendDiscount2 / riskFreeDiscount;

            if (max_basket != null)
            {
                switch (payoff.optionType())
                {
                // euro call on a two asset max basket
                case Option.Type.Call:
                    results_.value = euroTwoAssetMaxBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2,
                                                               rho_);

                    break;

                // euro put on a two asset max basket
                case Option.Type.Put:
                    results_.value = strike * riskFreeDiscount -
                                     euroTwoAssetMaxBasketCall(forward1, forward2, 0.0,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_) +
                                     euroTwoAssetMaxBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_);
                    break;

                default:
                    Utils.QL_FAIL("unknown option type");
                    break;
                }
            }
            else if (min_basket != null)
            {
                switch (payoff.optionType())
                {
                // euro call on a two asset min basket
                case Option.Type.Call:
                    results_.value = euroTwoAssetMinBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2,
                                                               rho_);
                    break;

                // euro put on a two asset min basket
                case Option.Type.Put:
                    results_.value = strike * riskFreeDiscount -
                                     euroTwoAssetMinBasketCall(forward1, forward2, 0.0,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_) +
                                     euroTwoAssetMinBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_);
                    break;

                default:
                    Utils.QL_FAIL("unknown option type");
                    break;
                }
            }
            else
            {
                Utils.QL_FAIL("unknown type");
            }
        }
        public static Greeks GetOptionOnFutureGreeks(double underlyingPrice,double strike,double riskFreeRate, 
            DateTime expirationDate, DateTime calculationDate, string optionType, string exerciseType,
            double optionPrice=double.NaN,double impliedVol=0.15,string engineName="baw")
        {
            QLNet.Date ExpirationDateObj = new QLNet.Date(expirationDate.Day, expirationDate.Month, expirationDate.Year);
            QLNet.Date CalculationDateObj = new QLNet.Date(calculationDate.Day, calculationDate.Month, calculationDate.Year);

            QLNet.DayCounter DayCountObj = new QLNet.Actual365Fixed();
            QLNet.Calendar CalendarObj = new QLNet.UnitedStates();

            Greeks GreeksOutput = new Greeks();
            QLNet.Option.Type OptionTypeObj;
            QLNet.Exercise ExerciseObj;
            double ImpliedVol;
            double OptionPrice;

            int CalDte = DayCountObj.dayCount(CalculationDateObj, ExpirationDateObj);
            GreeksOutput.CalDte = CalDte;

            if (!double.IsNaN(optionPrice))
            {
                if (optionType.ToUpper() == "C")
                {
                    if (optionPrice + strike - underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = 1;
                        return GreeksOutput;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (optionPrice - strike + underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = -1;
                        return GreeksOutput;
                    }
                }
            }

            if (CalDte == 0)
            {
                if (optionType.ToUpper() == "C")
                {
                    if (strike <= underlyingPrice)
                    {
                        GreeksOutput.Delta = 1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (strike >= underlyingPrice)
                    {
                        GreeksOutput.Delta = -1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                return GreeksOutput;
            }

            if (optionType.ToUpper() == "C")
            {
                OptionTypeObj = QLNet.Option.Type.Call;
            }
            else if (optionType.ToUpper() == "P")
            {
                OptionTypeObj = QLNet.Option.Type.Put;
            }
            else
            {
                return GreeksOutput;
            }

            if (exerciseType.ToUpper() == "E")
            {
                ExerciseObj = new QLNet.EuropeanExercise(ExpirationDateObj);
            }
            else if (exerciseType.ToUpper() == "A")
            {
                ExerciseObj = new QLNet.AmericanExercise(CalculationDateObj, ExpirationDateObj);
            }
            else
            {
                return GreeksOutput;
            }

            QLNet.Settings.setEvaluationDate(CalculationDateObj);

            QLNet.Handle<Quote> UnderlyingObj = new QLNet.Handle<Quote>(new QLNet.SimpleQuote(underlyingPrice));
            QLNet.Handle<YieldTermStructure> FlatRateObj = new QLNet.Handle<YieldTermStructure>(new QLNet.FlatForward(CalculationDateObj, riskFreeRate, DayCountObj));
            QLNet.Handle<BlackVolTermStructure> FlatVolTsObj = new QLNet.Handle<BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, impliedVol, DayCountObj));

            QLNet.BlackProcess BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);
            QLNet.PlainVanillaPayoff PayoffObj = new QLNet.PlainVanillaPayoff(OptionTypeObj, strike);

            QLNet.VanillaOption OptionObj = new QLNet.VanillaOption(PayoffObj, ExerciseObj);

            if (engineName == "baw")
            {
                OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
            }
            else if (engineName == "fda")
            {
                OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
            }
            else
            {
                return GreeksOutput;
            }


            if (!double.IsNaN(optionPrice))
            {
                try
                {

                    ImpliedVol = OptionObj.impliedVolatility(targetValue:optionPrice, process:BlackProc,accuracy:1e-5);
                }
                catch
                {
                    return GreeksOutput;
                }
                
                FlatVolTsObj = new QLNet.Handle<BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, ImpliedVol, DayCountObj));
                BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);

                if (engineName == "baw")
                {
                    OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
                }
                else if (engineName == "fda")
                {
                    OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
                }
                OptionPrice = optionPrice;
            }
            else
            {
                OptionPrice = OptionObj.NPV();
                ImpliedVol = impliedVol;
            }

            OptionObj = new QLNet.VanillaOption(PayoffObj, new QLNet.EuropeanExercise(ExpirationDateObj));
            OptionObj.setPricingEngine(new QLNet.AnalyticEuropeanEngine(BlackProc));

            GreeksOutput.Delta = OptionObj.delta();
            GreeksOutput.Vega = OptionObj.vega();
            GreeksOutput.Theta = OptionObj.thetaPerDay();
            GreeksOutput.Gamma = OptionObj.gamma();
            GreeksOutput.OptionPrice = OptionPrice;
            GreeksOutput.ImpliedVol = ImpliedVol;

            return GreeksOutput;

        }
Ejemplo n.º 17
0
        public void testMCDiscreteArithmeticAveragePrice()
        {
            //BOOST_MESSAGE("Testing Monte Carlo discrete arithmetic average-price Asians...");

            //QL_TEST_START_TIMING

            // data from "Asian Option", Levy, 1997
            // in "Exotic Options: The State of the Art",
            // edited by Clewlow, Strickland

            DiscreteAverageData[] cases4 = {
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 2,0.13, true, 1.3942835683),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 4,0.13, true, 1.5852442983),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 8,0.13, true, 1.66970673),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 12,0.13, true, 1.6980019214),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 26,0.13, true, 1.7255070456),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 52,0.13, true, 1.7401553533),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 100,0.13, true, 1.7478303712),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 250,0.13, true, 1.7490291943),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 500,0.13, true, 1.7515113291),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 0.0,11.0/12.0, 1000,0.13, true, 1.7537344885),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 2,0.13, true, 1.8496053697),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 4,0.13, true, 2.0111495205),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 8,0.13, true, 2.0852138818),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 12,0.13, true, 2.1105094397),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 26,0.13, true, 2.1346526695),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 52,0.13, true, 2.147489651),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 100,0.13, true, 2.154728109),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 250,0.13, true, 2.1564276565),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 500,0.13, true, 2.1594238588),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 1.0/12.0,11.0/12.0, 1000,0.13, true, 2.1595367326),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 2,0.13, true, 2.63315092584),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 4,0.13, true, 2.76723962361),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 8,0.13, true, 2.83124836881),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 12,0.13, true, 2.84290301412),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 26,0.13, true, 2.88179560417),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 52,0.13, true, 2.88447044543),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 100,0.13, true, 2.89985329603),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 250,0.13, true, 2.90047296063),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 500,0.13, true, 2.89813412160),
            new DiscreteAverageData(Option.Type.Put, 90.0, 87.0, 0.06, 0.025, 3.0/12.0,11.0/12.0, 1000,0.13, true, 2.89703362437)
            };

            DayCounter dc = new Actual360();
            Date today = Date.Today ;

            SimpleQuote spot = new SimpleQuote(100.0);
            SimpleQuote qRate = new SimpleQuote(0.03);
            YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc);
            SimpleQuote rRate = new SimpleQuote(0.06);
            YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);
            SimpleQuote vol = new SimpleQuote(0.20);
            BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc);

            Average.Type averageType = Average.Type.Arithmetic;
            double runningSum = 0.0;
            int pastFixings = 0;
            for (int l=0; l<cases4.Length ; l++) {

                StrikedTypePayoff payoff = new
                    PlainVanillaPayoff(cases4[l].type, cases4[l].strike);

                double dt = cases4[l].length/(cases4[l].fixings-1);
                List<double> timeIncrements = new QLNet.InitializedList<double>(cases4[l].fixings);
                List<Date> fixingDates = new QLNet.InitializedList<Date>(cases4[l].fixings);
                timeIncrements[0] = cases4[l].first;
                fixingDates[0] = today + (int)(timeIncrements[0]*360+0.5);
                for (int i=1; i<cases4[l].fixings; i++) {
                    timeIncrements[i] = i*dt + cases4[l].first;
                    fixingDates[i] = today + (int)(timeIncrements[i]*360+0.5);
                }
                Exercise exercise = new EuropeanExercise(fixingDates[cases4[l].fixings-1]);

                spot.setValue(cases4[l].underlying);
                qRate.setValue(cases4[l].dividendYield);
                rRate.setValue(cases4[l].riskFreeRate);
                vol.setValue(cases4[l].volatility);

                BlackScholesMertonProcess stochProcess =
                    new BlackScholesMertonProcess(new Handle<Quote>(spot),
                                                new Handle<YieldTermStructure>(qTS),
                                                new Handle<YieldTermStructure>(rTS),
                                                new Handle<BlackVolTermStructure>(volTS));

                ulong seed=42;
                const int nrTrails = 5000;
                LowDiscrepancy.icInstance = new InverseCumulativeNormal();
                IRNG rsg = (IRNG)new LowDiscrepancy().make_sequence_generator(nrTrails,seed);

                new PseudoRandom().make_sequence_generator(nrTrails,seed);

                IPricingEngine engine =
                    new MakeMCDiscreteArithmeticAPEngine<LowDiscrepancy, Statistics>(stochProcess)
                        .withStepsPerYear(1)
                        .withSamples(2047)
                        .withControlVariate()
                        .value();
                DiscreteAveragingAsianOption option=
                    new DiscreteAveragingAsianOption(averageType, runningSum,
                                                    pastFixings, fixingDates,
                                                    payoff, exercise);
                option.setPricingEngine(engine);

                double calculated = option.NPV();
                double expected = cases4[l].result;
                double tolerance = 2.0e-2;
                if (Math.Abs(calculated-expected) > tolerance) {
                    REPORT_FAILURE("value", averageType, runningSum, pastFixings,
                                fixingDates, payoff, exercise, spot.value(),
                                qRate.value(), rRate.value(), today,
                                vol.value(), expected, calculated, tolerance);
                }
            }
        }
Ejemplo n.º 18
0
        protected override void performCalculations()
        {
            Calendar calendar = index_.fixingCalendar();
            int fixingDays = index_.fixingDays();

            Date exerciseDate = exerciseDate_;
              if (exerciseDate == null)
                exerciseDate = calendar.advance(termStructure_.link.referenceDate(),
                                            maturity_,
                                            index_.businessDayConvention());

            Date startDate = calendar.advance(exerciseDate,
                                    fixingDays, TimeUnit.Days,
                                    index_.businessDayConvention());

            Date endDate = endDate_;
            if (endDate == null)
            endDate = calendar.advance(startDate, length_,
                                       index_.businessDayConvention());

            Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar,
                               index_.businessDayConvention(),
                               index_.businessDayConvention(),
                               DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar,
                               index_.businessDayConvention(),
                               index_.businessDayConvention(),
                               DateGeneration.Rule.Forward, false);

            IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false);

            VanillaSwap.Type type = VanillaSwap.Type.Receiver;

            VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_,
                            fixedSchedule, 0.0, fixedLegDayCounter_,
                            floatSchedule, index_, 0.0, floatingLegDayCounter_);
            temp.setPricingEngine(swapEngine);
            double forward = temp.fairRate();
            if(! strike_.HasValue)
              {
            exerciseRate_ = forward;
            }
            else
              {
            exerciseRate_ = strike_.Value;
            type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer;
            // ensure that calibration instrument is out of the money
            }
            swap_ = new VanillaSwap(type, nominal_,
                            fixedSchedule, exerciseRate_, fixedLegDayCounter_,
                            floatSchedule, index_, 0.0, floatingLegDayCounter_);
            swap_.setPricingEngine(swapEngine);

            Exercise exercise = new EuropeanExercise(exerciseDate);

            swaption_ = new Swaption(swap_, exercise);

            base.performCalculations();
        }
Ejemplo n.º 19
0
        public void testMCDiscreteArithmeticAverageStrike()
        {
            //BOOST_MESSAGE("Testing Monte Carlo discrete arithmetic average-strike Asians...");

            //QL_TEST_START_TIMING

            // data from "Asian Option", Levy, 1997
            // in "Exotic Options: The State of the Art",
            // edited by Clewlow, Strickland
            DiscreteAverageData[] cases5 = {
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 2,
                  0.13, true, 1.51917595129 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 4,
                  0.13, true, 1.67940165674 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 8,
                  0.13, true, 1.75371215251 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 12,
                  0.13, true, 1.77595318693 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 26,
                  0.13, true, 1.81430536630 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 52,
                  0.13, true, 1.82269246898 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 100,
                  0.13, true, 1.83822402464 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 250,
                  0.13, true, 1.83875059026 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 500,
                  0.13, true, 1.83750703638 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 0.0, 11.0/12.0, 1000,
                  0.13, true, 1.83887181884 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 2,
                  0.13, true, 1.51154400089 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 4,
                  0.13, true, 1.67103508506 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 8,
                  0.13, true, 1.74529684070 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 12,
                  0.13, true, 1.76667074564 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 26,
                  0.13, true, 1.80528400613 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 52,
                  0.13, true, 1.81400883891 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 100,
                  0.13, true, 1.82922901451 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 250,
                  0.13, true, 1.82937111773 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 500,
                  0.13, true, 1.82826193186 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 1.0/12.0, 11.0/12.0, 1000,
                  0.13, true, 1.82967846654 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 2,
                  0.13, true, 1.49648170891 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 4,
                  0.13, true, 1.65443100462 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 8,
                  0.13, true, 1.72817806731 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 12,
                  0.13, true, 1.74877367895 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 26,
                  0.13, true, 1.78733801988 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 52,
                  0.13, true, 1.79624826757 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 100,
                  0.13, true, 1.81114186876 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 250,
                  0.13, true, 1.81101152587 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 500,
                  0.13, true, 1.81002311939 ),
                new DiscreteAverageData(Option.Type.Call, 90.0, 87.0, 0.06, 0.025, 3.0/12.0, 11.0/12.0, 1000,
                  0.13, true, 1.81145760308 )
            };

            DayCounter dc = new Actual360();
            Date today = Date.Today ;

            SimpleQuote spot = new SimpleQuote(100.0);
            SimpleQuote qRate = new SimpleQuote(0.03);
            YieldTermStructure qTS =Utilities.flatRate(today, qRate, dc);
            SimpleQuote rRate = new SimpleQuote(0.06);
            YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);
            SimpleQuote vol = new SimpleQuote(0.20);
            BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc);

            Average.Type averageType = QLNet.Average.Type.Arithmetic;
            double runningSum = 0.0;
            int pastFixings = 0;
            for (int l=0; l<cases5.Length; l++) {

                StrikedTypePayoff payoff =
                    new PlainVanillaPayoff(cases5[l].type, cases5[l].strike);

                double dt = cases5[l].length/(cases5[l].fixings-1);
                List<double> timeIncrements = new InitializedList<double>(cases5[l].fixings);
                List<Date> fixingDates = new InitializedList<Date>(cases5[l].fixings);
                timeIncrements[0] = cases5[l].first;
                fixingDates[0] = today + (int)(timeIncrements[0]*360+0.5);
                for (int i=1; i<cases5[l].fixings; i++) {
                    timeIncrements[i] = i*dt + cases5[l].first;
                    fixingDates[i] = today + (int)(timeIncrements[i]*360+0.5);
                }
                Exercise exercise = new EuropeanExercise(fixingDates[cases5[l].fixings-1]);

                spot.setValue(cases5[l].underlying);
                qRate.setValue(cases5[l].dividendYield);
                rRate.setValue(cases5[l].riskFreeRate);
                vol.setValue(cases5[l].volatility);

                BlackScholesMertonProcess stochProcess =
                    new BlackScholesMertonProcess(new Handle<Quote>(spot),
                                                new Handle<YieldTermStructure>(qTS),
                                                new Handle<YieldTermStructure>(rTS),
                                                new Handle<BlackVolTermStructure>(volTS));

                IPricingEngine engine =
                    new MakeMCDiscreteArithmeticASEngine<LowDiscrepancy,Statistics>(stochProcess)
                    .withSeed(3456789)
                    .withSamples(1023)
                    .value() ;

                DiscreteAveragingAsianOption option =
                    new DiscreteAveragingAsianOption(averageType, runningSum,
                                                    pastFixings, fixingDates,
                                                    payoff, exercise);
                option.setPricingEngine(engine);

                double calculated = option.NPV();
                double expected = cases5[l].result;
                double tolerance = 2.0e-2;
                if (Math.Abs(calculated-expected) > tolerance) {
                    REPORT_FAILURE("value", averageType, runningSum, pastFixings,
                                   fixingDates, payoff, exercise, spot.value(),
                                   qRate.value(), rRate.value(), today,
                                   vol.value(), expected, calculated, tolerance);
                }
            }
        }
Ejemplo n.º 20
0
 public CliquetOption(PercentageStrikePayoff payoff, EuropeanExercise maturity, List <Date> resetDates)
     : base(payoff, maturity)
 {
     resetDates_ = new List <Date>(resetDates);
 }
Ejemplo n.º 21
0
        public void testMCDiscreteGeometricAveragePrice()
        {
            //BOOST_MESSAGE("Testing Monte Carlo discrete geometric average-price Asians...");

            // data from "Implementing Derivatives Model",
            // Clewlow, Strickland, p.118-123

            DayCounter dc = new Actual360();
            Date today = Date.Today;

            SimpleQuote spot = new SimpleQuote(100.0);
            SimpleQuote qRate = new SimpleQuote(0.03);
            YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc);
            SimpleQuote rRate = new SimpleQuote(0.06);
            YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);
            SimpleQuote vol  = new SimpleQuote(0.20);
            BlackVolTermStructure volTS =Utilities.flatVol(today, vol, dc);

            BlackScholesMertonProcess stochProcess =
            new BlackScholesMertonProcess(new Handle<Quote>(spot),
                                        new Handle<YieldTermStructure>(qTS),
                                        new Handle<YieldTermStructure>(rTS),
                                        new Handle<BlackVolTermStructure>(volTS));

            double tolerance = 4.0e-3;

            IPricingEngine engine =
            new MakeMCDiscreteGeometricAPEngine
                                <LowDiscrepancy,Statistics>(stochProcess)
                                .withStepsPerYear(1)
                                .withSamples(8191)
                                .value();

            Average.Type averageType = Average.Type.Geometric;
            double runningAccumulator = 1.0;
            int pastFixings = 0;
            int futureFixings = 10;
            Option.Type type = Option.Type.Call;
            double strike = 100.0;
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);

            Date exerciseDate = today + 360;
            Exercise exercise = new EuropeanExercise(exerciseDate);

            List<Date> fixingDates = new InitializedList<Date>(futureFixings);
            int dt = (int)(360/futureFixings+0.5);
            fixingDates[0] = today + dt;
            for (int j=1; j<futureFixings; j++)
            fixingDates[j] = fixingDates[j-1] + dt;

            DiscreteAveragingAsianOption  option =
            new DiscreteAveragingAsianOption(averageType, runningAccumulator,
                                            pastFixings, fixingDates,
                                            payoff, exercise);
            option.setPricingEngine(engine);

            double calculated = option.NPV();

            IPricingEngine engine2 =
              new AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess);
            option.setPricingEngine(engine2);
            double expected = option.NPV();

            if (Math.Abs(calculated-expected) > tolerance) {
            REPORT_FAILURE("value", averageType, runningAccumulator, pastFixings,
                           fixingDates, payoff, exercise, spot.value(),
                           qRate.value(), rRate.value(), today,
                           vol.value(), expected, calculated, tolerance);
            }
        }
Ejemplo n.º 22
0
        public void testPastFixings()
        {
            //BOOST_MESSAGE("Testing use of past fixings in Asian options...");
            DayCounter dc = new Actual360();
            Date today = Date.Today ;

            SimpleQuote spot = new SimpleQuote(100.0);
            SimpleQuote qRate = new SimpleQuote(0.03);
            YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc);
            SimpleQuote rRate = new SimpleQuote(0.06);
            YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc);
            SimpleQuote vol = new SimpleQuote(0.20);
            BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc);

            StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Put, 100.0);

            Exercise exercise = new EuropeanExercise(today + new Period(1,TimeUnit.Years));

            BlackScholesMertonProcess stochProcess =
                new BlackScholesMertonProcess(new Handle<Quote>(spot),
                                              new Handle<YieldTermStructure>(qTS),
                                              new Handle<YieldTermStructure>(rTS),
                                              new Handle<BlackVolTermStructure>(volTS));

            // MC arithmetic average-price
            double runningSum = 0.0;
            int pastFixings = 0;
            List<Date> fixingDates1 = new InitializedList<Date>();
            for (int i=0; i<=12; ++i)
                fixingDates1.Add(today + new Period(i,TimeUnit.Months));

            DiscreteAveragingAsianOption option1 =
                new DiscreteAveragingAsianOption(Average.Type.Arithmetic, runningSum,
                                                 pastFixings, fixingDates1,
                                                 payoff, exercise);

            pastFixings = 2;
            runningSum = pastFixings * spot.value() * 0.8;
            List<Date> fixingDates2 = new InitializedList<Date>();
            for (int i=-2; i<=12; ++i)
                fixingDates2.Add(today + new Period(i,TimeUnit.Months));

            DiscreteAveragingAsianOption option2 =
                new DiscreteAveragingAsianOption(Average.Type.Arithmetic, runningSum,
                                                 pastFixings, fixingDates2,
                                                 payoff, exercise);

            IPricingEngine engine =
               new MakeMCDiscreteArithmeticAPEngine<LowDiscrepancy,Statistics>(stochProcess)
                .withStepsPerYear(1)
                .withSamples(2047)
                .value() ;

            option1.setPricingEngine(engine);
            option2.setPricingEngine(engine);

            double price1 = option1.NPV();
            double price2 = option2.NPV();

            if (Utils.close(price1, price2)) {
                Assert.Fail(
                     "past fixings had no effect on arithmetic average-price option"
                     + "\n  without fixings: " + price1
                     + "\n  with fixings:    " + price2);
            }

            // MC arithmetic average-strike
            engine = new MakeMCDiscreteArithmeticASEngine<LowDiscrepancy,Statistics>(stochProcess)
                .withSamples(2047)
                .value();

            option1.setPricingEngine(engine);
            option2.setPricingEngine(engine);

            price1 = option1.NPV();
            price2 = option2.NPV();

            if (Utils.close(price1, price2)) {
                Assert.Fail(
                     "past fixings had no effect on arithmetic average-strike option"
                     + "\n  without fixings: " + price1
                     + "\n  with fixings:    " + price2);
            }

            // analytic geometric average-price
            double runningProduct = 1.0;
            pastFixings = 0;

            DiscreteAveragingAsianOption option3 =
                new DiscreteAveragingAsianOption(Average.Type.Geometric, runningProduct,
                                                 pastFixings, fixingDates1,
                                                 payoff, exercise);

            pastFixings = 2;
            runningProduct = spot.value() * spot.value();

            DiscreteAveragingAsianOption option4 =
                new DiscreteAveragingAsianOption(Average.Type.Geometric, runningProduct,
                                                 pastFixings, fixingDates2,
                                                 payoff, exercise);

            engine = new AnalyticDiscreteGeometricAveragePriceAsianEngine(stochProcess);

            option3.setPricingEngine(engine);
            option4.setPricingEngine(engine);

            double price3 = option3.NPV();
            double price4 = option4.NPV();

            if (Utils.close(price3, price4)) {
                Assert.Fail(
                     "past fixings had no effect on geometric average-price option"
                     + "\n  without fixings: " + price3
                     + "\n  with fixings:    " + price4);
            }

            // MC geometric average-price
            engine = new MakeMCDiscreteGeometricAPEngine<LowDiscrepancy,Statistics>(stochProcess)
                        .withStepsPerYear(1)
                        .withSamples(2047)
                        .value();

            option3.setPricingEngine(engine);
            option4.setPricingEngine(engine);

            price3 = option3.NPV();
            price4 = option4.NPV();

            if (Utils.close(price3, price4)) {
                Assert.Fail(
                     "past fixings had no effect on geometric average-price option"
                     + "\n  without fixings: " + price3
                     + "\n  with fixings:    " + price4);
            }
        }
        public void calculate(double[] p, GBMParaViewModel para)
        {

            this.xData_ = p;
            this.yData_ = new double[p.Length];

            double sellBuySign = 1.0;

            if (this.sellBuy_ == "매도")
            {
                sellBuySign = -1.0;
            }
            else
            { 
            }

            // set up dates
            Calendar calendar = new TARGET();
            //Date todaysDate = new Date(DateTime.Now);
            Date settlementDate = new Date(para.ReferenceDate_);
            Settings.setEvaluationDate(settlementDate);

            // our options
            Option.Type type = this.callPutEnum_;

            double underlying = para.CurrentPrice_;
            double strike = this.strike_;
            double dividendYield = para.Dividend_ / 100;
            double riskFreeRate = para.Drift_ / 100;

            if (this.callPutEnum_ == Option.Type.Call)
            {
                this.imVol_ = para.Call_Interpolation_.value(this.strike_);
            }
            else if (this.callPutEnum_ == Option.Type.Put)
            {
                this.imVol_ = para.Put_Interpolation_.value(this.strike_);
            }

            double volatility = (this.imVol_ ) / 100;

            Date maturity = new Date(this.maturiry_.AddDays(1));
            

            if (this.callPutEnum_ == 0)
            {
                this.deltaCal_ = 1.0;
                this.gammaCal_ = 0.0;
                this.vegaCal_ = 0.0;
                this.thetaCal_ = 0.0;
                this.rhoCal_ = 0.0;

                this.deltaPosition_ = sellBuySign * this.unit_ * 500000 * underlying;

                this.deltaRisk_ = this.deltaPosition_ * 0.09;
                this.gammaRisk_ = 0.0;
                this.vegaRisk_ = 0.0;

                this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;
                this.deepOTM_ = 0.0;

                //this.remainDays_ = maturity - settlementDate;
                this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;

                return;
            }

            DayCounter dayCounter = new Actual365Fixed();

            Exercise europeanExercise = new EuropeanExercise(maturity);

            SimpleQuote quote = new SimpleQuote(underlying);

            Handle<Quote> underlyingH = new Handle<Quote>(quote);

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);
            var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            // options
            VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise);

            // Analytic formulas:
            // Black-Scholes for European
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));

            this.npv_ = Math.Round(europeanOption.NPV(), 6);
            this.deltaCal_ = sellBuySign * Math.Round(europeanOption.delta(), 6);
            this.gammaCal_ = sellBuySign * Math.Round(europeanOption.gamma(), 6);
            this.vegaCal_ = sellBuySign * Math.Round(europeanOption.vega() / 100, 6);
            this.thetaCal_ = sellBuySign * Math.Round(europeanOption.theta() / 365, 6);
            this.rhoCal_ = sellBuySign * Math.Round(europeanOption.rho() / 100, 6);

            this.deltaPosition_ = Math.Round(this.deltaCal_ * this.unit_ * 500000 * underlying,0);
            this.deltaRisk_ = Math.Round(this.deltaPosition_ * 0.09,0);
            this.gammaRisk_ = Math.Round(0.5 * this.gammaCal_ * (underlying * underlying * 0.08 * 0.08) * this.unit_ * 500000, 0);
            this.vegaRisk_ = Math.Round(this.vegaCal_ * this.imVol_ * 0.25 * this.unit_ * 500000, 0);
            
            this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;

            this.deepOTM_ = 0.0;
            //this.remainDays_ = maturity - settlementDate;
            this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;


            for (int i = 0; i < this.xData_.Length; i++)
			{
                quote.setValue(this.xData_[i]);
                this.yData_[i] = 500000.0 * (double)this.unit_ * europeanOption.NPV();
			}
        }