/**
   * Calculate the accrued premium at the start of a trade
   *
   * @param premiumLegSchedule
   * @param stepinDate The trade effective date
   * @return accrued premium
   */
  private double calculateAccruedInterest(
      final ISDAPremiumLegSchedule premiumLegSchedule, final LocalDate stepinDate) {

    final int n = premiumLegSchedule.getNumPayments();

    // stepinDate is before first accStart or after last accEnd
    if (!stepinDate.isAfter(premiumLegSchedule.getAccStartDate(0))
        || !stepinDate.isBefore(premiumLegSchedule.getAccEndDate(n - 1))) {
      return 0.0;
    }

    int index = premiumLegSchedule.getAccStartDateIndex(stepinDate);
    if (index >= 0) {
      return 0.0; // on accrual start date
    }

    index = -(index + 1); // binary search notation
    if (index == 0) {
      throw new MathException(
          "Error in calculateAccruedInterest - check logic"); // this should never be hit
    }

    return _accuralDayCount.getDayCountFraction(
        premiumLegSchedule.getAccStartDate(index - 1), stepinDate);
  }
 /**
  * If effective date is present at the swap level, that is the value to use. If the effective date
  * is null, then there must be effective dates defined on the legs. In this case return the
  * minimum value between the two legs.
  *
  * @return effective date for the swap
  */
 public LocalDate getEffectiveDate() {
   if (_effectiveDate != null) {
     return _effectiveDate;
   } else {
     LocalDate leg1 = getPayLeg().getEffectiveDate();
     LocalDate leg2 = getReceiveLeg().getEffectiveDate();
     if (leg1 == null || leg2 == null) {
       throw new OpenGammaRuntimeException("Cannot find effective date on swap or both legs");
     }
     if (leg1.isBefore(leg2)) {
       return leg1;
     } else {
       return leg2;
     }
   }
 }
