swig+java issues resolved! EquityOption.java provided

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

swig+java issues resolved! EquityOption.java provided

Tito Ingargiola

Hi,

I've finally gotten my java+swig issues worked out largely due to the
gracious help of Guillaume Dru and the patient Richard Gomes - thank
you both for your help!

Since one of my frustrations was not having a substantive java sample
to play with, I include below a mostly complete java version of the
EquityOption program.  Luigi, this could go into the
QuantLib-SWIG/Java/test directory if you feel it's appropriate. I
certainly would have found it handy!

It will require the below patch to be applied to the options.i swig
file as I added-in the Binomial Joshi4 method for swig access.  Also
missing from swig is the MC Longstaff Schwartz method & Finite
Differences for Bermudan options but that seemed a bit involved for
my current level of swig interfaces understanding.  All of the
numbers in the java program match the c++ version except for the MC
Sobol method where I think I've sent wrong initial values to the
ctor. 

Hopefully someone will find it useful if they ever need to access
quantlib functionality from a java app.

Regards,

        Tito.

-----  patch for options.i -----------

--- /home/tingarg/tmp/QuantLib-SWIG-0.8.0/SWIG/options.i    2007-05-21 03:36:53.000000000 -0400
+++ options.i    2007-09-08 18:32:39.000000000 -0400
@@ -394,6 +394,7 @@
 using QuantLib::Trigeorgis;
 using QuantLib::Tian;
 using QuantLib::LeisenReimer;
+using QuantLib::Joshi4;
 typedef boost::shared_ptr<PricingEngine> BinomialVanillaEnginePtr;
 %}
 
@@ -423,6 +424,9 @@
             else if (s == "lr" || s == "leisenreimer")
                 return new BinomialVanillaEnginePtr(
                     new BinomialVanillaEngine<LeisenReimer>(steps));
+            else if (s == "j4" || s == "joshi4")
+                return new BinomialVanillaEnginePtr(
+                    new BinomialVanillaEngine<Joshi4>(steps));
             else
                 QL_FAIL("unknown binomial engine type: "+s);
         }

---------- EquityOption.java ---------------


package test;

import org.quantlib.Actual365Fixed;
import org.quantlib.AmericanExercise;
import org.quantlib.AnalyticEuropeanEngine;
import org.quantlib.BaroneAdesiWhaleyEngine;
import org.quantlib.BermudanExercise;
import org.quantlib.BinomialVanillaEngine;
import org.quantlib.BjerksundStenslandEngine;
import org.quantlib.BlackConstantVol;
import org.quantlib.BlackScholesMertonProcess;
import org.quantlib.BlackVolTermStructureHandle;
import org.quantlib.Date;
import org.quantlib.DateVector;
import org.quantlib.DayCounter;
import org.quantlib.EuropeanExercise;
import org.quantlib.FDAmericanEngine;
import org.quantlib.FDEuropeanEngine;
import org.quantlib.FlatForward;
import org.quantlib.IntegralEngine;
import org.quantlib.MCEuropeanEngine;
import org.quantlib.Month;
import org.quantlib.Option;
import org.quantlib.Payoff;
import org.quantlib.Period;
import org.quantlib.PlainVanillaPayoff;
import org.quantlib.QuoteHandle;
import org.quantlib.Settings;
import org.quantlib.SimpleQuote;
import org.quantlib.StochasticProcess;
import org.quantlib.TimeUnit;
import org.quantlib.VanillaOption;
import org.quantlib.YieldTermStructureHandle;

/**
 * EquityOption Test app - java version of QuantLib/Examples/EquityOption
 * to illustrate use of Quantlib through supplied SWIG interfaces.
 *
 * You need to run this with a correctly set library path and something like:
 *
 * -Djava.library.path=/usr/local/lib
 *
 * @author Tito Ingargiola
 */
public class EquityOption {
   
    static {
        try {System.loadLibrary("QuantLibJNI"); }
        catch (RuntimeException e) { e.printStackTrace(); }
    }
   
