com.opengamma.analytics.financial.model.option.definition.ForwardStartOptionDefinition.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.option.definition.ForwardStartOptionDefinition.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.analytics.financial.model.option.definition;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.analytics.financial.model.option.Moneyness;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.time.Expiry;

/**
 * 
 */
public class ForwardStartOptionDefinition extends OptionDefinition {
    private static final Logger s_logger = LoggerFactory.getLogger(ForwardStartOptionDefinition.class);
    private final OptionExerciseFunction<StandardOptionDataBundle> _exerciseFunction = new EuropeanExerciseFunction<>();
    private final OptionPayoffFunction<StandardOptionDataBundle> _payoffFunction = new OptionPayoffFunction<StandardOptionDataBundle>() {

        @Override
        public double getPayoff(final StandardOptionDataBundle data, final Double optionPrice) {
            final ZonedDateTime date = data.getDate();
            if (date.isBefore(getStartTime().getExpiry())) {
                throw new IllegalArgumentException("Cannot get strike before start time: it has not been defined");
            }
            final double spot = data.getSpot();
            final double alpha = getAlpha();
            final double strike = spot * alpha;
            return isCall() ? Math.max(0, spot - strike) : Math.max(0, strike - spot);
        }

    };

    private final Expiry _startTime;
    private final double _percent;
    private final Moneyness _moneyness;
    private final double _alpha;

    public ForwardStartOptionDefinition(final Expiry expiry, final Boolean isCall, final Expiry startTime) {
        this(expiry, isCall, startTime, 1, Moneyness.ATM);
    }

    public ForwardStartOptionDefinition(final Expiry expiry, final Boolean isCall, final Expiry startTime,
            final double percent, final Moneyness moneyness) {
        super(null, expiry, isCall);
        Validate.notNull(startTime);
        ArgumentChecker.notNegative(percent, "percent");
        Validate.notNull(moneyness, "moneyness");
        if (expiry.getExpiry().isBefore(startTime.getExpiry())) {
            throw new IllegalArgumentException("The forward start time must be before the expiry of the option");
        }
        if (moneyness == Moneyness.ATM && percent != 1) {
            s_logger.info("Option is ATM but percentage is not one; ignoring value for percent");
        }
        _startTime = startTime;
        _percent = percent;
        _moneyness = moneyness;
        switch (moneyness) {
        case ITM:
            _alpha = isCall ? 1 - percent : 1 + percent;
            break;
        case OTM:
            _alpha = isCall ? percent + 1 : 1 - percent;
            break;
        case ATM:
            _alpha = 1;
            break;
        default:
            throw new IllegalArgumentException("Can only handle ITM, OTM and ATM");
        }
    }

    public Expiry getStartTime() {
        return _startTime;
    }

    public double getAlpha() {
        return _alpha;
    }

    public double getPercent() {
        return _percent;
    }

    public Moneyness getMoneyness() {
        return _moneyness;
    }

    @Override
    public OptionExerciseFunction<StandardOptionDataBundle> getExerciseFunction() {
        return _exerciseFunction;
    }

    @Override
    public OptionPayoffFunction<StandardOptionDataBundle> getPayoffFunction() {
        return _payoffFunction;
    }

    public double getTimeToStart(final ZonedDateTime date) {
        if (date.isAfter(getStartTime().getExpiry())) {
            throw new IllegalArgumentException("Date " + date + " is after startTime " + getStartTime());
        }
        return DateUtils.getDifferenceInYears(date, getStartTime().getExpiry());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((_moneyness == null) ? 0 : _moneyness.hashCode());
        long temp;
        temp = Double.doubleToLongBits(_percent);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((_startTime == null) ? 0 : _startTime.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ForwardStartOptionDefinition other = (ForwardStartOptionDefinition) obj;
        if (!ObjectUtils.equals(_moneyness, other._moneyness)) {
            return false;
        }
        if (Double.doubleToLongBits(_percent) != Double.doubleToLongBits(other._percent)) {
            return false;
        }
        return ObjectUtils.equals(_startTime, other._startTime);
    }

}