Exemplo n.º 3
0
  public static void scheduleAll(Context context) {
    String[] projection = {
      DBContract.Medicines._ID,
      DBContract.Medicines.COLUMN_NAME_ALARM,
      DBContract.Medicines.COLUMN_NAME_STARTDATE,
      DBContract.Medicines.COLUMN_NAME_ENDDATE,
      DBContract.Medicines.COLUMN_NAME_RECURRENCE,
      DBContract.Medicines.COLUMN_NAME_SCHEDULE
    };

    String selection = DBContract.Medicines.COLUMN_NAME_ENDDATE + " != ?";
    String[] selectionArgs = {"0"};

    // obtener medicamentos en vigor: fecha fin distinta de cero
    Cursor cursor =
        context
            .getContentResolver()
            .query(
                LembramoContentProvider.CONTENT_URI_MEDICINES,
                projection,
                selection,
                selectionArgs,
                null);

    boolean active, started;
    long idMedicine, endMillis;
    long rangeStartMillis = 0, rangeEndMillis = 0;
    LocalDate startDate, endDate;
    LocalDate now = LocalDate.now();

    while (cursor.moveToNext()) {
      idMedicine = cursor.getLong(cursor.getColumnIndex(DBContract.Medicines._ID));
      startDate =
          TimeUtils.parseDate(
              cursor.getString(cursor.getColumnIndex(DBContract.Medicines.COLUMN_NAME_STARTDATE)));
      endMillis = cursor.getLong(cursor.getColumnIndex(DBContract.Medicines.COLUMN_NAME_ENDDATE));
      endDate = TimeUtils.getDateFromMillis(endMillis);

      // hemos comenzado el tratamiento?
      started = true;
      if (now.isBefore(startDate)) {
        // aun no se ha llegado a la fecha de inicio del tratamiento
        // si queda más de un día no planificamos todavía
        if (Period.between(now, startDate).getDays() > 1) started = false;
      }

      // endMillis != 0 porque lo hemos pedido así en la consulta
      // si endMillis == -1 es tratamiento para siempre
      active = true;
      if (endMillis != -1) {
        // fecha concreta de finalización
        if (now.isAfter(endDate)) {
          active = false;
          setInactive(context, idMedicine);
        }
      }

      if (started && active) {
        String recurrenceRule =
            cursor.getString(cursor.getColumnIndex(DBContract.Medicines.COLUMN_NAME_RECURRENCE));
        String intakeRule =
            cursor.getString(cursor.getColumnIndex(DBContract.Medicines.COLUMN_NAME_SCHEDULE));
        Time dtStart =
            TimeUtils.getTimeDateFromString(
                cursor.getString(
                    cursor.getColumnIndex(DBContract.Medicines.COLUMN_NAME_STARTDATE)));

        // buscar en tabla intakes última planificación
        long last = getLastPlannedIntakeDate(context, idMedicine);
        boolean plan = true;
        if (last == 0) {
          // no hay ninguna planificacion previa, partimos de cero
          rangeStartMillis = TimeUtils.getMillis(startDate);

          if (now.isAfter(startDate))
            // el móvil estuvo apagado, estamos en medio de la planificación
            // pero aún no hubo ninguna. se perdieron intakes
            rangeEndMillis = TimeUtils.getMillis(now.plusDays(1));
          else rangeEndMillis = TimeUtils.getMillis(startDate.plusDays(1));

        } else {
          // hubo planificaciones anteriores
          LocalDate d = TimeUtils.getDateFromMillis(last).plusDays(1);
          if (Period.between(now, d).getDays() > 1) {
            plan = false;
          } else {
            rangeStartMillis = TimeUtils.getMillis(d);
            rangeEndMillis = TimeUtils.getMillis(d.plusDays(1));
          }
        }

        if (plan) {
          long[] days = expand(dtStart, recurrenceRule, rangeStartMillis, rangeEndMillis);
          if (days.length > 0) {
            List<IntakeHelper> dailyIntakes = IntakeUtils.parseDailyIntakes(intakeRule);

            for (long day : days) {
              LocalDate date = TimeUtils.getDateFromMillis(day);
              int max;
              // controlar las que son COUNT
              if ((getDurationType(dtStart, recurrenceRule) == END_BY_COUNT)
                  && (date.isEqual(endDate)))
                max = getNumberOfLastIntakesByCount(dtStart, recurrenceRule, dailyIntakes.size());
              else max = dailyIntakes.size();

              IntakeHelper intake;
              long intakeInstant;
              int i = 0;
              while (i < max) {
                // añadir las tomas de ese día
                intake = dailyIntakes.get(i);
                intakeInstant = TimeUtils.getMillis(date, intake.getTime());
                saveIntake(context, intakeInstant, intake.getDose(), idMedicine);
                i++;
              }
            }
          }
        }
      }
    }
    cursor.close();
  }
  /**
   * This is the present value of the premium leg per unit of fractional spread - hence it is equal
   * to 10,000 times the RPV01 (Risky PV01). The actual PV of the leg is this multiplied by the
   * notional and the fractional spread (i.e. spread in basis points divided by 10,000)
   *
   * <p>This mimics the ISDA c function <b>JpmcdsCdsFeeLegPV</b>
   *
   * @param today The 'current' date
   * @param stepinDate Date when party assumes ownership. This is normally today + 1 (T+1). Aka
   *     assignment date or effective date.
   * @param valueDate The valuation date. The date that values are PVed to. Is is normally today + 3
   *     business days. Aka cash-settle date.
   * @param startDate The protection start date. If protectStart = true, then protections starts at
   *     the beginning of the day, otherwise it is at the end.
   * @param endDate The protection end date (the protection ends at end of day)
   * @param payAccOnDefault Is the accrued premium paid in the event of a default
   * @param tenor The nominal step between premium payments (e.g. 3 months, 6 months).
   * @param stubType stubType Options are FRONTSHORT, FRONTLONG, BACKSHORT, BACKLONG or NONE -
   *     <b>Note</b> in this code NONE is not allowed
   * @param yieldCurve Curve from which payments are discounted
   * @param hazardRateCurve Curve giving survival probability
   * @param protectStart Does protection start at the beginning of the day
   * @param priceType Clean or Dirty price. The clean price removes the accrued premium if the trade
   *     is between payment times.
   * @return 10,000 times the RPV01 (on a notional of 1)
   */
  public double pvPremiumLegPerUnitSpread(
      final LocalDate today,
      final LocalDate stepinDate,
      final LocalDate valueDate,
      final LocalDate startDate,
      final LocalDate endDate,
      final boolean payAccOnDefault,
      final Period tenor,
      final StubType stubType,
      final ISDACompliantDateYieldCurve yieldCurve,
      final ISDACompliantDateCreditCurve hazardRateCurve,
      final boolean protectStart,
      final PriceType priceType) {
    ArgumentChecker.notNull(today, "null today");
    ArgumentChecker.notNull(stepinDate, "null stepinDate");
    ArgumentChecker.notNull(valueDate, "null valueDate");
    ArgumentChecker.notNull(startDate, "null startDate");
    ArgumentChecker.notNull(endDate, "null endDate");
    ArgumentChecker.notNull(tenor, "null tenor");
    ArgumentChecker.notNull(stubType, "null stubType");
    ArgumentChecker.notNull(yieldCurve, "null yieldCurve");
    ArgumentChecker.notNull(hazardRateCurve, "null hazardRateCurve");
    ArgumentChecker.notNull(priceType, "null priceType");
    ArgumentChecker.isFalse(valueDate.isBefore(today), "Require valueDate >= today");
    ArgumentChecker.isFalse(stepinDate.isBefore(today), "Require stepin >= today");

    final ISDAPremiumLegSchedule paymentSchedule =
        new ISDAPremiumLegSchedule(
            startDate,
            endDate,
            tenor,
            stubType,
            _businessdayAdjustmentConvention,
            _calandar,
            protectStart);
    final int nPayments = paymentSchedule.getNumPayments();

    // these are potentially different from startDate and endDate
    final LocalDate globalAccStart = paymentSchedule.getAccStartDate(0);
    final LocalDate golobalAccEnd = paymentSchedule.getAccEndDate(nPayments - 1);

    // TODO this logic could be part of ISDAPremiumLegSchdule
    final LocalDate matDate = protectStart ? golobalAccEnd.minusDays(1) : golobalAccEnd;

    if (today.isAfter(matDate) || stepinDate.isAfter(matDate)) {
      return 0.0; // trade has expired
    }

    final LocalDate[] yieldCurveDates = yieldCurve.getCurveDates();
    final LocalDate[] creditCurveDates = hazardRateCurve.getCurveDates();
    // This is common to the protection leg
    final LocalDate[] integrationSchedule =
        payAccOnDefault
            ? getIntegrationNodesAsDates(
                globalAccStart, golobalAccEnd, yieldCurveDates, creditCurveDates)
            : null;
    final int obsOffset = protectStart ? -1 : 0; // protection start at the beginning or end day

    double rpv01 = 0.0;
    for (int i = 0; i < nPayments; i++) {

      final LocalDate accStart = paymentSchedule.getAccStartDate(i);
      final LocalDate accEnd = paymentSchedule.getAccEndDate(i);
      final LocalDate pay = paymentSchedule.getPaymentDate(i);

      if (!accEnd.isAfter(stepinDate)) {
        continue; // this cashflow has already been realised
      }

      final double[] temp =
          calculateSinglePeriodRPV01(
              today, accStart, accEnd, pay, obsOffset, yieldCurve, hazardRateCurve);
      rpv01 += temp[0];

      if (payAccOnDefault) {
        final LocalDate offsetStepinDate = stepinDate.plusDays(obsOffset);
        final LocalDate offsetAccStartDate = accStart.plusDays(obsOffset);
        final LocalDate offsetAccEndDate = accEnd.plusDays(obsOffset);
        rpv01 +=
            calculateSinglePeriodAccrualOnDefault(
                today,
                offsetStepinDate,
                offsetAccStartDate,
                offsetAccEndDate,
                temp[1],
                yieldCurve,
                hazardRateCurve,
                integrationSchedule);
      }
    }

    // Compute the discount factor discounting the upfront payment made on the cash settlement date
    // back to the valuation date
    final double t = _curveDayCount.getDayCountFraction(today, valueDate);
    final double df = yieldCurve.getDiscountFactor(t);
    rpv01 /= df;

    // Do we want to calculate the clean price (includes the previously accrued portion of the
    // premium)
    if (priceType == PriceType.CLEAN) {
      rpv01 -= calculateAccruedInterest(paymentSchedule, stepinDate);
    }

    return rpv01;
  }
  /**
   * Get the value of the protection leg for unit notional
   *
   * <p>This mimics the ISDA c function <b>JpmcdsCdsContingentLegPV</b>
   *
   * @param today The 'current' date
   * @param stepinDate Date when party assumes ownership. This is normally today + 1 (T+1). Aka
   *     assignment date or effective date.
   * @param valueDate The valuation date. The date that values are PVed to. Is is normally today + 3
   *     business days. Aka cash-settle date.
   * @param startDate The protection start date. If protectStart = true, then protections starts at
   *     the beginning of the day, otherwise it is at the end.
   * @param endDate The protection end date (the protection ends at end of day)
   * @param yieldCurve Curve from which payments are discounted
   * @param hazardRateCurve Curve giving survival probability
   * @param recoveryRate The recovery rate of the protected debt
   * @param protectStart Does protection start at the beginning of the day
   * @return unit notional PV of protection (or contingent) leg
   */
  public double calculateProtectionLeg(
      final LocalDate today,
      final LocalDate stepinDate,
      final LocalDate valueDate,
      final LocalDate startDate,
      final LocalDate endDate,
      final ISDACompliantDateYieldCurve yieldCurve,
      final ISDACompliantDateCreditCurve hazardRateCurve,
      final double recoveryRate,
      final boolean protectStart) {
    ArgumentChecker.notNull(today, "null today");
    ArgumentChecker.notNull(valueDate, "null valueDate");
    ArgumentChecker.notNull(startDate, "null startDate");
    ArgumentChecker.notNull(endDate, "null endDate");
    ArgumentChecker.notNull(yieldCurve, "null yieldCurve");
    ArgumentChecker.notNull(hazardRateCurve, "null hazardRateCurve");
    ArgumentChecker.isInRangeInclusive(0, 1.0, recoveryRate);
    ArgumentChecker.isFalse(valueDate.isBefore(today), "Require valueDate >= today");
    ArgumentChecker.isFalse(stepinDate.isBefore(today), "Require stepin >= today");

    if (recoveryRate == 1.0) {
      return 0.0;
    }

    final LocalDate temp = stepinDate.isAfter(startDate) ? stepinDate : startDate;
    final LocalDate effectiveStartDate = protectStart ? temp.minusDays(1) : temp;

    if (!endDate.isAfter(effectiveStartDate)) {
      return 0.0; // the protection has expired
    }

    final LocalDate[] yieldCurveDates = yieldCurve.getCurveDates();
    final LocalDate[] creditCurveDates = hazardRateCurve.getCurveDates();
    final double[] integrationSchedule =
        ISDACompliantScheduleGenerator.getIntegrationNodesAsTimes(
            today, effectiveStartDate, endDate, yieldCurveDates, creditCurveDates);

    // double s1 = hazardRateCurve.getSurvivalProbability(integrationSchedule[0]);
    // double df1 = yieldCurve.getDiscountFactor(integrationSchedule[0]);

    double ht1 = hazardRateCurve.getRT(integrationSchedule[0]);
    double rt1 = yieldCurve.getRT(integrationSchedule[0]);
    double s1 = Math.exp(-ht1);
    double p1 = Math.exp(-rt1);
    double pv = 0.0;
    final int n = integrationSchedule.length;
    for (int i = 1; i < n; ++i) {

      final double ht0 = ht1;
      final double rt0 = rt1;
      final double p0 = p1;
      final double s0 = s1;

      ht1 = hazardRateCurve.getRT(integrationSchedule[i]);
      rt1 = yieldCurve.getRT(integrationSchedule[i]);
      s1 = Math.exp(-ht1);
      p1 = Math.exp(-rt1);
      final double dht = ht1 - ht0;
      final double drt = rt1 - rt0;
      final double dhrt = dht + drt;

      // this is equivalent to the ISDA code without explicitly calculating the time step - it also
      // handles the limit
      double dPV;
      if (Math.abs(dhrt) < 1e-5) {
        dPV = dht * (1 - dhrt * (0.5 - dhrt / 6)) * p0 * s0;
      } else {
        dPV = dht / dhrt * (p0 * s0 - p1 * s1);
      }

      // *************
      // ISDA code
      // **************
      // final double dt = integrationSchedule[i] - integrationSchedule[i - 1];
      // final double s0 = s1;
      // final double df0 = df1;
      // s1 = hazardRateCurve.getSurvivalProbability(integrationSchedule[i]);
      // df1 = yieldCurve.getDiscountFactor(integrationSchedule[i]);
      // final double hazardRate = Math.log(s0 / s1) / dt;
      // final double interestRate = Math.log(df0 / df1) / dt;
      // pv += (hazardRate / (hazardRate + interestRate)) * (1.0 - Math.exp(-(hazardRate +
      // interestRate) * dt)) * s0 * df0;

      pv += dPV;
    }
    pv *= 1.0 - recoveryRate;
    // System.out.println(pv);

    // Compute the discount factor discounting the upfront payment made on the cash settlement date
    // back to the valuation date
    final double t = _curveDayCount.getDayCountFraction(today, valueDate);
    final double df = yieldCurve.getDiscountFactor(t);
    pv /= df;

    return pv;
  }