Exemplo n.º 1
0
		internal static EPutCall SPutCall(PutCall x)
		{
			switch (x)
			{
			case PutCall.Put:
				return EPutCall.Put;
			case PutCall.Call:
				return EPutCall.Call;
			default:
				throw new NotSupportedException();
			}
		}
Exemplo n.º 2
0
		public static double Parity(double P, double S, double X, double t, double r, PutCall PutCall)
		{
			return SmartQuant.Quant.FinMath.Parity(P, S, X, t, r, FinMath.SPutCall(PutCall));
		}
Exemplo n.º 3
0
		public static double Rho(double S, double X, double t, double s, double r, PutCall PutCall)
		{
			return SmartQuant.Quant.FinMath.Rho(S, X, t, s, r, FinMath.SPutCall(PutCall));
		}
Exemplo n.º 4
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Obtains an instance.
        /// </summary>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="putCall">  put or call </param>
        /// <param name="numberOfSteps">  the number of time steps </param>
        /// <returns> the instance </returns>
        public static EuropeanVanillaOptionFunction of(double strike, double timeToExpiry, PutCall putCall, int numberOfSteps)
        {
            double sign = putCall.Call ? 1d : -1d;

            ArgChecker.isTrue(numberOfSteps > 0, "the number of steps should be positive");
            return(new EuropeanVanillaOptionFunction(strike, timeToExpiry, sign, numberOfSteps));
        }
Exemplo n.º 5
0
		public Instrument(Instrument instrument) : this()
		{
			this.id = instrument.id;
			this.type = instrument.type;
			this.symbol = instrument.symbol;
			this.description = instrument.description;
			this.exchange = instrument.exchange;
			this.currencyId = instrument.currencyId;
			this.tickSize = instrument.tickSize;
			this.putcall = instrument.putcall;
			this.factor = instrument.factor;
			this.strike = instrument.strike;
			this.maturity = instrument.maturity;
			this.margin = instrument.margin;
			foreach (Leg current in instrument.Legs)
			{
				this.Legs.Add(new Leg(current.Instrument, current.Weight));
			}
			this.trade = instrument.Trade;
			this.bid = instrument.Bid;
			this.ask = instrument.Ask;
		}