    public static void main(String[] args) throws Exception {
        long begin = System.currentTimeMillis();
        System.out.println("");
       
        // our options
        Option.Type type = Option.Type.Put;
        double strike = 40;
        double underlying = 36;
        double riskFreeRate = 0.06;
        double divYield = 0;
        double volatility = 0.2;

        Date todaysDt = new Date(15, Month.May, 1998);
        Date settleDt = new Date(17, Month.May, 1998);
        Settings.instance().setEvaluationDate(todaysDt);

        Date maturityDt = new Date(17, Month.May, 1999);
        DayCounter dayc = new Actual365Fixed();

        System.out.println("Option Type          = "+type);
        System.out.println("Maturity             = "+maturityDt);
        System.out.println("Underlying Price     = "+underlying);
        System.out.println("Strike               = "+strike);
        System.out.println("Risk-free rate       = "+riskFreeRate);
        System.out.println("Dividend yield       = "+divYield);
        System.out.println("Volatility           = "+volatility);
       
        // write column headings
        String fmt = "\n%-35s %-14s %-14s %-14s\n";
        System.out.printf(fmt, "Method", "European", "Bermudan", "American");
       
        DateVector exerciseDates = new DateVector(3);
        for (int i = 1; i <= 4 ; i++) {
            exerciseDates.add
                (settleDt.add( new Period (3*i, TimeUnit.Months ) ) );
        }
 
        EuropeanExercise euroExer = new EuropeanExercise(maturityDt);
        BermudanExercise bermExer = new BermudanExercise(exerciseDates);
        AmericanExercise amerExer = new AmericanExercise(settleDt, maturityDt);

        SimpleQuote under = new SimpleQuote(underlying);
        QuoteHandle underh = new QuoteHandle(under);
       
        // bootstrap the yield/dividend/vol curves
        YieldTermStructureHandle  flatTS = new YieldTermStructureHandle
            (new FlatForward(settleDt,riskFreeRate, dayc));
       
        YieldTermStructureHandle flatDivTS = new YieldTermStructureHandle
            (new FlatForward(settleDt,divYield, dayc));

        BlackVolTermStructureHandle flatVolTS = new BlackVolTermStructureHandle
            (new BlackConstantVol(settleDt,volatility,dayc));
       
        Payoff payoff = new PlainVanillaPayoff(type, strike) ;

        StochasticProcess stochp = new BlackScholesMertonProcess
            (underh,flatDivTS,flatTS,flatVolTS);

        // options
        VanillaOption euroOption = new VanillaOption
            (stochp, payoff,euroExer);
        VanillaOption bermOption = new VanillaOption
            (stochp, payoff,bermExer);
        VanillaOption amerOption = new VanillaOption
            (stochp, payoff,amerExer);
 
        // Analytic formulas:

        // Black-Scholes for European
        String method = "Black-Scholes";
        euroOption.setPricingEngine(new AnalyticEuropeanEngine());
        fmt = "%-35s %-14f %-14s %-14s\n";
        System.out.printf(fmt, method, euroOption.NPV(), "N/A", "N/A");
       
        // Barone-Adesi and Whaley approximation for American
        method = "Barone-Adesi/Whaley";
        amerOption.setPricingEngine(new BaroneAdesiWhaleyEngine());
        fmt = "%-35s %-14s %-14s %-14f\n";
        System.out.printf(fmt, method, "N/A", "N/A", amerOption.NPV() );

        // Bjerksund and Stensland approximation for American
        method = "Bjerksund/Stensland";
        amerOption.setPricingEngine(new BjerksundStenslandEngine());
        System.out.printf(fmt, method, "N/A", "N/A", amerOption.NPV() );

        // Integral
        method = "Integral";
        euroOption.setPricingEngine(new IntegralEngine());
        fmt = "%-35s %-14f %-14s %-14s\n";
        System.out.printf(fmt, method, euroOption.NPV(), "N/A", "N/A");

        // Finite differences
        int timeSteps = 801;
        method = "Finite differences";
        euroOption.setPricingEngine
            (new FDEuropeanEngine(timeSteps,timeSteps-1));
        //bermOption.setPricingEngine          // TODO
            //(new FDBermudanEngine(timeSteps,timeSteps-1));   
        amerOption.setPricingEngine
            (new FDAmericanEngine(timeSteps,timeSteps-1));
        fmt = "%-35s %-14f %-14s %-14f\n";
        System.out.printf
            (fmt, method, euroOption.NPV(), "TODO", amerOption.NPV());

        // Binomial method
        method = "Binomial Jarrow-Rudd";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("jarrowrudd", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("jarrowrudd", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("jarrowrudd", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
          (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());
       
        method = "Binomial Cox-Ross-Rubinstein";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("crr", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("crr", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("crr", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
          (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());

        method = "Additive equiprobabilities";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("eqp", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("eqp", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("eqp", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
          (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());

        method = "Binomial Trigeorgis";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("trigeorgis", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("trigeorgis", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("trigeorgis", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
      (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());
       
        method = "Binomial Tian";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("tian", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("tian", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("tian", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
      (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());
       
        method = "Binomial Leisen-Reimer";
        euroOption.setPricingEngine
          (new BinomialVanillaEngine("leisenreimer", timeSteps));
        bermOption.setPricingEngine
      (new BinomialVanillaEngine("leisenreimer", timeSteps));
        amerOption.setPricingEngine
      (new BinomialVanillaEngine("leisenreimer", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
      (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());

        method = "Binomial Joshi";
        euroOption.setPricingEngine
            (new BinomialVanillaEngine("joshi4", timeSteps));
        bermOption.setPricingEngine
            (new BinomialVanillaEngine("joshi4", timeSteps));
        amerOption.setPricingEngine
            (new BinomialVanillaEngine("joshi4", timeSteps));
        fmt = "%-35s %-14f %-14f %-14f\n";
        System.out.printf
      (fmt, method, euroOption.NPV(), bermOption.NPV(), amerOption.NPV());
       
        // Monte Carlo Method
        timeSteps = 1;
        method = "MC (crude)";
        int mcSeed = 42;
        int nSamples = 32768; // 2^15
        int maxSamples = 1048576; // 2^20
        euroOption.setPricingEngine
          (new MCEuropeanEngine("pseudorandom", timeSteps, 252,
            false, false, false, nSamples, 0.02, maxSamples, mcSeed));
        fmt = "%-35s %-14f %-14s %-14s\n";
        System.out.printf(fmt, method, euroOption.NPV(), "N/A", "N/A");
       
        method = "MC (Sobol)";
        euroOption.setPricingEngine // my defaults seem a bit off
          (new MCEuropeanEngine("lowdiscrepancy", timeSteps, 252,
            false, false, false, nSamples, 0.02, maxSamples, mcSeed));
        fmt = "%-35s %-14f %-14s %-14s\n";
        System.out.printf(fmt, method, euroOption.NPV(), "N/A", "N/A");

        method = "MC (Longstaff Schwartz)";
        fmt = "%-35s %-14s %-14s %-14s\n";
        System.out.printf(fmt, method, "N/A", "N/A", "TODO");
       
        long msecs = (System.currentTimeMillis()-begin);
        System.out.println("Run completed in "+msecs+" ms.");
       
    }
}




-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users