com.qaant.optionModels.QWhaley.java Source code

Java tutorial

Introduction

Here is the source code for com.qaant.optionModels.QWhaley.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.qaant.optionModels;

import com.qaant.Qinterfaces.QOptionable;
import org.apache.commons.math3.distribution.NormalDistribution;
import com.qaant.structures.Qunderlying;

/**
 *
 * @author pauli
 */
public class QWhaley extends QAbstractModel implements QOptionable {

    static {
        modelMap.put(2, "Whaley Barone Adesi- QAANT");
    }

    protected double q, b;

    public QWhaley() {
        super();
    }

    public QWhaley(Qunderlying und, char callPut, double strike, double daysToExpiration, double rate,
            double optionMktValue) {
        super(und, callPut, strike, daysToExpiration, rate, optionMktValue);
    }

    public QWhaley(char tipoContrato, double underlyingValue, double underlyingHistVolatility, double dividendRate,
            char callPut, double strike, double daysToExpiration, double rate, double optionMktValue) {
        super(tipoContrato, underlyingValue, underlyingHistVolatility, dividendRate, callPut, strike,
                daysToExpiration, rate, optionMktValue);
    }

    @Override
    //public void runModel(){
    public void run() {
        //recalcula un modelo BS para obtener las greeks por BS

        QBlackScholes optW = new QBlackScholes(tipoContrato, underlyingValue, underlyingHistVolatility,
                dividendRate, callPut, strike, daysToExpiration, rate, 0);

        prima = optW.getPrima();
        delta = optW.getDelta();
        gamma = optW.getGamma();
        vega = optW.getVega();
        theta = optW.getTheta();
        rho = optW.getRho();

        if (tipoContrato == 'F' || callPut == 'P') {
            wWhaley();
        }

    }

    private void wWhaley() {

        pModelName = "Whaley QAANT";
        modelNumber = 2;
        tipoEjercicio = AMERICAN;

        //     q=(tipoContrato==STOCK) ? dividendRate:rate; 
        //q: si es una accion q es el dividendo, si es un futuro q se toma la rate para descontar el valor futr a presente 
        //Se hace este reemplazo para poder usar la misma form en STOCK y FUTURO

        double xx;

        switch (tipoContrato) {
        case STOCK:
            q = dividendRate;
            b = rate;
            break;

        case FUTURES:
            q = rate;
            b = 0;
            break;
        }
        double vlt2 = volatModel * volatModel;
        double VltSqrDayYear = volatModel * sqrDayYear;
        double h = 1 - z; //descuento para valor presente

        double alfa = 2 * rate / vlt2;
        double beta = 2 * (b - q) / vlt2;

        double lambda = (-(beta - 1) + cpFlag * Math.sqrt((beta - 1) * (beta - 1) + 4 * alfa / h)) / 2;

        double eex = Math.exp(-q * dayYear);//descuento por dividendos

        double s1 = strike;
        double zz = 1 / Math.sqrt(2 * Math.PI);
        double zerror = 1;
        do {
            double d1 = (Math.log(s1 / strike) + ((rate - q) + vlt2 / 2) * dayYear) / VltSqrDayYear;
            xx = (1 - eex * new NormalDistribution().cumulativeProbability(cpFlag * d1));

            double corr = s1 / lambda * xx;

            QBlackScholes option = new QBlackScholes(tipoContrato, s1, volatModel, dividendRate, callPut, strike,
                    daysToExpiration, rate, 0);

            double mBlackScholes = option.getPrima();
            double rhs = mBlackScholes + cpFlag * corr;

            double lhs = cpFlag * (s1 - strike);
            zerror = lhs - rhs;
            double nd1 = zz * Math.exp(-0.5 * d1 * d1); //standard normal prob?
            double slope = cpFlag * (1 - 1 / lambda) * xx + 1 / lambda * (eex * nd1) * 1 / VltSqrDayYear;
            s1 = s1 - zerror / slope;

        } while (Math.abs(zerror) > 0.000001);

        double a = cpFlag * s1 / lambda * xx;

        switch (callPut) {
        case CALL: //Call
            if (underlyingValue >= s1) {
                prima = underlyingValue - strike;
            } else {
                prima += a * Math.pow((underlyingValue / s1), lambda);
            }
            break;

        case PUT: //Put
            if (underlyingValue <= s1) {
                prima = strike - underlyingValue;
            } else {
                prima += a * Math.pow((underlyingValue / s1), lambda);
            }
            //prima=10.1;
            break;
        }
    }

    @Override
    protected double modelGetPrima(double volForLambda) {
        return new QWhaley(tipoContrato, underlyingValue, volForLambda, dividendRate, callPut, strike,
                daysToExpiration, rate, -1).getPrima();
    }

}