Exemplo n.º 6
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the vega.
        /// <para>
        /// Note that the 'numeraire' is a simple multiplier and is the responsibility of the caller.
        ///
        /// </para>
        /// </summary>
        /// <param name="forward">  the forward value of the underlying </param>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="normalVol">  the normal volatility </param>
        /// <param name="putCall">  whether it is put or call </param>
        /// <returns> the vega </returns>
        public static double vega(double forward, double strike, double timeToExpiry, double normalVol, PutCall putCall)
        {
            int    sign       = putCall.Call ? 1 : -1;
            double rootT      = Math.Sqrt(timeToExpiry);
            double sigmaRootT = normalVol * rootT;

            if (sigmaRootT < NEAR_ZERO)
            {
                double x = sign * (forward - strike);
                // ambiguous if x and sigmaRootT are tiny, then reference number is returned
                return(Math.Abs(x) > NEAR_ZERO ? 0d : rootT / Math.Sqrt(2d * Math.PI));
            }
            double arg = (forward - strike) / sigmaRootT;
            double pdf = DISTRIBUTION.getPDF(arg);

            return(pdf * rootT);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates an identifier for an ETD option instrument.
        /// <para>
        /// This takes into account the expiry of the underlying instrument. If the underlying expiry
        /// is the same as the expiry of the option, the identifier is the same as the normal one.
        /// Otherwise, the underlying expiry is added after the option expiry. For example:
        /// {@code 'OG-ETD~O-ECAG-OGBS-201706-P1.50-U201709'}.
        ///
        /// </para>
        /// </summary>
        /// <param name="exchangeId">  the MIC code of the exchange where the instruments are traded </param>
        /// <param name="contractCode">  the code supplied by the exchange for use in clearing and margining, such as in SPAN </param>
        /// <param name="expiryMonth">  the month of expiry </param>
        /// <param name="variant">  the variant of the ETD, such as 'Monthly', 'Weekly, 'Daily' or 'Flex' </param>
        /// <param name="version">  the non-negative version, zero by default </param>
        /// <param name="putCall">  the Put/Call flag </param>
        /// <param name="strikePrice">  the strike price </param>
        /// <param name="underlyingExpiryMonth">  the expiry of the underlying instrument, such as a future, may be null </param>
        /// <returns> the identifier </returns>
        public static SecurityId optionId(ExchangeId exchangeId, EtdContractCode contractCode, YearMonth expiryMonth, EtdVariant variant, int version, PutCall putCall, double strikePrice, YearMonth underlyingExpiryMonth)
        {
            ArgChecker.notNull(exchangeId, "exchangeId");
            ArgChecker.notNull(contractCode, "contractCode");
            ArgChecker.notNull(expiryMonth, "expiryMonth");
            ArgChecker.notNull(variant, "variant");
            ArgChecker.notNull(putCall, "putCall");

            string putCallStr  = putCall == PutCall.PUT ? "P" : "C";
            string versionCode = version > 0 ? "V" + version + SEPARATOR : "";

            NumberFormat f = NumberFormat.getIntegerInstance(Locale.ENGLISH);

            f.GroupingUsed          = false;
            f.MaximumFractionDigits = 8;
            string strikeStr = f.format(strikePrice).replace('-', 'M');

            string underlying = "";

            if (underlyingExpiryMonth != null && !underlyingExpiryMonth.Equals(expiryMonth))
            {
                underlying = SEPARATOR + "U" + underlyingExpiryMonth.format(YM_FORMAT);
            }

            string id = (new StringBuilder(40)).Append(OPT_PREFIX).Append(exchangeId).Append(SEPARATOR).Append(contractCode).Append(SEPARATOR).Append(expiryMonth.format(YM_FORMAT)).Append(variant.Code).Append(SEPARATOR).Append(versionCode).Append(putCallStr).Append(strikeStr).Append(underlying).ToString();

            return(SecurityId.of(ETD_SCHEME, id));
        }
Exemplo n.º 8
0
 private EtdOptionSecurity(SecurityInfo info, EtdContractSpecId contractSpecId, YearMonth expiry, EtdVariant variant, int version, PutCall putCall, double strikePrice, YearMonth underlyingExpiryMonth)
 {
     JodaBeanUtils.notNull(info, "info");
     JodaBeanUtils.notNull(contractSpecId, "contractSpecId");
     JodaBeanUtils.notNull(expiry, "expiry");
     JodaBeanUtils.notNull(variant, "variant");
     ArgChecker.notNegative(version, "version");
     JodaBeanUtils.notNull(putCall, "putCall");
     this.info                  = info;
     this.contractSpecId        = contractSpecId;
     this.expiry                = expiry;
     this.variant               = variant;
     this.version               = version;
     this.putCall               = putCall;
     this.strikePrice           = strikePrice;
     this.underlyingExpiryMonth = underlyingExpiryMonth;
 }
Exemplo n.º 9
0
 /// <summary>
 /// Sets whether the option is a put or call. </summary>
 /// <param name="putCall">  the new value, not null </param>
 /// <returns> this, for chaining, not null </returns>
 public Builder putCall(PutCall putCall)
 {
     JodaBeanUtils.notNull(putCall, "putCall");
     this.putCall_Renamed = putCall;
     return(this);
 }
Exemplo n.º 10
0
 //-------------------------------------------------------------------------
 /// <summary>
 /// Obtains an instance from a contract specification, expiry year-month, variant, version, put/call and strike price.
 /// <para>
 /// The security identifier will be automatically created using <seealso cref="EtdIdUtils"/>.
 /// The specification must be for an option.
 ///
 /// </para>
 /// </summary>
 /// <param name="spec">  the option contract specification </param>
 /// <param name="expiry">  the expiry year-month of the option </param>
 /// <param name="variant">  the variant of the ETD, such as 'Monthly', 'Weekly, 'Daily' or 'Flex' </param>
 /// <param name="version">  the non-negative version, zero if versioning does not apply </param>
 /// <param name="putCall">  whether the option is a put or call </param>
 /// <param name="strikePrice">  the strike price of the option </param>
 /// <returns> an option security based on this contract specification </returns>
 /// <exception cref="IllegalStateException"> if the product type of the contract specification is not {@code OPTION} </exception>
 public static EtdOptionSecurity of(EtdContractSpec spec, YearMonth expiry, EtdVariant variant, int version, PutCall putCall, double strikePrice)
 {
     return(of(spec, expiry, variant, version, putCall, strikePrice, null));
 }
Exemplo n.º 11
0
        /// <summary>
        /// Obtains an instance from a contract specification, expiry year-month, variant,
        /// version, put/call, strike price and underlying expiry.
        /// <para>
        /// The security identifier will be automatically created using <seealso cref="EtdIdUtils"/>.
        /// The specification must be for an option.
        ///
        /// </para>
        /// </summary>
        /// <param name="spec">  the option contract specification </param>
        /// <param name="expiry">  the expiry year-month of the option </param>
        /// <param name="variant">  the variant of the ETD, such as 'Monthly', 'Weekly, 'Daily' or 'Flex' </param>
        /// <param name="version">  the non-negative version, zero if versioning does not apply </param>
        /// <param name="putCall">  whether the option is a put or call </param>
        /// <param name="strikePrice">  the strike price of the option </param>
        /// <param name="underlyingExpiryMonth">  the expiry of the underlying instrument, such as a future, may be null </param>
        /// <returns> an option security based on this contract specification </returns>
        /// <exception cref="IllegalStateException"> if the product type of the contract specification is not {@code OPTION} </exception>
        public static EtdOptionSecurity of(EtdContractSpec spec, YearMonth expiry, EtdVariant variant, int version, PutCall putCall, double strikePrice, YearMonth underlyingExpiryMonth)
        {
            if (spec.Type != EtdType.OPTION)
            {
                throw new System.InvalidOperationException(Messages.format("Cannot create an EtdOptionSecurity from a contract specification of type '{}'", spec.Type));
            }
            SecurityId securityId = EtdIdUtils.optionId(spec.ExchangeId, spec.ContractCode, expiry, variant, version, putCall, strikePrice, underlyingExpiryMonth);

            return(EtdOptionSecurity.builder().info(SecurityInfo.of(securityId, spec.PriceInfo)).contractSpecId(spec.Id).expiry(expiry).variant(variant).version(version).putCall(putCall).strikePrice(strikePrice).underlyingExpiryMonth(underlyingExpiryMonth).build());
        }
 /// <summary>
 /// Creates an option security based on this contract specification.
 /// <para>
 /// The security identifier will be automatically created using <seealso cref="EtdIdUtils"/>.
 /// The <seealso cref="#getType() type"/> must be <seealso cref="EtdType#OPTION"/> otherwise an exception will be thrown.
 ///
 /// </para>
 /// </summary>
 /// <param name="expiryMonth">  the expiry month of the option </param>
 /// <param name="variant">  the variant of the ETD, such as 'Monthly', 'Weekly, 'Daily' or 'Flex' </param>
 /// <param name="version">  the non-negative version, zero by default </param>
 /// <param name="putCall">  whether the option is a put or call </param>
 /// <param name="strikePrice">  the strike price of the option </param>
 /// <param name="underlyingExpiryMonth">  the expiry of the underlying instrument, such as a future </param>
 /// <returns> an option security based on this contract specification </returns>
 /// <exception cref="IllegalStateException"> if the product type of the contract specification is not {@code OPTION} </exception>
 public EtdOptionSecurity createOption(YearMonth expiryMonth, EtdVariant variant, int version, PutCall putCall, double strikePrice, YearMonth underlyingExpiryMonth)
 {
     return(EtdOptionSecurity.of(this, expiryMonth, variant, version, putCall, strikePrice, underlyingExpiryMonth));
 }
Exemplo n.º 13
0
        /// <summary>
        /// Test consistency between price methods, and Greek via finite difference.
        /// </summary>
        public virtual void test_trinomialTree()
        {
            int    nSteps = 135;
            double dt     = TIME / nSteps;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            double fdEps = 1.0e-4;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function   = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps);
                                double[]       @params    = lattice.getParametersTrinomial(vol, interest - dividend, dt).toArray();
                                DoubleArray    time       = DoubleArray.of(nSteps + 1, i => dt * i);
                                DoubleArray    df         = DoubleArray.of(nSteps, i => Math.Exp(-interest * dt));
                                double[][]     stateValue = new double[nSteps + 1][];
                                stateValue[0] = new double[] { SPOT };
                                IList <DoubleMatrix> prob  = new List <DoubleMatrix>();
                                double[]             probs = new double[] { @params[5], @params[4], @params[3] };
                                for (int i = 0; i < nSteps; ++i)
                                {
                                    int index = i;
                                    stateValue[i + 1] = DoubleArray.of(2 * i + 3, j => SPOT * Math.Pow(@params[2], index + 1 - j) * Math.Pow(@params[1], j)).toArray();
                                    double[][] probMatrix = new double[2 * i + 1][];
                                    Arrays.fill(probMatrix, probs);
                                    prob.Add(DoubleMatrix.ofUnsafe(probMatrix));
                                }
                                RecombiningTrinomialTreeData treeData = RecombiningTrinomialTreeData.of(DoubleMatrix.ofUnsafe(stateValue), prob, df, time);
                                double priceData   = TRINOMIAL_TREE.optionPrice(function, treeData);
                                double priceParams = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(priceData, priceParams);
                                ValueDerivatives priceDeriv = TRINOMIAL_TREE.optionPriceAdjoint(function, treeData);
                                assertEquals(priceDeriv.Value, priceData);
                                double priceUp = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT + fdEps, vol, interest, dividend);
                                double priceDw = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT - fdEps, vol, interest, dividend);
                                double fdDelta = 0.5 * (priceUp - priceDw) / fdEps;
                                assertEquals(priceDeriv.getDerivative(0), fdDelta, 3.0e-2);
                            }
                        }
                    }
                }
            }
        }
        public virtual void test_trinomialTree()
        {
            int nSteps = 135;

            LatticeSpecification[] lattices = new LatticeSpecification[]
            {
                new CoxRossRubinsteinLatticeSpecification(),
                new TrigeorgisLatticeSpecification()
            };
            double tol = 5.0e-3;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps);
                                double         exact    = BlackScholesFormulaRepository.price(SPOT, strike, TIME, vol, interest, interest - dividend, isCall);
                                foreach (LatticeSpecification lattice in lattices)
                                {
                                    double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                    assertEquals(computed, exact, Math.Max(exact, 1d) * tol);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 15
0
		internal static PutOrCall Convert(PutCall value)
		{
			switch (value)
			{
			case PutCall.Put:
				return PutOrCall.Put;
			case PutCall.Call:
				return PutOrCall.Call;
			default:
				throw new ArgumentException(string.Format("Unsupported PutOrCall - {0}", value));
			}
		}
Exemplo n.º 16
0
 public static double BM(double S, double X, double t, double s, double r, PutCall PutCall, int n)
 {
     return(SmartQuant.Quant.FinMath.BM(S, X, t, s, r, FinMath.SPutCall(PutCall)));
 }
Exemplo n.º 17
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the price and first order derivatives.
        /// <para>
        /// The derivatives are stored in an array with:
        /// <ul>
        /// <li>[0] derivative with respect to the forward
        /// <li>[1] derivative with respect to the volatility
        /// <li>[2] derivative with respect to the strike
        /// </ul>
        ///
        /// </para>
        /// </summary>
        /// <param name="forward">  the forward value of the underlying </param>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="normalVol">  the normal volatility </param>
        /// <param name="numeraire">  the numeraire </param>
        /// <param name="putCall">  whether it is put or call </param>
        /// <returns> the price and associated derivatives </returns>
        public static ValueDerivatives priceAdjoint(double forward, double strike, double timeToExpiry, double normalVol, double numeraire, PutCall putCall)
        {
            int    sign = putCall.Call ? 1 : -1;
            double price;
            double cdf = 0d;
            double pdf = 0d;
            double arg = 0d;
            double x   = 0d;
            // Implementation Note: Forward sweep.
            double sigmaRootT = normalVol * Math.Sqrt(timeToExpiry);

            if (sigmaRootT < NormalFormulaRepository.NEAR_ZERO)
            {
                x     = sign * (forward - strike);
                price = (x > 0 ? numeraire * x : 0d);
            }
            else
            {
                arg   = sign * (forward - strike) / sigmaRootT;
                cdf   = NormalFormulaRepository.DISTRIBUTION.getCDF(arg);
                pdf   = NormalFormulaRepository.DISTRIBUTION.getPDF(arg);
                price = numeraire * (sign * (forward - strike) * cdf + sigmaRootT * pdf);
            }
            // Implementation Note: Backward sweep.
            double forwardDerivative;
            double volatilityDerivative;
            double strikeDerivative;
            double priceBar = 1d;

            if (sigmaRootT < NormalFormulaRepository.NEAR_ZERO)
            {
                double xBar = (x > 0 ? numeraire : 0d);
                forwardDerivative    = sign * xBar;
                strikeDerivative     = -forwardDerivative;
                volatilityDerivative = 0d;
            }
            else
            {
                double cdfBar = numeraire * (sign * (forward - strike)) * priceBar;
                double pdfBar = numeraire * sigmaRootT * priceBar;
                double argBar = pdf * cdfBar - pdf * arg * pdfBar;
                forwardDerivative = numeraire * sign * cdf * priceBar + sign / sigmaRootT * argBar;
                strikeDerivative  = -forwardDerivative;
                double sigmaRootTBar = -arg / sigmaRootT * argBar + numeraire * pdf * priceBar;
                volatilityDerivative = Math.Sqrt(timeToExpiry) * sigmaRootTBar;
            }
            return(ValueDerivatives.of(price, DoubleArray.of(forwardDerivative, volatilityDerivative, strikeDerivative)));
        }
Exemplo n.º 18
0
 public static double Theta(double S, double X, double t, double s, double r, PutCall PutCall)
 {
     return(SmartQuant.Quant.FinMath.Theta(S, X, t, s, r, FinMath.SPutCall(PutCall)));
 }
Exemplo n.º 19
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the forward price.
        /// <para>
        /// Note that the 'numeraire' is a simple multiplier and is the responsibility of the caller.
        ///
        /// </para>
        /// </summary>
        /// <param name="forward">  the forward value of the underlying </param>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="normalVol">  the normal volatility </param>
        /// <param name="putCall">  whether it is put or call </param>
        /// <returns> the forward price </returns>
        public static double price(double forward, double strike, double timeToExpiry, double normalVol, PutCall putCall)
        {
            double sigmaRootT = normalVol * Math.Sqrt(timeToExpiry);
            int    sign       = putCall.Call ? 1 : -1;

            if (sigmaRootT < NEAR_ZERO)
            {
                double x = sign * (forward - strike);
                return(x > 0 ? x : 0d);
            }
            double arg = sign * (forward - strike) / sigmaRootT;
            double cdf = DISTRIBUTION.getCDF(arg);
            double pdf = DISTRIBUTION.getPDF(arg);

            return(sign * (forward - strike) * cdf + sigmaRootT * pdf);
        }
Exemplo n.º 20
0
        public double priceVega(double expiry, PutCall putCall, double strike, double forward, double volatility)
        {
            double shift = shiftCurve.yValue(expiry);

            return(BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility));
        }
