Package com.opengamma.analytics.financial.credit.schedulegeneration

Source Code of com.opengamma.analytics.financial.credit.schedulegeneration.ScheduleUtils

/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.credit.schedulegeneration;

import it.unimi.dsi.fastutil.doubles.DoubleLinkedOpenHashSet;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;

import org.threeten.bp.LocalDate;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.analytics.financial.credit.ISDAYieldCurveAndHazardRateCurveProvider;
import com.opengamma.analytics.financial.credit.creditdefaultswap.definition.vanilla.CreditDefaultSwapDefinition;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.CompareUtils;

/**
* Class containing utility functions associated with schedule generation for credit instruments
*/
public final class ScheduleUtils {

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // TODO : Need to check the logic of calculateWorkday more thoroughly

  // ----------------------------------------------------------------------------------------------------------------------------------------

  private ScheduleUtils() {
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // Function to compute the next business day that is spotDays after baseDate (takes into account we may have e.g. weekends in between working days)

  public static ZonedDateTime calculateWorkday(
      final CreditDefaultSwapDefinition cds,
      final ZonedDateTime baseDate,
      final int spotDays) {

    ArgumentChecker.notNegative(spotDays, "Cash settlement days");

    ZonedDateTime requiredDate = baseDate;

    if (spotDays > 0) {
      int n = 0;

      for (int i = 0; i < spotDays; i++) {

        requiredDate = requiredDate.plusDays(1);

        if (!cds.getCalendar().isWorkingDay(requiredDate.toLocalDate())) {
          n++;
        }
      }

      requiredDate = requiredDate.plusDays(n);

      while (!cds.getCalendar().isWorkingDay(requiredDate.toLocalDate())) {
        requiredDate = requiredDate.plusDays(1);
      }
    }

    return requiredDate;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  public static ZonedDateTime[] getTruncatedTimeLine(final ZonedDateTime[] allDates, final ZonedDateTime startDate, final ZonedDateTime endDate,
      final boolean sorted) {
    ArgumentChecker.notNull(allDates, "all dates");
    ArgumentChecker.notNull(startDate, "start date");
    ArgumentChecker.notNull(endDate, "end date");
    ArgumentChecker.isTrue(startDate.isBefore(endDate), "Start date {} must be before end date {}", startDate, endDate);
    final int n = allDates.length;
    if (n == 0) {
      return new ZonedDateTime[] {startDate, endDate };
    }
    final HashSet<ZonedDateTime> truncated = new LinkedHashSet<>(n + 2, 1);
    final LocalDate startDateAsLocal = startDate.toLocalDate();
    final LocalDate endDateAsLocal = endDate.toLocalDate();
    for (final ZonedDateTime date : allDates) {
      final LocalDate localDate = date.toLocalDate();
      if (!(localDate.isBefore(startDateAsLocal) || localDate.isAfter(endDateAsLocal))) {
        truncated.add(date);
      }
    }
    final int truncatedSize = truncated.size();
    if (truncatedSize == 0) {
      return new ZonedDateTime[] {startDate, endDate };
    }
    final ZonedDateTime[] truncatedArray = truncated.toArray(new ZonedDateTime[truncatedSize]);
    if (!sorted) {
      Arrays.sort(truncatedArray);
    }
    if (truncatedArray[0].equals(startDate)) {
      if (truncatedArray[truncatedSize - 1].equals(endDate)) {
        return truncatedArray;
      }
      final ZonedDateTime[] result = new ZonedDateTime[truncatedSize + 1];
      System.arraycopy(truncatedArray, 0, result, 0, truncatedSize);
      result[truncatedSize] = endDate;
      return result;
    }
    if (truncatedArray[truncatedSize - 1].equals(endDate)) {
      final ZonedDateTime[] result = new ZonedDateTime[truncatedSize + 1];
      System.arraycopy(truncatedArray, 0, result, 1, truncatedSize);
      result[0] = startDate;
      return result;
    }
    final ZonedDateTime[] result = new ZonedDateTime[truncatedSize + 2];
    System.arraycopy(truncatedArray, 0, result, 1, truncatedSize);
    result[0] = startDate;
    result[truncatedSize + 1] = endDate;
    return result;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  public static double[] getTruncatedTimeLine(final double[] allTimes, final double startTime, final double endTime, final boolean sorted,
      final double tolerance) {
    ArgumentChecker.notNull(allTimes, "all dates");
    ArgumentChecker.isTrue(startTime < endTime, "Start time {} must be before end time {}", startTime, endTime);
    final int n = allTimes.length;
    if (n == 0) {
      return new double[] {startTime, endTime };
    }
    final DoubleLinkedOpenHashSet truncated = new DoubleLinkedOpenHashSet(n + 2, 1);
    for (final Double time : allTimes) {
      if (time > startTime && time < endTime) {
        truncated.add(time);
      }
    }
    final int truncatedSize = truncated.size();
    if (truncatedSize == 0) {
      return new double[] {startTime, endTime };
    }
    final double[] truncatedArray = truncated.toDoubleArray();
    if (!sorted) {
      Arrays.sort(truncatedArray);
    }
    if (CompareUtils.closeEquals(truncatedArray[0], startTime, tolerance)) {
      if (CompareUtils.closeEquals(truncatedArray[truncatedSize - 1], endTime, tolerance)) {
        return truncatedArray;
      }
      final double[] result = new double[truncatedSize + 1];
      System.arraycopy(truncatedArray, 0, result, 0, truncatedSize);
      result[truncatedSize] = endTime;
      return result;
    }
    if (CompareUtils.closeEquals(truncatedArray[truncatedSize - 1], endTime, tolerance)) {
      final double[] result = new double[truncatedSize + 1];
      System.arraycopy(truncatedArray, 0, result, 1, truncatedSize);
      result[0] = startTime;
      return result;
    }
    final double[] result = new double[truncatedSize + 2];
    System.arraycopy(truncatedArray, 0, result, 1, truncatedSize);
    result[0] = startTime;
    result[truncatedSize + 1] = endTime;
    return result;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  public static ZonedDateTime[] constructISDACompliantAccruedLegIntegrationSchedule(final ISDAYieldCurveAndHazardRateCurveProvider curves,
      final ZonedDateTime startDate, final ZonedDateTime endDate) {
    final ZonedDateTime[] yieldCurveDates = curves.getYieldCurve().getCurveDates();
    final ZonedDateTime[] hazardCurveDates = curves.getHazardRateCurve().getCurveTenors();
    final int nYieldCurveDates = yieldCurveDates.length;
    final int nHazardCurveDates = hazardCurveDates.length;
    final int total = nYieldCurveDates + nHazardCurveDates;
    final ZonedDateTime[] result = new ZonedDateTime[total];
    System.arraycopy(yieldCurveDates, 0, result, 0, nYieldCurveDates);
    System.arraycopy(hazardCurveDates, 0, result, nYieldCurveDates, nHazardCurveDates);
    return ScheduleUtils.getTruncatedTimeLine(result, startDate, endDate, false);
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------
}
TOP

Related Classes of com.opengamma.analytics.financial.credit.schedulegeneration.ScheduleUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.