ScenarioMarketSurfaceBuilder.java

  1. package org.drip.state.creator;

  2. /*
  3.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  4.  */

  5. /*!
  6.  * Copyright (C) 2020 Lakshmi Krishnamurthy
  7.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  8.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  9.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  10.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  11.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  12.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  13.  *
  14.  *  This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
  15.  *      asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
  16.  *      analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
  17.  *      equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
  18.  *      numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
  19.  *      and computational support.
  20.  *  
  21.  *      https://lakshmidrip.github.io/DROP/
  22.  *  
  23.  *  DROP is composed of three modules:
  24.  *  
  25.  *  - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
  26.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  27.  *  - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
  28.  *
  29.  *  DROP Product Core implements libraries for the following:
  30.  *  - Fixed Income Analytics
  31.  *  - Loan Analytics
  32.  *  - Transaction Cost Analytics
  33.  *
  34.  *  DROP Portfolio Core implements libraries for the following:
  35.  *  - Asset Allocation Analytics
  36.  *  - Asset Liability Management Analytics
  37.  *  - Capital Estimation Analytics
  38.  *  - Exposure Analytics
  39.  *  - Margin Analytics
  40.  *  - XVA Analytics
  41.  *
  42.  *  DROP Computational Core implements libraries for the following:
  43.  *  - Algorithm Support
  44.  *  - Computation Support
  45.  *  - Function Analysis
  46.  *  - Model Validation
  47.  *  - Numerical Analysis
  48.  *  - Numerical Optimizer
  49.  *  - Spline Builder
  50.  *  - Statistical Learning
  51.  *
  52.  *  Documentation for DROP is Spread Over:
  53.  *
  54.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  55.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  56.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  57.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  58.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  59.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  60.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  61.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  62.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  63.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  64.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  65.  *
  66.  *  Licensed under the Apache License, Version 2.0 (the "License");
  67.  *      you may not use this file except in compliance with the License.
  68.  *  
  69.  *  You may obtain a copy of the License at
  70.  *      http://www.apache.org/licenses/LICENSE-2.0
  71.  *  
  72.  *  Unless required by applicable law or agreed to in writing, software
  73.  *      distributed under the License is distributed on an "AS IS" BASIS,
  74.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  75.  *  
  76.  *  See the License for the specific language governing permissions and
  77.  *      limitations under the License.
  78.  */

  79. /**
  80.  * <i>ScenarioMarketSurfaceBuilder</i> implements the construction of the scenario market Node surface using
  81.  * the input option instruments, their quotes, and a wide variety of custom builds.
  82.  *
  83.  *  <br><br>
  84.  *  <ul>
  85.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  86.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  87.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/state/README.md">Latent State Inference and Creation Utilities</a></li>
  88.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/state/creator/README.md">Scenario State Curve/Surface Builders</a></li>
  89.  *  </ul>
  90.  * <br><br>
  91.  *
  92.  * @author Lakshmi Krishnamurthy
  93.  */

  94. public class ScenarioMarketSurfaceBuilder {

  95.     /**
  96.      * Build an Instance of the Market Node Surface using Custom Wire Span and Surface Splines.
  97.      *
  98.      * @param strName Name of the Volatility Surface
  99.      * @param dtStart Start/Epoch Julian Date
  100.      * @param strCurrency Currency
  101.      * @param adblX Array of X Ordinates
  102.      * @param adblY Array of Y Ordinates
  103.      * @param aadblNode Double Array of the Surface Nodes
  104.      * @param scbcWireSpan The Wire Span Segment Customizer
  105.      * @param scbcSurface The Surface Segment Customizer
  106.      *
  107.      * @return Instance of the Market Node Surface
  108.      */

  109.     public static final org.drip.analytics.definition.MarketSurface CustomSplineWireSurface (
  110.         final java.lang.String strName,
  111.         final org.drip.analytics.date.JulianDate dtStart,
  112.         final java.lang.String strCurrency,
  113.         final double[] adblX,
  114.         final double[] adblY,
  115.         final double[][] aadblNode,
  116.         final org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan,
  117.         final org.drip.spline.params.SegmentCustomBuilderControl scbcSurface)
  118.     {
  119.         if (null == dtStart || null == strName || strName.isEmpty() || null == strCurrency ||
  120.             strCurrency.isEmpty() || null == adblX || null == adblY || null == aadblNode || null ==
  121.                 scbcWireSpan || null == scbcSurface)
  122.             return null;

  123.         int iNumX = adblX.length;
  124.         int iNumMaturity = adblY.length;
  125.         int iNumOuterNode = aadblNode.length;

  126.         if (0 == iNumX || 0 == iNumMaturity || iNumX != iNumOuterNode) return null;

  127.         for (int i = 0; i < iNumX; ++i) {
  128.             double[] adblInner = aadblNode[i];

  129.             if (null == adblInner || iNumMaturity != adblInner.length) return null;
  130.         }

  131.         org.drip.spline.params.SegmentCustomBuilderControl[] aSCBCWireSpan = new
  132.             org.drip.spline.params.SegmentCustomBuilderControl[iNumX - 1];

  133.         for (int i = 0; i < iNumX - 1; ++i)
  134.             aSCBCWireSpan[i] = scbcWireSpan;

  135.         java.util.TreeMap<java.lang.Double, org.drip.spline.grid.Span> mapWireSpan = new
  136.             java.util.TreeMap<java.lang.Double, org.drip.spline.grid.Span>();

  137.         for (int i = 0; i < iNumX; ++i) {
  138.             org.drip.spline.stretch.MultiSegmentSequence mssWire =
  139.                 org.drip.spline.stretch.MultiSegmentSequenceBuilder.CreateCalibratedStretchEstimator
  140.                     ("Stretch@" + strName + "@" + org.drip.numerical.common.StringUtil.GUID(), adblY,
  141.                         aadblNode[i], aSCBCWireSpan, null,
  142.                             org.drip.spline.stretch.BoundarySettings.NaturalStandard(),
  143.                                 org.drip.spline.stretch.MultiSegmentSequence.CALIBRATE);

  144.             if (null == mssWire) return null;

  145.             try {
  146.                 mapWireSpan.put (adblX[i], new org.drip.spline.grid.OverlappingStretchSpan (mssWire));
  147.             } catch (java.lang.Exception e) {
  148.                 e.printStackTrace();

  149.                 return null;
  150.             }
  151.         }

  152.         try {
  153.             return new org.drip.state.curve.BasisSplineMarketSurface (dtStart.julian(),
  154.                 org.drip.state.identifier.CustomLabel.Standard (strName), strCurrency, new
  155.                     org.drip.spline.multidimensional.WireSurfaceStretch ("WireSurfaceStretch@" + strName +
  156.                         "@" + org.drip.numerical.common.StringUtil.GUID(), scbcSurface, mapWireSpan));
  157.         } catch (java.lang.Exception e) {
  158.             e.printStackTrace();
  159.         }

  160.         return null;
  161.     }

  162.     /**
  163.      * Construct a Scenario Market Surface off of Cubic Polynomial Wire Spline and Cubic Polynomial Surface
  164.      *  Spline.
  165.      *
  166.      * @param strName Name of the Volatility Surface
  167.      * @param dtStart Start/Epoch Julian Date
  168.      * @param strCurrency Currency
  169.      * @param adblX Array of X Ordinates
  170.      * @param astrTenor Array of Maturity Tenors
  171.      * @param aadblNode Double Array of the Surface Nodes
  172.      *
  173.      * @return Instance of the Market Node Surface
  174.      */

  175.     public static final org.drip.analytics.definition.MarketSurface CubicPolynomialWireSurface (
  176.         final java.lang.String strName,
  177.         final org.drip.analytics.date.JulianDate dtStart,
  178.         final java.lang.String strCurrency,
  179.         final double[] adblX,
  180.         final java.lang.String[] astrTenor,
  181.         final double[][] aadblNode)
  182.     {
  183.         if (null == astrTenor) return null;

  184.         int iNumTenor = astrTenor.length;
  185.         double[] adblY = new double[iNumTenor];
  186.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  187.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  188.         if (0 == iNumTenor) return null;

  189.         for (int i = 0; i < iNumTenor; ++i)
  190.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  191.         try {
  192.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  193.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL, new
  194.                     org.drip.spline.basis.PolynomialFunctionSetParams (4),
  195.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  196.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  197.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL, new
  198.                     org.drip.spline.basis.PolynomialFunctionSetParams (4),
  199.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  200.         } catch (java.lang.Exception e) {
  201.             e.printStackTrace();

  202.             return null;
  203.         }

  204.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  205.             scbcSurface);
  206.     }

  207.     /**
  208.      * Construct a Scenario Market Surface off of Quartic Polynomial Wire Spline and Quartic Polynomial
  209.      *  Surface Spline.
  210.      *
  211.      * @param strName Name of the Volatility Surface
  212.      * @param dtStart Start/Epoch Julian Date
  213.      * @param strCurrency Currency
  214.      * @param adblX Array of X Ordinates
  215.      * @param astrTenor Array of Maturity Tenors
  216.      * @param aadblNode Double Array of the Surface Nodes
  217.      *
  218.      * @return Instance of the Market Node Surface
  219.      */

  220.     public static final org.drip.analytics.definition.MarketSurface QuarticPolynomialWireSurface (
  221.         final java.lang.String strName,
  222.         final org.drip.analytics.date.JulianDate dtStart,
  223.         final java.lang.String strCurrency,
  224.         final double[] adblX,
  225.         final java.lang.String[] astrTenor,
  226.         final double[][] aadblNode)
  227.     {
  228.         if (null == astrTenor) return null;

  229.         int iNumTenor = astrTenor.length;
  230.         double[] adblY = new double[iNumTenor];
  231.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  232.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  233.         if (0 == iNumTenor) return null;

  234.         for (int i = 0; i < iNumTenor; ++i)
  235.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  236.         try {
  237.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  238.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL, new
  239.                     org.drip.spline.basis.PolynomialFunctionSetParams (5),
  240.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  241.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  242.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL, new
  243.                     org.drip.spline.basis.PolynomialFunctionSetParams (5),
  244.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  245.         } catch (java.lang.Exception e) {
  246.             e.printStackTrace();

  247.             return null;
  248.         }

  249.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  250.             scbcSurface);
  251.     }

  252.     /**
  253.      * Construct a Scenario Market Surface off of Kaklis-Pandelis Wire Spline and Kaklis-Pandelis Surface
  254.      *  Spline.
  255.      *
  256.      * @param strName Name of the Volatility Surface
  257.      * @param dtStart Start/Epoch Julian Date
  258.      * @param strCurrency Currency
  259.      * @param adblX Array of X Ordinates
  260.      * @param astrTenor Array of Maturity Tenors
  261.      * @param aadblNode Double Array of the Surface Nodes
  262.      *
  263.      * @return Instance of the Market Node Surface
  264.      */

  265.     public static final org.drip.analytics.definition.MarketSurface KaklisPandelisWireSurface (
  266.         final java.lang.String strName,
  267.         final org.drip.analytics.date.JulianDate dtStart,
  268.         final java.lang.String strCurrency,
  269.         final double[] adblX,
  270.         final java.lang.String[] astrTenor,
  271.         final double[][] aadblNode)
  272.     {
  273.         if (null == astrTenor) return null;

  274.         int iNumTenor = astrTenor.length;
  275.         double[] adblY = new double[iNumTenor];
  276.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  277.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  278.         if (0 == iNumTenor) return null;

  279.         for (int i = 0; i < iNumTenor; ++i)
  280.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  281.         try {
  282.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  283.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KAKLIS_PANDELIS, new
  284.                     org.drip.spline.basis.KaklisPandelisSetParams (2),
  285.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  286.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  287.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KAKLIS_PANDELIS, new
  288.                     org.drip.spline.basis.KaklisPandelisSetParams (2),
  289.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  290.         } catch (java.lang.Exception e) {
  291.             e.printStackTrace();

  292.             return null;
  293.         }

  294.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  295.             scbcSurface);
  296.     }

  297.     /**
  298.      * Construct a Scenario Market Surface off of KLK Hyperbolic Wire Spline and KLK Hyperbolic Surface
  299.      *  Spline.
  300.      *
  301.      * @param strName Name of the Volatility Surface
  302.      * @param dtStart Start/Epoch Julian Date
  303.      * @param strCurrency Currency
  304.      * @param adblX Array of X Ordinates
  305.      * @param astrTenor Array of Maturity Tenors
  306.      * @param aadblNode Double Array of the Surface Nodes
  307.      * @param dblTension The Tension Parameter
  308.      *
  309.      * @return Instance of the Market Node Surface
  310.      */

  311.     public static final org.drip.analytics.definition.MarketSurface KLKHyperbolicWireSurface (
  312.         final java.lang.String strName,
  313.         final org.drip.analytics.date.JulianDate dtStart,
  314.         final java.lang.String strCurrency,
  315.         final double[] adblX,
  316.         final java.lang.String[] astrTenor,
  317.         final double[][] aadblNode,
  318.         final double dblTension)
  319.     {
  320.         if (null == astrTenor) return null;

  321.         int iNumTenor = astrTenor.length;
  322.         double[] adblY = new double[iNumTenor];
  323.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  324.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  325.         if (0 == iNumTenor) return null;

  326.         for (int i = 0; i < iNumTenor; ++i)
  327.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  328.         try {
  329.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  330.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_HYPERBOLIC_TENSION, new
  331.                     org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  332.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  333.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  334.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_HYPERBOLIC_TENSION, new
  335.                     org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  336.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  337.         } catch (java.lang.Exception e) {
  338.             e.printStackTrace();

  339.             return null;
  340.         }

  341.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  342.             scbcSurface);
  343.     }

  344.     /**
  345.      * Construct a Scenario Market Surface off of KLK Rational Linear Wire Spline and KLK Rational Linear
  346.      *  Surface Spline.
  347.      *
  348.      * @param strName Name of the Volatility Surface
  349.      * @param dtStart Start/Epoch Julian Date
  350.      * @param strCurrency Currency
  351.      * @param adblX Array of X Ordinates
  352.      * @param astrTenor Array of Maturity Tenors
  353.      * @param aadblNode Double Array of the Surface Nodes
  354.      * @param dblTension The Tension Parameter
  355.      *
  356.      * @return Instance of the Market Node Surface
  357.      */

  358.     public static final org.drip.analytics.definition.MarketSurface KLKRationalLinearWireSurface (
  359.         final java.lang.String strName,
  360.         final org.drip.analytics.date.JulianDate dtStart,
  361.         final java.lang.String strCurrency,
  362.         final double[] adblX,
  363.         final java.lang.String[] astrTenor,
  364.         final double[][] aadblNode,
  365.         final double dblTension)
  366.     {
  367.         if (null == astrTenor) return null;

  368.         int iNumTenor = astrTenor.length;
  369.         double[] adblY = new double[iNumTenor];
  370.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  371.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  372.         if (0 == iNumTenor) return null;

  373.         for (int i = 0; i < iNumTenor; ++i)
  374.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  375.         try {
  376.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  377.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_RATIONAL_LINEAR_TENSION,
  378.                     new org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  379.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  380.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  381.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_RATIONAL_LINEAR_TENSION,
  382.                     new org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  383.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  384.         } catch (java.lang.Exception e) {
  385.             e.printStackTrace();

  386.             return null;
  387.         }

  388.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  389.             scbcSurface);
  390.     }

  391.     /**
  392.      * Construct a Scenario Market Surface off of KLK Rational Quadratic Wire Spline and KLK Rational
  393.      *  Quadratic Surface Spline.
  394.      *
  395.      * @param strName Name of the Volatility Surface
  396.      * @param dtStart Start/Epoch Julian Date
  397.      * @param strCurrency Currency
  398.      * @param adblX Array of X Ordinates
  399.      * @param astrTenor Array of Maturity Tenors
  400.      * @param aadblNode Double Array of the Surface Nodes
  401.      * @param dblTension The Tension Parameter
  402.      *
  403.      * @return Instance of the Market Node Surface
  404.      */

  405.     public static final org.drip.analytics.definition.MarketSurface KLKRationalQuadraticWireSurface (
  406.         final java.lang.String strName,
  407.         final org.drip.analytics.date.JulianDate dtStart,
  408.         final java.lang.String strCurrency,
  409.         final double[] adblX,
  410.         final java.lang.String[] astrTenor,
  411.         final double[][] aadblNode,
  412.         final double dblTension)
  413.     {
  414.         if (null == astrTenor) return null;

  415.         int iNumTenor = astrTenor.length;
  416.         double[] adblY = new double[iNumTenor];
  417.         org.drip.spline.params.SegmentCustomBuilderControl scbcSurface = null;
  418.         org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan = null;

  419.         if (0 == iNumTenor) return null;

  420.         for (int i = 0; i < iNumTenor; ++i)
  421.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  422.         try {
  423.             scbcWireSpan = new org.drip.spline.params.SegmentCustomBuilderControl
  424.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_RATIONAL_QUADRATIC_TENSION,
  425.                     new org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  426.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);

  427.             scbcSurface = new org.drip.spline.params.SegmentCustomBuilderControl
  428.                 (org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_KLK_RATIONAL_QUADRATIC_TENSION,
  429.                     new org.drip.spline.basis.ExponentialTensionSetParams (dblTension),
  430.                         org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
  431.         } catch (java.lang.Exception e) {
  432.             e.printStackTrace();

  433.             return null;
  434.         }

  435.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  436.             scbcSurface);
  437.     }

  438.     /**
  439.      * Construct a Scenario Market Surface off of Custom Wire Spline and Custom Surface Spline.
  440.      *
  441.      * @param strName Name of the Volatility Surface
  442.      * @param dtStart Start/Epoch Julian Date
  443.      * @param strCurrency Currency
  444.      * @param adblX Array of X Ordinates
  445.      * @param astrTenor Array of Maturity Tenors
  446.      * @param aadblNode Double Array of the Surface Nodes
  447.      * @param scbcWireSpan The Wire Span Segment Customizer
  448.      * @param scbcSurface The Surface Segment Customizer
  449.      *
  450.      * @return Instance of the Market Node Surface
  451.      */

  452.     public static final org.drip.analytics.definition.MarketSurface CustomWireSurface (
  453.         final java.lang.String strName,
  454.         final org.drip.analytics.date.JulianDate dtStart,
  455.         final java.lang.String strCurrency,
  456.         final double[] adblX,
  457.         final java.lang.String[] astrTenor,
  458.         final double[][] aadblNode,
  459.         final org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan,
  460.         final org.drip.spline.params.SegmentCustomBuilderControl scbcSurface)
  461.     {
  462.         if (null == astrTenor) return null;

  463.         int iNumTenor = astrTenor.length;
  464.         double[] adblY = new double[iNumTenor];

  465.         if (0 == iNumTenor) return null;

  466.         for (int i = 0; i < iNumTenor; ++i)
  467.             adblY[i] = dtStart.addTenor (astrTenor[i]).julian();

  468.         return CustomSplineWireSurface (strName, dtStart, strCurrency, adblX, adblY, aadblNode, scbcWireSpan,
  469.             scbcSurface);
  470.     }

  471.     /**
  472.      * Create a Price/Volatility Market Surface Based off of a Single Run using the Heston 1993 Model
  473.      *
  474.      * @param strName Surface Name
  475.      * @param dtStart Epoch/Start Date
  476.      * @param strCurrency Currency
  477.      * @param dblRiskFreeRate Risk-Free Rate
  478.      * @param dblUnderlier The Underlier
  479.      * @param bIsForward TRUE - The Underlier represents the Forward, FALSE - it represents Spot
  480.      * @param dblInitialVolatility Initial Volatility
  481.      * @param adblStrike Array of Strikes
  482.      * @param astrTenor Array of Maturity Tenors
  483.      * @param fphp The Heston Stochastic Volatility Generation Parameters
  484.      * @param bPriceSurface TRUE - Generate the Price Surface; FALSE - Generate the Vol Surface
  485.      * @param scbcWireSpan The Wire Span Segment Customizer
  486.      * @param scbcSurface The Surface Segment Customizer
  487.      *
  488.      * @return Instance of the Market Node Surface
  489.      */

  490.     public static final org.drip.analytics.definition.MarketSurface HestonRunMarketSurface (
  491.         final java.lang.String strName,
  492.         final org.drip.analytics.date.JulianDate dtStart,
  493.         final java.lang.String strCurrency,
  494.         final double dblRiskFreeRate,
  495.         final double dblUnderlier,
  496.         final boolean bIsForward,
  497.         final double dblInitialVolatility,
  498.         final double[] adblStrike,
  499.         final java.lang.String[] astrTenor,
  500.         final org.drip.param.pricer.HestonOptionPricerParams fphp,
  501.         final boolean bPriceSurface,
  502.         final org.drip.spline.params.SegmentCustomBuilderControl scbcWireSpan,
  503.         final org.drip.spline.params.SegmentCustomBuilderControl scbcSurface)
  504.     {
  505.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblRiskFreeRate) ||
  506.             !org.drip.numerical.common.NumberUtil.IsValid (dblUnderlier) ||
  507.                 !org.drip.numerical.common.NumberUtil.IsValid (dblInitialVolatility) || null == adblStrike ||
  508.                     null == astrTenor || null == fphp)
  509.             return null;

  510.         int iStrike = 0;
  511.         int iNumTenor = astrTenor.length;
  512.         int iNumStrike = adblStrike.length;
  513.         double[][] aadblImpliedNode = new double[iNumStrike][iNumTenor];
  514.         org.drip.pricer.option.HestonStochasticVolatilityAlgorithm hsva = null;

  515.         try {
  516.             hsva = new org.drip.pricer.option.HestonStochasticVolatilityAlgorithm (fphp);
  517.         } catch (java.lang.Exception e) {
  518.             e.printStackTrace();

  519.             return null;
  520.         }

  521.         if (0 == iNumTenor || 0 == iNumStrike) return null;

  522.         for (double dblStrike : adblStrike) {
  523.             int iTenor = 0;

  524.             for (java.lang.String strTenor : astrTenor) {
  525.                 try {
  526.                     double dblTimeToExpiry = org.drip.analytics.support.Helper.TenorToYearFraction
  527.                         (strTenor);

  528.                     org.drip.pricer.option.Greeks callGreeks = hsva.greeks (dblStrike, dblTimeToExpiry,
  529.                         dblRiskFreeRate, dblUnderlier, false, bIsForward, dblInitialVolatility);

  530.                     if (null == callGreeks) return null;

  531.                     aadblImpliedNode[iStrike][iTenor++] = bPriceSurface ? callGreeks.price() : new
  532.                         org.drip.pricer.option.BlackScholesAlgorithm().impliedVolatilityFromPrice
  533.                             (dblStrike, dblTimeToExpiry, dblRiskFreeRate, dblUnderlier, false, false,
  534.                                 callGreeks.price());
  535.                 } catch (java.lang.Exception e) {
  536.                     e.printStackTrace();

  537.                     return null;
  538.                 }
  539.             }

  540.             ++iStrike;
  541.         }

  542.         return CustomWireSurface (strName, dtStart, strCurrency, adblStrike, astrTenor, aadblImpliedNode,
  543.             scbcWireSpan, scbcSurface);
  544.     }
  545. }