Exemplo n.º 21
0
		public static double Theta(double S, double X, double t, double s, double r, PutCall PutCall)
		{
			return FreeQuant.Quant.FinMath.Theta(S, X, t, s, r, FinMath.SPutCall(PutCall));
		}
Exemplo n.º 22
0
 public static double Payoff(double S, double X, PutCall PutCall)
 {
     return(FreeQuant.Quant.FinMath.Payoff(S, X, FinMath.SPutCall(PutCall)));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Obtains an instance.
        /// </summary>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="putCall">  put or call </param>
        /// <param name="numberOfSteps">  number of steps </param>
        /// <param name="barrierType">  the barrier type </param>
        /// <param name="barrierLevel">  the barrier level </param>
        /// <param name="rebate">  the rebate </param>
        /// <returns> the instance </returns>
        public static ConstantContinuousSingleBarrierKnockoutFunction of(double strike, double timeToExpiry, PutCall putCall, int numberOfSteps, BarrierType barrierType, double barrierLevel, DoubleArray rebate)
        {
            ArgChecker.isTrue(numberOfSteps > 0, "the number of steps should be positive");
            ArgChecker.isTrue(numberOfSteps + 1 == rebate.size(), "the size of rebate should be numberOfSteps + 1");
            double sign = putCall.Call ? 1d : -1d;

            return(new ConstantContinuousSingleBarrierKnockoutFunction(strike, timeToExpiry, sign, numberOfSteps, barrierType, barrierLevel, rebate));
        }
Exemplo n.º 24
0
 public static double Parity(double P, double S, double X, double t, double r, PutCall PutCall)
 {
     return(FreeQuant.Quant.FinMath.Parity(P, S, X, t, r, FinMath.SPutCall(PutCall)));
 }
Exemplo n.º 25
0
		public static double Payoff(double S, double X, PutCall PutCall)
		{
			return SmartQuant.Quant.FinMath.Payoff(S, X, FinMath.SPutCall(PutCall));
		}
Exemplo n.º 26
0
 public static double MC(double S, double X, double t, double s, double r, PutCall PutCall, int n)
 {
     return(FreeQuant.Quant.FinMath.MC(S, X, t, s, r, FinMath.SPutCall(PutCall)));
 }
Exemplo n.º 27
0
		public static double MC(double S, double X, double t, double s, double r, PutCall PutCall, int n)
		{
			return SmartQuant.Quant.FinMath.MC(S, X, t, s, r, FinMath.SPutCall(PutCall));
		}
Exemplo n.º 28
0
 public static double Rho(double S, double X, double t, double s, double r, PutCall PutCall)
 {
     return(FreeQuant.Quant.FinMath.Rho(S, X, t, s, r, FinMath.SPutCall(PutCall)));
 }
Exemplo n.º 29
0
		public static double ImpliedVolatility(double S, double X, double t, double r, double P, OptionType OptionType, PutCall PutCall, OptionPrice Method)
		{
			return SmartQuant.Quant.FinMath.ImpliedVolatility(S, X, t, r, P, FinMath.SOptionType(OptionType), FinMath.SPutCall(PutCall), FinMath.SOptionPrice(Method));
		}
Exemplo n.º 30
0
 public static double ImpliedVolatility(double S, double X, double t, double r, double P, OptionType OptionType, PutCall PutCall, OptionPrice Method)
 {
     return(FreeQuant.Quant.FinMath.ImpliedVolatility(S, X, t, r, P, FinMath.SOptionType(OptionType), FinMath.SPutCall(PutCall), FinMath.SOptionPrice(Method)));
 }
Exemplo n.º 31
0
 /// <summary>
 /// Sets whether the option is put or call.
 /// <para>
 /// A call gives the owner the right, but not obligation, to buy the underlying at
 /// an agreed price in the future. A put gives a similar option to sell.
 /// </para>
 /// </summary>
 /// <param name="putCall">  the new value </param>
 /// <returns> this, for chaining, not null </returns>
 public Builder putCall(PutCall putCall)
 {
     this.putCall_Renamed = putCall;
     return(this);
 }
Exemplo n.º 32
0
        public virtual void test_trinomialTree_down()
        {
            int nSteps = 133;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            DoubleArray          rebate  = DoubleArray.of(nSteps + 1, i => REBATE_AMOUNT);
            double barrierLevel          = 76d;
            double tol = 1.0e-2;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function = ConstantContinuousSingleBarrierKnockoutFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps, BarrierType.DOWN, barrierLevel, rebate);
                                SimpleConstantContinuousBarrier barrier = SimpleConstantContinuousBarrier.of(BarrierType.DOWN, KnockType.KNOCK_OUT, barrierLevel);
                                double exact    = REBATE_AMOUNT * REBATE_PRICER.price(SPOT, TIME, interest - dividend, interest, vol, barrier.inverseKnockType()) + BARRIER_PRICER.price(SPOT, strike, TIME, interest - dividend, interest, vol, isCall, barrier);
                                double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(computed, exact, Math.Max(exact, 1d) * tol);
                            }
                        }
                    }
                }
            }
        }
 public double priceTheta(double expiry, PutCall putCall, double strike, double forward, double volatility)
 {
     return(NormalFormulaRepository.theta(forward, strike, expiry, volatility, putCall));
 }
 public double priceDelta(double expiry, double tenor, PutCall putCall, double strike, double forward, double volatility)
 {
     return(BlackFormulaRepository.delta(forward, strike, expiry, volatility, putCall.Call));
 }
