/*
 Copyright (C) 2008 Srinivas Hasti
 Copyright (C) 2008 Tim Swetonic

 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) 2001, 2002, 2003 Sadruddin Rejeb
 Copyright (C) 2005 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.methods.lattices;

import java.util.Vector;

import org.jquantlib.processes.StochasticProcess1D;
import org.jquantlib.time.TimeGrid;

/**
 * Recombining trinomial tree class
 * 

* This class defines a recombining trinomial tree approximating a 1-D stochastic process. * * @warning The diffusion term of the SDE must be independent of the underlying process. * * @category lattices * * @author Srinivas Hasti * @author Tim Swetonic */ //TODO: http://bugs.jquantlib.org/view.php?id=394 public class TrinomialTree extends Tree { public static final Branches branches = Branches.TRINOMIAL; protected Vector branchings_ = new Vector(); protected double x0_; protected Vector dx_ = new Vector(); protected TimeGrid timeGrid_; public TrinomialTree(final StochasticProcess1D process, final TimeGrid timeGrid) { this(process, timeGrid, false); } public TrinomialTree(final StochasticProcess1D process, final TimeGrid timeGrid, final boolean isPositive) { super(timeGrid.size()); dx_.add(new Double(1)); dx_.add(new Double(0.0)); timeGrid_ = timeGrid; x0_ = process.x0(); final int nTimeSteps = timeGrid.size() - 1; Integer jMin = 0; Integer jMax = 0; for (int i = 0; i < nTimeSteps; i++) { final double t = timeGrid.at(i); final double dt = timeGrid.dt(i); // Variance must be independent of x final double v2 = process.variance(t, 0.0, dt); /* Volatility */final double v = Math.sqrt(v2); dx_.add(v * Math.sqrt(3.0)); final Branching branching = new Branching(); for (int j = jMin; j <= jMax; j++) { final double x = x0_ + j * dx_.get(i); final double m = process.expectation(t, x, dt); int temp = (int) Math.floor((m - x0_) / dx_.get(i + 1) + 0.5); if (isPositive) { while (x0_ + (temp - 1) * dx_.get(i + 1) <= 0) { temp++; } } final double e = m - (x0_ + temp * dx_.get(i + 1)); final double e2 = e * e; final double e3 = e * Math.sqrt(3.0); final double p1 = (1.0 + e2 / v2 - e3 / v) / 6.0; final double p2 = (2.0 - e2 / v2) / 3.0; final double p3 = (1.0 + e2 / v2 + e3 / v) / 6.0; branching.add(temp, p1, p2, p3); } branchings_.add(branching); jMin = branching.jMin(); jMax = branching.jMax(); } } public double dx(final int i) { return dx_.get(i).doubleValue(); } public TimeGrid timeGrid() { return timeGrid_; } @Override public int size(final int i) { return i == 0 ? 1 : branchings_.get(i - 1).size(); } @Override public double underlying(final int i, final int index) { if (i == 0) return x0_; else return x0_ + (branchings_.get(i - 1).jMin() + (double) (index)) * dx(i); } @Override public int descendant(final int i, final int index, final int branch) { return branchings_.get(i).descendant(index, branch); } @Override public double probability(final int i, final int index, final int branch) { return branchings_.get(i).probability(index, branch); } private static class Branching { private final Vector k_ = new Vector(); private final Vector> probs_ = new Vector>(3); private int kMin_, jMin_, kMax_, jMax_; public Branching() { kMin_ = Integer.MAX_VALUE; jMin_ = Integer.MAX_VALUE; kMax_ = Integer.MIN_VALUE; jMax_ = Integer.MIN_VALUE; } public int descendant(final int index, final int branch) { return k_.elementAt(index) - jMin_ - 1 + branch; } public double probability(final int index, final int branch) { return probs_.elementAt(branch).elementAt(index); } public int size() { return jMax_ - jMin_ + 1; } public int jMin() { return jMin_; } public int jMax() { return jMax_; } public void add(final int k, final double p1, final double p2, final double p3) { // store k_.add(k); final Vector v1 = new Vector(); final Vector v2 = new Vector(); final Vector v3 = new Vector(); v1.add(new Double(p1)); v2.add(new Double(p2)); v3.add(new Double(p3)); probs_.add(v1); probs_.add(v2); probs_.add(v3); // maintain invariants kMin_ = Math.min(kMin_, k); jMin_ = kMin_ - 1; kMax_ = Math.max(kMax_, k); jMax_ = kMax_ + 1; } } }

Ads help maintain this website.