@Override
 public SwaptionCashFixedIbor toDerivative(
     final ZonedDateTime date, final String... yieldCurveNames) {
   Validate.notNull(date, "date");
   Validate.notNull(yieldCurveNames, "yield curve names");
   final DayCount actAct = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA");
   final double expiryTime = actAct.getDayCountFraction(date, _expiry.getExpiry());
   final double settlementTime = actAct.getDayCountFraction(date, _settlementDate);
   final FixedCouponSwap<? extends Payment> underlyingSwap =
       _underlyingSwap.toDerivative(date, yieldCurveNames);
   return SwaptionCashFixedIbor.from(expiryTime, underlyingSwap, settlementTime, _isLong);
 }
 /**
  * @param callStrike The strike of the potential call option
  * @param putStrike The strike of the potential put option
  * @param chooseDate The choice date (expiry) of the chooser option
  * @param callExpiry The expiry date of the potential call option
  * @param putExpiry The expiry date of the potential put option
  */
 public ComplexChooserOptionDefinition(
     final Expiry chooseDate,
     final double callStrike,
     final Expiry callExpiry,
     final double putStrike,
     final Expiry putExpiry) {
   super(null, chooseDate, null);
   Validate.notNull(callExpiry);
   Validate.notNull(putExpiry);
   ArgumentChecker.notNegative(callStrike, "call strike");
   ArgumentChecker.notNegative(putStrike, "put strike");
   if (callExpiry.getExpiry().isBefore(chooseDate.getExpiry())) {
     throw new IllegalArgumentException("Call expiry must be after the choose date");
   }
   if (putExpiry.getExpiry().isBefore(chooseDate.getExpiry())) {
     throw new IllegalArgumentException("Put expiry must be after the choose date");
   }
   _callStrike = callStrike;
   _putStrike = putStrike;
   _callExpiry = callExpiry;
   _putExpiry = putExpiry;
   _callDefinition = new EuropeanVanillaOptionDefinition(callStrike, callExpiry, true);
   _putDefinition = new EuropeanVanillaOptionDefinition(putStrike, putExpiry, false);
 }
 @Test
 public void test() {
   assertEquals(PUT.getPeriodEnd(), PERIOD_END);
   assertFalse(PUT.isReverse());
   ExtremeSpreadOptionDefinition other =
       new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, false);
   assertEquals(other, PUT);
   assertEquals(other.hashCode(), PUT.hashCode());
   other =
       new ExtremeSpreadOptionDefinition(
           EXPIRY, false, new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.15)), false);
   assertFalse(other.equals(PUT));
   other = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, true);
   assertFalse(other.equals(PUT));
   assertEquals(PUT.getTimeFromPeriodEnd(EXPIRY.getExpiry()), 0.725, 0);
   assertEquals(PUT.getTimeFromPeriodEnd(DATE), -0.275, 0);
 }
  // -------------------------------------------------------------------------
  @Override
  protected ManageableSecurity createSecurity(FudgeMsg fieldData) {
    String expiryDate = fieldData.getString(FIELD_FUT_LAST_TRADE_DT);
    String futureTradingHours = fieldData.getString(FIELD_FUT_TRADING_HRS);
    String micExchangeCode = fieldData.getString(FIELD_ID_MIC_PRIM_EXCH);
    String currencyStr = fieldData.getString(FIELD_CRNCY);
    String underlyingTicker = fieldData.getString(FIELD_UNDL_SPOT_TICKER);
    String name = fieldData.getString(FIELD_FUT_LONG_NAME);
    String bbgUnique = fieldData.getString(FIELD_ID_BBG_UNIQUE);
    String marketSector = fieldData.getString(FIELD_MARKET_SECTOR_DES);
    String unitAmount = fieldData.getString(FIELD_FUT_VAL_PT);

    if (!isValidField(bbgUnique)) {
      s_logger.warn("bbgUnique is null, cannot construct EquityFutureSecurity");
      return null;
    }
    if (!isValidField(expiryDate)) {
      s_logger.warn("expiry date is null, cannot construct EquityFutureSecurity");
      return null;
    }
    if (!isValidField(futureTradingHours)) {
      s_logger.warn("futures trading hours is null, cannot construct EquityFutureSecurity");
      return null;
    }
    if (!isValidField(micExchangeCode)) {
      s_logger.warn("settlement exchange is null, cannot construct EquityFutureSecurity");
      return null;
    }
    if (!isValidField(currencyStr)) {
      s_logger.info("currency is null, cannot construct EquityFutureSecurity");
      return null;
    }
    ExternalId underlying = null;
    if (underlyingTicker != null) {
      underlying = SecurityUtils.bloombergTickerSecurityId(underlyingTicker + " " + marketSector);
    }

    Currency currency = Currency.parse(currencyStr);

    Expiry expiry = decodeExpiry(expiryDate, futureTradingHours);
    if (expiry == null) {
      return null;
    }

    // FIXME: Case - treatment of Settlement Date
    s_logger.warn(
        "Creating EquityFutureSecurity - settlementDate set equal to expiryDate. Missing lag.");
    ZonedDateTime settlementDate = expiry.getExpiry();

    EquityFutureSecurity security =
        new EquityFutureSecurity(
            expiry,
            micExchangeCode,
            micExchangeCode,
            currency,
            Double.valueOf(unitAmount),
            settlementDate,
            underlying);

    if (isValidField(name)) {
      security.setName(BloombergDataUtils.removeDuplicateWhiteSpace(name, " "));
    }
    // set identifiers
    parseIdentifiers(fieldData, security);
    return security;
  }