Exemplo n.º 35
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the delta.
        /// <para>
        /// Note that the 'numeraire' is a simple multiplier and is the responsibility of the caller.
        ///
        /// </para>
        /// </summary>
        /// <param name="forward">  the forward value of the underlying </param>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="normalVol">  the normal volatility </param>
        /// <param name="putCall">  whether it is put or call </param>
        /// <returns> the delta </returns>
        public static double delta(double forward, double strike, double timeToExpiry, double normalVol, PutCall putCall)
        {
            int    sign       = putCall.Call ? 1 : -1;
            double sigmaRootT = normalVol * Math.Sqrt(timeToExpiry);

            if (sigmaRootT < NEAR_ZERO)
            {
                double x = sign * (forward - strike);
                if (Math.Abs(x) <= NEAR_ZERO)
                {
                    // ambiguous if x and sigmaRootT are tiny, then reference number is returned
                    return(sign * 0.5);
                }
                return(x > 0 ? sign : 0d);
            }
            double arg = sign * (forward - strike) / sigmaRootT;
            double cdf = DISTRIBUTION.getCDF(arg);

            return(sign * cdf);
        }
 public double priceTheta(double expiry, double tenor, PutCall putCall, double strike, double forward, double volatility)
 {
     return(BlackFormulaRepository.driftlessTheta(forward, strike, expiry, volatility));
 }
