CSVGrid.java

  1. package org.drip.feed.loader;

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

  78. /**
  79.  * <i>CSVGrid</i> Holds the Outputs of a CSV Parsing Exercise.
  80.  *
  81.  *  <br><br>
  82.  *  <ul>
  83.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  84.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationSupportLibrary.md">Computation Support</a></li>
  85.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/feed/README.md">Load, Transform, and compute Target Metrics across Feeds</a></li>
  86.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/feed/loader/README.md">Reference/Market Data Feed Loader</a></li>
  87.  *  </ul>
  88.  *
  89.  * @author Lakshmi Krishnamurthy
  90.  */

  91. public class CSVGrid {
  92.     private java.lang.String[] _astrHeader = null;
  93.     private java.util.List<java.lang.String[]> _lsastr = null;

  94.     /**
  95.      * Convert the String Element to double. Fall back is NaN.
  96.      *
  97.      * @param strElement String Element
  98.      *
  99.      * @return The Return Value
  100.      */

  101.     public static final double ToDouble (
  102.         final java.lang.String strElement)
  103.     {
  104.         if (null == strElement || strElement.trim().isEmpty()) return java.lang.Double.NaN;

  105.         try {
  106.             return java.lang.Double.parseDouble (strElement);
  107.         } catch (java.lang.Exception e) {
  108.             e.printStackTrace();
  109.         }

  110.         return java.lang.Double.NaN;
  111.     }

  112.     /**
  113.      * Convert the String Element to int. Fall back is MIN_VALUE.
  114.      *
  115.      * @param strElement String Element
  116.      *
  117.      * @return The Return Value
  118.      */

  119.     public static final int ToInteger (
  120.         final java.lang.String strElement)
  121.     {
  122.         if (null == strElement || strElement.trim().isEmpty()) return java.lang.Integer.MIN_VALUE;

  123.         try {
  124.             return java.lang.Integer.parseInt (strElement);
  125.         } catch (java.lang.Exception e) {
  126.             e.printStackTrace();
  127.         }

  128.         return java.lang.Integer.MIN_VALUE;
  129.     }

  130.     /**
  131.      * Convert the String Element to a JulianDate Instance.
  132.      *
  133.      * @param strElement String Element
  134.      *
  135.      * @return The Return Value
  136.      */

  137.     public static final org.drip.analytics.date.JulianDate ToDate (
  138.         final java.lang.String strElement)
  139.     {
  140.         org.drip.analytics.date.JulianDate dt = org.drip.analytics.date.DateUtil.CreateFromDDMMMYYYY
  141.             (strElement.trim());

  142.         if (null != dt || null != (dt = org.drip.analytics.date.DateUtil.MakeJulianFromDDMMMYY (strElement,
  143.             "-")))
  144.             return dt;

  145.         return org.drip.analytics.date.DateUtil.CreateFromMDY (strElement, "-");
  146.     }

  147.     /**
  148.      * Empty CSVGrid Constructor
  149.      */

  150.     public CSVGrid()
  151.     {
  152.     }

  153.     /**
  154.      * Retrieve the Underlying CSV Grid
  155.      *
  156.      * @return The Underlying CSV Field Grid
  157.      */

  158.     public java.util.List<java.lang.String[]> grid()
  159.     {
  160.         return _lsastr;
  161.     }

  162.     /**
  163.      * Retrieve the Size of the Sample Set
  164.      *
  165.      * @return Size of the Sample Set
  166.      */

  167.     public int size()
  168.     {
  169.         return null == _lsastr ? 0 : _lsastr.size();
  170.     }

  171.     /**
  172.      * Set the Column Headers
  173.      *
  174.      * @param astrHeader The Column Headers
  175.      *
  176.      * @return TRUE - Column Headers successfully set
  177.      */

  178.     public boolean setHeader (
  179.         final java.lang.String[] astrHeader)
  180.     {
  181.         if (null == astrHeader || 0 == astrHeader.length) return false;

  182.         _astrHeader = astrHeader;
  183.         return true;
  184.     }

  185.     /**
  186.      * Add a String Array to the Grid
  187.      *
  188.      * @param astr The String Array
  189.      *
  190.      * @return TRUE - The String Array successfully added
  191.      */

  192.     public boolean add (
  193.         final java.lang.String[] astr)
  194.     {
  195.         if (null == astr || 0 == astr.length) return false;

  196.         if (null == _lsastr) _lsastr = new java.util.ArrayList<java.lang.String[]>();

  197.         _lsastr.add (astr);

  198.         return true;
  199.     }

  200.     /**
  201.      * Retrieve the Array of Headers
  202.      *
  203.      * @return The Header Array
  204.      */

  205.     public java.lang.String[] headers()
  206.     {
  207.         return _astrHeader;
  208.     }

  209.     /**
  210.      * Retrieve the Header identified by the Index
  211.      *
  212.      * @param iIndex The Index
  213.      *
  214.      * @return The Header identified by the Index
  215.      */

  216.     public java.lang.String header (
  217.         final int iIndex)
  218.     {
  219.         return null == _astrHeader || _astrHeader.length <= iIndex ? null : _astrHeader[iIndex];
  220.     }

  221.     /**
  222.      *
  223.      * Retrieve the Array of String Values corresponding to the specified Column Index
  224.      *
  225.      * @param iColumn The Column Index
  226.      *
  227.      * @return The Array of Strings
  228.      */

  229.     public java.lang.String[] stringArrayAtColumn (
  230.         final int iColumn)
  231.     {
  232.         if (0 > iColumn) return null;

  233.         int iRow = 0;

  234.         java.lang.String[] astrColumn = new java.lang.String[_lsastr.size()];

  235.         for (java.lang.String[] astr : _lsastr) {
  236.             if (null == astr || astr.length <= iColumn) return null;

  237.             astrColumn[iRow++] = astr[iColumn];
  238.         }

  239.         return astrColumn;
  240.     }

  241.     /**
  242.      * Retrieve the Array of Integer Values corresponding to the specified Column Index
  243.      *
  244.      * @param iColumn The Column Index
  245.      *
  246.      * @return The Array of Integers
  247.      */

  248.     public int[] intArrayAtColumn (
  249.         final int iColumn)
  250.     {
  251.         if (0 > iColumn) return null;

  252.         int iRow = 0;

  253.         int[] ai = new int[_lsastr.size()];

  254.         for (java.lang.String[] astr : _lsastr) {
  255.             if (null == astr || astr.length <= iColumn) return null;

  256.             ai[iRow++] = ToInteger (astr[iColumn]);
  257.         }

  258.         return ai;
  259.     }

  260.     /**
  261.      * Retrieve the Array of Double Values corresponding to the specified Column Index
  262.      *
  263.      * @param iColumn The Column Index
  264.      * @param dblScaler The Scaling Multiplier
  265.      *
  266.      * @return The Array of Doubles
  267.      */

  268.     public double[] doubleArrayAtColumn (
  269.         final int iColumn,
  270.         final double dblScaler)
  271.     {
  272.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblScaler) || 0 > iColumn) return null;

  273.         int iRow = 0;

  274.         double[] adbl = new double[_lsastr.size()];

  275.         for (java.lang.String[] astr : _lsastr) {
  276.             if (null == astr || astr.length <= iColumn) return null;

  277.             adbl[iRow++] = dblScaler * ToDouble (astr[iColumn]);
  278.         }

  279.         return adbl;
  280.     }

  281.     /**
  282.      * Retrieve the Array of Double Values corresponding to the specified Column Index
  283.      *
  284.      * @param iColumn The Column Index
  285.      *
  286.      * @return The Array of Doubles
  287.      */

  288.     public double[] doubleArrayAtColumn (
  289.         final int iColumn)
  290.     {
  291.         return doubleArrayAtColumn (iColumn, 1.);
  292.     }

  293.     /**
  294.      * Retrieve the Array of JulianDate corresponding to the specified Column Index
  295.      *
  296.      * @param iColumn The Column Index
  297.      *
  298.      * @return The Array of JulianDate
  299.      */

  300.     public org.drip.analytics.date.JulianDate[] dateArrayAtColumn (
  301.         final int iColumn)
  302.     {
  303.         if (0 > iColumn) return null;

  304.         int iRow = 0;

  305.         org.drip.analytics.date.JulianDate[] adt = new org.drip.analytics.date.JulianDate[_lsastr.size()];

  306.         for (java.lang.String[] astr : _lsastr) {
  307.             if (null == astr || astr.length <= iColumn) return null;

  308.             adt[iRow++] = ToDate (astr[iColumn]);
  309.         }

  310.         return adt;
  311.     }

  312.     /**
  313.      * Construct a Historical Map of Scaled/Keyed Double
  314.      *
  315.      * @param dblScaler The Scale to be applied
  316.      *
  317.      * @return Historical Map of Scaled/Keyed Double
  318.      */

  319.     public java.util.Map<org.drip.analytics.date.JulianDate, java.util.Map<java.lang.Double,
  320.         java.lang.Double>>
  321.             doubleMap (
  322.                 final double dblScaler)
  323.     {
  324.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblScaler) || null == _lsastr) return null;

  325.         int iNumClose = _lsastr.size();

  326.         if (0 == iNumClose) return null;

  327.         java.lang.String[] astrHeader = _lsastr.get (0);

  328.         int iNumMark = astrHeader.length;
  329.         double adblHeader[] = new double[iNumMark];

  330.         for (int i = 1; i < iNumMark; ++i) {
  331.             if (null == astrHeader[i] || astrHeader[i].isEmpty()) return null;

  332.             double dblHeader = java.lang.Double.NaN;

  333.             java.lang.String strHeader = astrHeader[i].trim();

  334.             if (null == strHeader || strHeader.isEmpty()) return null;

  335.             try {
  336.                 dblHeader = java.lang.Double.parseDouble (strHeader);
  337.             } catch (java.lang.Exception e) {
  338.                 e.printStackTrace();

  339.                 return null;
  340.             }

  341.             if (!org.drip.numerical.common.NumberUtil.IsValid (dblHeader)) return null;

  342.             adblHeader[i] = dblHeader;;
  343.         }

  344.         java.util.Map<org.drip.analytics.date.JulianDate, java.util.Map<java.lang.Double, java.lang.Double>>
  345.             mapClose = new java.util.TreeMap<org.drip.analytics.date.JulianDate,
  346.                 java.util.Map<java.lang.Double, java.lang.Double>>();

  347.         for (int i = 1; i < iNumClose; ++i) {
  348.             java.util.Map<java.lang.Double, java.lang.Double> mapClosingMark = new
  349.                 java.util.TreeMap<java.lang.Double, java.lang.Double>();

  350.             java.lang.String[] astrClosingMark = _lsastr.get (i);

  351.             for (int j = 1; j < iNumMark; ++j) {
  352.                 double dblClosingMark = java.lang.Double.NaN;

  353.                 java.lang.String strClosingMark = null == astrClosingMark[j] || astrClosingMark[j].isEmpty()
  354.                     ? null : astrClosingMark[j].trim();

  355.                 try {
  356.                     if (null != strClosingMark && !strClosingMark.isEmpty())
  357.                         dblClosingMark = java.lang.Double.parseDouble (strClosingMark);
  358.                 } catch (java.lang.Exception e) {
  359.                 }

  360.                 if (org.drip.numerical.common.NumberUtil.IsValid (dblClosingMark))
  361.                     mapClosingMark.put (adblHeader[j], dblScaler * dblClosingMark);
  362.             }

  363.             if (0 != mapClosingMark.size())
  364.                 mapClose.put (org.drip.analytics.date.DateUtil.CreateFromDDMMMYYYY (astrClosingMark[0]),
  365.                     mapClosingMark);
  366.         }

  367.         return mapClose;
  368.     }

  369.     /**
  370.      * Construct a Historical Map of Scaled/Keyed/Tenor Ordered Double
  371.      *
  372.      * @param dblScaler The Scale to be applied
  373.      *
  374.      * @return Historical Map of Scaled/Keyed/Tenor Ordered Double
  375.      */

  376.     public java.util.Map<org.drip.analytics.date.JulianDate, org.drip.feed.loader.InstrumentSetTenorQuote>
  377.         groupedOrderedDouble (
  378.             final double dblScaler)
  379.     {
  380.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblScaler) || null == _lsastr) return null;

  381.         int iNumClose = _lsastr.size();

  382.         if (0 == iNumClose) return null;

  383.         java.lang.String[] astrHeader = _lsastr.get (0);

  384.         int iNumMark = astrHeader.length;
  385.         java.lang.String[] astrTenor = new java.lang.String[iNumMark - 1];
  386.         java.lang.String[] astrInstrument = new java.lang.String[iNumMark - 1];

  387.         for (int i = 1; i < iNumMark; ++i) {
  388.             astrHeader[i].trim();

  389.             if (null == astrHeader[i] || astrHeader[i].isEmpty()) astrHeader[i] = "@:#";

  390.             java.lang.String[] astrInstrumentTenor = org.drip.numerical.common.StringUtil.Split
  391.                 (astrHeader[i].trim(), ":");

  392.             if (null == astrInstrumentTenor || 2 != astrInstrumentTenor.length) return null;

  393.             astrTenor[i - 1] = astrInstrumentTenor[1];
  394.             astrInstrument[i - 1] = astrInstrumentTenor[0];
  395.         }

  396.         java.util.Map<org.drip.analytics.date.JulianDate, org.drip.feed.loader.InstrumentSetTenorQuote>
  397.             mapISTQ = new java.util.TreeMap<org.drip.analytics.date.JulianDate,
  398.                 org.drip.feed.loader.InstrumentSetTenorQuote>();

  399.         for (int i = 1; i < iNumClose; ++i) {
  400.             java.lang.String[] astrClosingMark = _lsastr.get (i);

  401.             org.drip.feed.loader.InstrumentSetTenorQuote istq = new
  402.                 org.drip.feed.loader.InstrumentSetTenorQuote();

  403.             for (int j = 1; j < iNumMark; ++j) {
  404.                 double dblClosingMark = java.lang.Double.NaN;

  405.                 java.lang.String strClosingMark = null == astrClosingMark[j] || astrClosingMark[j].isEmpty()
  406.                     ? null : astrClosingMark[j].trim();

  407.                 try {
  408.                     if (null != strClosingMark && !strClosingMark.isEmpty())
  409.                         dblClosingMark = java.lang.Double.parseDouble (strClosingMark);
  410.                 } catch (java.lang.Exception e) {
  411.                 }

  412.                 istq.add (astrInstrument[j - 1], astrTenor[j - 1], dblClosingMark, dblScaler);
  413.             }

  414.             if (!istq.isEmpty())
  415.                 mapISTQ.put (org.drip.analytics.date.DateUtil.CreateFromDDMMMYYYY (astrClosingMark[0]),
  416.                     istq);
  417.         }

  418.         return mapISTQ;
  419.     }
  420. }