//        ! Returns the put option rate
        //           (multiplied by: nominal*accrualperiod*discount is the NPV of the option)
        //
        public double putOptionRate()
        {
            double putOptionRate = 0.0;

            if (hasPutStrike_)
            {
                // Step function
                putOptionRate = isPutCashOrNothing_ ? putDigitalPayoff_ : putStrike_;
                CappedFlooredCoupon next     = new CappedFlooredCoupon(underlying_, null, putStrike_ + putRightEps_);
                CappedFlooredCoupon previous = new CappedFlooredCoupon(underlying_, null, putStrike_ - putLeftEps_);
                putOptionRate *= (next.rate() - previous.rate()) / (putLeftEps_ + putRightEps_);
                if (!isPutCashOrNothing_)
                {
                    // Put
                    CappedFlooredCoupon atStrike = new CappedFlooredCoupon(underlying_, null, putStrike_);
                    double put = -underlying_.rate() + atStrike.rate();
                    // Sum up
                    putOptionRate -= put;
                }
            }
            return(putOptionRate);
        }
        //        ! Returns the call option rate
        //           (multiplied by: nominal*accrualperiod*discount is the NPV of the option)
        //
        public double callOptionRate()
        {
            double callOptionRate = 0.0;

            if (hasCallStrike_)
            {
                // Step function
                callOptionRate = isCallCashOrNothing_ ? callDigitalPayoff_ : callStrike_;
                CappedFlooredCoupon next     = new CappedFlooredCoupon(underlying_, callStrike_ + callRightEps_);
                CappedFlooredCoupon previous = new CappedFlooredCoupon(underlying_, callStrike_ - callLeftEps_);
                callOptionRate *= (next.rate() - previous.rate()) / (callLeftEps_ + callRightEps_);
                if (!isCallCashOrNothing_)
                {
                    // Call
                    CappedFlooredCoupon atStrike = new CappedFlooredCoupon(underlying_, callStrike_);
                    double call = underlying_.rate() - atStrike.rate();
                    // Sum up
                    callOptionRate += call;
                }
            }
            return(callOptionRate);
        }