Exemplo n.º 37
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the implied volatility.
        /// <para>
        /// If the volatility data is not zero, it is used as a starting point for the volatility search.
        /// </para>
        /// <para>
        /// Note that the 'numeraire' is a simple multiplier and is the responsibility of the caller.
        ///
        /// </para>
        /// </summary>
        /// <param name="optionPrice">  the price of the option </param>
        /// <param name="forward">  the forward value of the underlying </param>
        /// <param name="strike">  the strike </param>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="initialNormalVol">  the normal volatility used to start the search </param>
        /// <param name="numeraire">  the numeraire </param>
        /// <param name="putCall">  whether it is put or call </param>
        /// <returns> the implied volatility </returns>
        public static double impliedVolatility(double optionPrice, double forward, double strike, double timeToExpiry, double initialNormalVol, double numeraire, PutCall putCall)
        {
            double intrinsicPrice = numeraire * Math.Max(0, (putCall.Call ? 1 : -1) * (forward - strike));

            ArgChecker.isTrue(optionPrice > intrinsicPrice || DoubleMath.fuzzyEquals(optionPrice, intrinsicPrice, 1e-6), "Option price (" + optionPrice + ") less than intrinsic value (" + intrinsicPrice + ")");
            if (System.BitConverter.DoubleToInt64Bits(optionPrice) == Double.doubleToLongBits(intrinsicPrice))
            {
                return(0d);
            }
            double           sigma     = (Math.Abs(initialNormalVol) < 1e-10 ? 0.3 * forward : initialNormalVol);
            double           maxChange = 0.5 * forward;
            ValueDerivatives price     = priceAdjoint(forward, strike, timeToExpiry, sigma, numeraire, putCall);
            double           vega      = price.getDerivative(1);
            double           change    = (price.Value - optionPrice) / vega;
            double           sign      = Math.Sign(change);

            change = sign * Math.Min(maxChange, Math.Abs(change));
            if (change > 0 && change > sigma)
            {
                change = sigma;
            }
            int count = 0;

            while (Math.Abs(change) > EPS)
            {
                sigma -= change;
                price  = priceAdjoint(forward, strike, timeToExpiry, sigma, numeraire, putCall);
                vega   = price.getDerivative(1);
                change = (price.Value - optionPrice) / vega;
                sign   = Math.Sign(change);
                change = sign * Math.Min(maxChange, Math.Abs(change));
                if (change > 0 && change > sigma)
                {
                    change = sigma;
                }
                if (count++ > MAX_ITERATIONS)
                {
                    BracketRoot bracketer = new BracketRoot();
                    BisectionSingleRootFinder    rootFinder = new BisectionSingleRootFinder(EPS);
                    System.Func <double, double> func       = (double?volatility) =>
                    {
                        return(numeraire * NormalFormulaRepository.price(forward, strike, timeToExpiry, volatility.Value, putCall) - optionPrice);
                    };
                    double[] range = bracketer.getBracketedPoints(func, 0d, 10d);
                    return(rootFinder.getRoot(func, range[0], range[1]).Value);
                }
            }
            return(sigma);
        }
