/*
Copyright (C) 2008 Praneet Tiwari

This source code is release under the BSD License.

This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/

JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license.  You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.

JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
 */

/*
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
 Copyright (C) 2006 Ferdinando Ametrano
 Copyright (C) 2007, 2008 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
 */

package org.jquantlib.instruments;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.cashflow.CashFlow;
import org.jquantlib.cashflow.CashFlows;
import org.jquantlib.cashflow.Leg;
import org.jquantlib.math.Constants;
import org.jquantlib.pricingengines.GenericEngine;
import org.jquantlib.pricingengines.PricingEngine;
import org.jquantlib.time.Date;

/**
 * Interest rate swap
 * 

* The cash flows belonging to the first leg are paid; the ones belonging to the second leg are received. * * @category instruments * * @author Praneet Tiwari */ public class Swap extends Instrument { protected List legs; protected double[] payer; protected double[] legNPV; protected double[] legBPS; // // public constructors // public Swap(final Leg firstLeg, final Leg secondLeg) { if (System.getProperty("EXPERIMENTAL") == null) { throw new UnsupportedOperationException("Work in progress"); } this.legs = new ArrayList(); this.payer = new double[2]; this.legNPV = new double[2]; this.legBPS = new double[2]; legs.add(firstLeg); legs.add(secondLeg); payer[0] = -1.0; payer[1] = +1.0; for (int i = 0; i < legs.size(); i++) { for (final CashFlow item : legs.get(i)) { item.addObserver(this); } } } public Swap(final List legs, final boolean[] payer) { if (System.getProperty("EXPERIMENTAL") == null) { throw new UnsupportedOperationException("Work in progress"); } this.legs = legs; this.payer = new double[legs.size()]; Arrays.fill(this.payer, 1.0); this.legNPV = new double[legs.size()]; this.legBPS = new double[legs.size()]; for (int j = 0; j < this.legs.size(); j++) { if (payer[j]) { this.payer[j] = -1.0; } for (int i = 0; i < legs.size(); i++) { for (final CashFlow item : legs.get(i)) { item.addObserver(this); } } } } // // protected constructors // protected Swap(final int legs) { if (System.getProperty("EXPERIMENTAL") == null) { throw new UnsupportedOperationException("Work in progress"); } this.legs = new ArrayList(); this.payer = new double[legs]; this.legNPV = new double[legs]; this.legBPS = new double[legs]; } // // public methods // public Date startDate() /* @ReadOnly */ { QL.require(legs.size() > 0 , "no legs given"); // TODO: message Date d = CashFlows.getInstance().startDate(this.legs.get(0)); for (int j = 1; j < this.legs.size(); j++) { d = Date.min(d, CashFlows.getInstance().startDate(this.legs.get(j))); } return d; } public Date maturityDate() /* @ReadOnly */ { QL.require(legs.size() > 0 , "no legs given"); // TODO: message Date d = CashFlows.getInstance().maturityDate(this.legs.get(0)); for (int j = 1; j < this.legs.size(); j++) { d = Date.max(d, CashFlows.getInstance().maturityDate(this.legs.get(j))); } return d; } // // overrides Instrument // @Override public boolean isExpired() /* @ReadOnly */ { final Date today = new Settings().evaluationDate(); for (int i = 0; i < legs.size(); i++) { for (final CashFlow item : legs.get(i)) { if (!item.hasOccurred(today)) { return false; } } } return true; } @Override protected void setupExpired() /* @ReadOnly */ { super.setupExpired(); Arrays.fill(legBPS, 0.0); Arrays.fill(legNPV, 0.0); } @Override public void setupArguments(final PricingEngine.Arguments arguments) /* @ReadOnly */ { final Swap.ArgumentsImpl a = (Swap.ArgumentsImpl)arguments; a.legs = legs; a.payer = payer; } @Override public void fetchResults(final PricingEngine.Results results) /* @ReadOnly */ { super.fetchResults(results); final Swap.ResultsImpl r = (Swap.ResultsImpl)results; if (r.legNPV.length > 0) { QL.require(r.legNPV.length == legNPV.length , "wrong number of leg NPV returned"); // TODO: message legNPV = r.legNPV; } else { Arrays.fill(legNPV, Constants.NULL_REAL); } if (r.legBPS.length > 0) { QL.require(r.legBPS.length == legBPS.length , "wrong number of leg BPS returned"); // TODO: message legBPS = r.legBPS; } else { Arrays.fill(legBPS, Constants.NULL_REAL); } } // // public inner interfaces // /** * Basic swap arguments * * @author Richard Gomes */ public interface Arguments extends Instrument.Arguments { /* marking interface */ } /** * Basic swap results * * @author Richard Gomes */ public interface Results extends Instrument.Results { /* marking interface */ } // // public inner classes // static public class ArgumentsImpl implements Swap.Arguments { public List legs; public double[] payer; @Override public void validate() /* @ReadOnly */ { QL.require(legs.size() == payer.length , "number of legs and multipliers differ"); // TODO: message } } static public class ResultsImpl extends Instrument.ResultsImpl implements Swap.Results { public double[] legNPV; public double[] legBPS; @Override public void reset() { super.reset(); if (legNPV != null) { Arrays.fill(legNPV, 0.0); } if (legBPS != null) { Arrays.fill(legBPS, 0.0); } } } static public class EngineImpl extends GenericEngine { protected EngineImpl() { super(new ArgumentsImpl(), new ResultsImpl()); } @Override public void calculate() /* @ReadOnly */ { // nothing } } }

Ads help maintain this website.