Exemplo n.º 38
0
		public static double BM(double S, double X, double t, double s, double r, PutCall PutCall, int n)
		{
			return FreeQuant.Quant.FinMath.BM(S, X, t, s, r, FinMath.SPutCall(PutCall));
		}
 public double priceVega(double expiry, PutCall putCall, double strike, double forward, double volatility)
 {
     return(BlackFormulaRepository.vega(forward, strike, expiry, volatility));
 }
Exemplo n.º 40
0
 /// <summary>
 /// Creates an identifier for an ETD option instrument.
 /// <para>
 /// A typical monthly ETD with version zero will have the format:
 /// {@code 'OG-ETD~O-ECAG-OGBS-201706-P1.50'}.
 /// </para>
 /// <para>
 /// A more complex flex ETD (12th of the month, Cash settlement, European) with version two will have the format:
 /// {@code 'OG-ETD~O-ECAG-OGBS-20170612CE-V2-P1.50'}.
 ///
 /// </para>
 /// </summary>
 /// <param name="exchangeId">  the MIC code of the exchange where the instruments are traded </param>
 /// <param name="contractCode">  the code supplied by the exchange for use in clearing and margining, such as in SPAN </param>
 /// <param name="expiryMonth">  the month of expiry </param>
 /// <param name="variant">  the variant of the ETD, such as 'Monthly', 'Weekly, 'Daily' or 'Flex' </param>
 /// <param name="version">  the non-negative version, zero by default </param>
 /// <param name="putCall">  the Put/Call flag </param>
 /// <param name="strikePrice">  the strike price </param>
 /// <returns> the identifier </returns>
 public static SecurityId optionId(ExchangeId exchangeId, EtdContractCode contractCode, YearMonth expiryMonth, EtdVariant variant, int version, PutCall putCall, double strikePrice)
 {
     return(optionId(exchangeId, contractCode, expiryMonth, variant, version, putCall, strikePrice, null));
 }