Package com.barchart.feed.ddf.market.provider

Source Code of com.barchart.feed.ddf.market.provider.MapperDDF

/**
* Copyright (C) 2011-2012 Barchart, Inc. <http://www.barchart.com/>
*
* All rights reserved. Licensed under the OSI BSD License.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package com.barchart.feed.ddf.market.provider;

import static com.barchart.feed.base.bar.enums.MarketBarType.CURRENT;
import static com.barchart.feed.base.bar.enums.MarketBarType.PREVIOUS;
import static com.barchart.feed.base.book.api.MarketBook.ENTRY_TOP;
import static com.barchart.feed.base.book.enums.MarketBookAction.MODIFY;
import static com.barchart.feed.ddf.message.provider.DDF_MessageService.isClear;
import static com.barchart.feed.ddf.message.provider.DDF_MessageService.isEmpty;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.barchart.feed.api.model.data.Book;
import com.barchart.feed.api.model.data.Market.Component;
import com.barchart.feed.base.bar.api.MarketDoBar;
import com.barchart.feed.base.bar.enums.MarketBarField;
import com.barchart.feed.base.bar.enums.MarketBarType;
import com.barchart.feed.base.book.api.MarketBook;
import com.barchart.feed.base.book.api.MarketBookTop;
import com.barchart.feed.base.book.api.MarketDoBookEntry;
import com.barchart.feed.base.book.enums.MarketBookAction;
import com.barchart.feed.base.cuvol.api.MarketDoCuvolEntry;
import com.barchart.feed.base.market.api.MarketDo;
import com.barchart.feed.base.market.enums.MarketField;
import com.barchart.feed.base.provider.DefBookEntry;
import com.barchart.feed.base.state.enums.MarketStateEntry;
import com.barchart.feed.base.trade.enums.MarketTradeSession;
import com.barchart.feed.base.values.api.PriceValue;
import com.barchart.feed.base.values.api.SizeValue;
import com.barchart.feed.base.values.api.TextValue;
import com.barchart.feed.base.values.api.TimeValue;
import com.barchart.feed.base.values.provider.ValueConst;
import com.barchart.feed.ddf.message.api.DDF_ControlResponse;
import com.barchart.feed.ddf.message.api.DDF_ControlTimestamp;
import com.barchart.feed.ddf.message.api.DDF_EOD_Commodity;
import com.barchart.feed.ddf.message.api.DDF_EOD_EquityForex;
import com.barchart.feed.ddf.message.api.DDF_MarketBook;
import com.barchart.feed.ddf.message.api.DDF_MarketBookTop;
import com.barchart.feed.ddf.message.api.DDF_MarketCondition;
import com.barchart.feed.ddf.message.api.DDF_MarketCuvol;
import com.barchart.feed.ddf.message.api.DDF_MarketParameter;
import com.barchart.feed.ddf.message.api.DDF_MarketQuote;
import com.barchart.feed.ddf.message.api.DDF_MarketSession;
import com.barchart.feed.ddf.message.api.DDF_MarketSnapshot;
import com.barchart.feed.ddf.message.api.DDF_MarketTrade;
import com.barchart.feed.ddf.message.api.DDF_MessageVisitor;
import com.barchart.feed.ddf.message.api.DDF_Prior_IndividCmdy;
import com.barchart.feed.ddf.message.enums.DDF_Condition;
import com.barchart.feed.ddf.message.enums.DDF_Indicator;
import com.barchart.feed.ddf.message.enums.DDF_MessageType;
import com.barchart.feed.ddf.message.enums.DDF_ParamType;
import com.barchart.feed.ddf.message.enums.DDF_QuoteMode;
import com.barchart.feed.ddf.message.enums.DDF_QuoteState;
import com.barchart.feed.ddf.message.enums.DDF_Session;
import com.barchart.feed.ddf.message.enums.DDF_TradeDay;
import com.barchart.util.common.anno.ThreadSafe;

// TODO: Auto-generated Javadoc
@ThreadSafe
class MapperDDF implements DDF_MessageVisitor<Void, MarketDo> {

  protected final Logger log = LoggerFactory.getLogger(getClass());

  @Override
  public Void visit(final DDF_ControlResponse message, final MarketDo market) {
    // not used
    return null;
  }

  @Override
  public Void visit(final DDF_ControlTimestamp message, final MarketDo market) {
    // not used
    return null;
  }

  @Override
  public Void visit(final DDF_MarketBook message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.BOOK_COMBINED);
   
    final MarketDoBookEntry[] entries = message.entries();

    final TimeValue time = message.getTime();

    market.setBookSnapshot(entries, time);
   
    return null;
  }

  @Override
  public Void visit(final DDF_MarketBookTop message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.BOOK_COMBINED);
   
    final TimeValue time = message.getTime();

    applyTop(message.entry(market.instrument(), Book.Side.BID), time, market);

    applyTop(message.entry(market.instrument(), Book.Side.ASK), time, market);

    return null;
  }

  @Override
  public Void visit(final DDF_MarketCondition message, final MarketDo market) {
    log.error("TODO : \n{}", message);
    return null;
  }

  @Override
  public Void visit(final DDF_MarketCuvol message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.CUVOL);
   
    final MarketDoCuvolEntry[] entries = message.entries();

    final TimeValue time = message.getTime();

    market.setCuvolSnapshot(entries, time);
   
    return null;
  }

  @Override
  public Void visit(final DDF_MarketParameter message, final MarketDo market) {

    final DDF_ParamType param = message.getParamType();

    final TimeValue time = message.getTime();
    final TimeValue date = message.getTradeDay().tradeDate();

    final DDF_ParamType.Kind kind = param.kind;

    final PriceValue price;
    final SizeValue size;

    switch (kind) {
    default:
     
    case SIZE:
      price = ValueConst.NULL_PRICE;
      size = message.getAsSize();
      break;
    case PRICE:
      price = message.getAsPrice();
      size = ValueConst.NULL_SIZE;
      break;
    }

    final DDF_Session ddfSession = message.getSession();
   
    //

    final MarketBookTop top = market.get(MarketField.BOOK_TOP);
    final MarketDoBar barCurrent = market.loadBar(CURRENT.field);
    final MarketDoBar barPrevious = market.loadBar(PREVIOUS.field);

    //
    switch (param) {
   
    case TRADE_ASK_PRICE:  // NEW
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.TRADE);
     
      log.debug("Mapper saw TRADE_ASK_PRICE - Price=" + price.toString() +
          " " + message.getSession() + " " + message.getTradeDay().toString() + " "
          + message.getInstrument().symbol());
     
      market.setTrade(ddfSession.type, ddfSession.session,
          ddfSession.sequencing, price, size, time, date);

      return null;
     
    case TRADE_BID_PRICE:  // NEW
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.TRADE);
     
      log.debug("Mapper saw TRADE_BID_PRICE - Price=" + price.toString() +
          " " + message.getSession() + " " + message.getTradeDay().toString() + " "
          + message.getInstrument().symbol());
     
      market.setTrade(ddfSession.type, ddfSession.session,
          ddfSession.sequencing, price, size, time, date);
     
      return null;
   
    case TRADE_LAST_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.TRADE);
     
      market.setTrade(ddfSession.type, ddfSession.session,
          ddfSession.sequencing, price, size, time, date);
     
      return null;
     
    case ASK_LAST: // NEW
     
      log.debug("Mapper saw ASK_LAST - Price=" + price.toString() +
          " " + message.getSession() + " " + message.getTradeDay().toString() + " "
          + message.getInstrument().symbol());
     
    case ASK_LAST_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.BOOK_COMBINED);
     
      final DefBookEntry topAskPrice = new DefBookEntry(
          MODIFY, Book.Side.ASK,
          Book.Type.DEFAULT, ENTRY_TOP, price, top.side(Book.Side.ASK).sizeValue());
      applyTop(topAskPrice, time, market);
     
      return null;

    case ASK_LAST_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.BOOK_COMBINED);
     
      final DefBookEntry topAskSize = new DefBookEntry(
          MODIFY, Book.Side.ASK,
          Book.Type.DEFAULT, ENTRY_TOP, top.side(Book.Side.ASK).priceValue(), size);
      applyTop(topAskSize, time, market);
     
      return null;

    case BID_LAST: // NEW
      log.debug("Mapper saw BID_LAST - Price=" + price.toString() +
          " " + message.getSession() + " " + message.getTradeDay().toString() + " "
          + message.getInstrument().symbol());
     
    case BID_LAST_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.BOOK_COMBINED);
     
      final DefBookEntry topBidPrice = new DefBookEntry(
          MODIFY, Book.Side.BID,
          Book.Type.DEFAULT, ENTRY_TOP, price, top.side(Book.Side.BID).sizeValue());
      applyTop(topBidPrice, time, market);
     
      return null;

    case BID_LAST_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.BOOK_COMBINED);
     
      final DefBookEntry topBidSize = new DefBookEntry(
          MODIFY, Book.Side.BID,
          Book.Type.DEFAULT, ENTRY_TOP, top.side(Book.Side.BID).priceValue(), size);
      applyTop(topBidSize, time, market);
     
      return null;

    case CLOSE_LAST: // NEW
    case CLOSE_2_LAST: // NEW
    case CLOSE_ASK_PRICE:
    case CLOSE_BID_PRICE:
    case CLOSE_2_ASK_PRICE:
    case CLOSE_2_BID_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      barCurrent.set(MarketBarField.CLOSE, price);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    case HIGH_LAST_PRICE:
    case HIGH_BID_PRICE:
    case YEAR_HIGH_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      barCurrent.set(MarketBarField.HIGH, price);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    case LOW_LAST_PRICE:
    case LOW_ASK_PRICE:
    case YEAR_LOW_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      barCurrent.set(MarketBarField.LOW, price);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    case VOLUME_LAST_SIZE:
      // TODO
      break;

    case VOLUME_PAST_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_PREVIOUS);
     
      barPrevious.set(MarketBarField.VOLUME, size);
      barPrevious.set(MarketBarField.BAR_TIME, time);
      market.setBar(PREVIOUS, barPrevious);
     
      return null;

    case VOLUME_THIS_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      barCurrent.set(MarketBarField.VOLUME, size);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    case OPEN_LAST_PRICE:
    case OPEN_ASK_PRICE:
    case OPEN_BID_PRICE:
    case OPEN_2_LAST_PRICE:
    case OPEN_2_ASK_PRICE:
    case OPEN_2_BID_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      //
      barCurrent.set(MarketBarField.OPEN, price);
      barCurrent.set(MarketBarField.HIGH, price);
      barCurrent.set(MarketBarField.LOW, price);
      barCurrent.set(MarketBarField.CLOSE, price);
      barCurrent.set(MarketBarField.INTEREST, size);
      barCurrent.set(MarketBarField.VOLUME, size);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
      //
      market.setState(MarketStateEntry.IS_SETTLED, false);
      //
     
      return null;

    case INTEREST_LAST_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      barCurrent.set(MarketBarField.INTEREST, size);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    case INTEREST_PAST_SIZE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_PREVIOUS);
     
      barPrevious.set(MarketBarField.INTEREST, size);
      barPrevious.set(MarketBarField.BAR_TIME, time);
      market.setBar(PREVIOUS, barPrevious);

      return null;

    case PREVIOUS_LAST_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_PREVIOUS);
     
      barPrevious.set(MarketBarField.CLOSE, price);
      barPrevious.set(MarketBarField.BAR_TIME, time);
      market.setBar(PREVIOUS, barPrevious);
     
      return null;

      /** only "final" sets the flag */
    case SETTLE_FINAL_PRICE:
      //log.debug("Set State IS_SETTLED true inside VISIT MARKET PARAMETER, SETTLE_FINAL_PRICE");
      market.setState(MarketStateEntry.IS_SETTLED, true);
      /** falls through */

      /** "early" does NOT set the flag */
    case SETTLE_EARLY_PRICE:
     
      /* Update changed comonents */
      market.clearChanges();
      market.setChange(Component.DEFAULT_CURRENT);
     
      //log.debug("Set prelim settle value but not IS_SETTLED flag inside VISIT MARKET PARAMETER, SETTLE_EARLY_PRICE");
      barCurrent.set(MarketBarField.SETTLE, price);
      barCurrent.set(MarketBarField.BAR_TIME, time);
      market.setBar(CURRENT, barCurrent);
     
      return null;

    default:
      break;
    }

    log.debug("@@@ TODO : {} \n{}", param, message.getTime().toString() + " " + message);

    return null;

  }

  /**
   * via feed XQ snapshot or web URL lookup.
   *
   * @param message
   *            the message
   * @param market
   *            the market
   * @return the void
   */
  @Override
  public Void visit(final DDF_MarketQuote message, final MarketDo market) {

    market.clearChanges();
    // ### process quote

    // TODO part of instrument; should update definition?
    final TextValue symbolName = message.getSymbolName();
    final PriceValue priceStep = message.getPriceStep();
    final PriceValue pointValue = message.getPointValue();

    // TODO add more complete flag support?
    final DDF_Condition condition = message.getCondition();
    final DDF_QuoteState state = message.getState();
    final DDF_QuoteMode mode = message.getMode();

    /** Handle quote publish state */
    {
      switch (mode) {
      case END_OF_DAY:
      case DELAYED:
      case SNAPSHOT:
      case UNKNOWN:
        market.setState(MarketStateEntry.IS_PUBLISH_REALTIME, false);
        market.setState(MarketStateEntry.IS_PUBLISH_DELAYED, true);
        break;
      case REALTIME:
        market.setState(MarketStateEntry.IS_PUBLISH_REALTIME, true);
        market.setState(MarketStateEntry.IS_PUBLISH_DELAYED, false);
        break;
      default:
        break;
      }
    }

    /** Handle settle state */
    {
      switch (state) {
      case GOT_CLOSE:
        break;
      case GOT_SETTLE:
        log.debug("Set State IS_SETTLED true inside visit MarketQuote by GOT_SETTLE state");
        market.setState(MarketStateEntry.IS_SETTLED, true);
        break;
      case PRE_MARKET:
        log.debug("Set State IS_SETTLED false inside visit MarketQuote by PRE_MARKET state");
        market.setState(MarketStateEntry.IS_SETTLED, false);
        break;
      }
    }

    /** Process Sessions */
    {
      final DDF_MarketSession[] sessionArray = message.sessions();

      for (final DDF_MarketSession session : sessionArray) {
        final DDF_Indicator indicator = session.getIndicator();
        log.debug("DDF_Indicator for session {} : {} ", session
            .getSession().name(), indicator.name());
        switch (indicator) {
        case CURRENT:
         
          /* Update changed comonents */
          market.setChange(Component.DEFAULT_CURRENT);
         
          visit(session, market);
         
          break;
        case PREVIOUS:
         
          /* Update changed comonents */
          market.setChange(Component.DEFAULT_PREVIOUS);
         
          visit(session, market);
         
          break;
        default:
          log.error("@@@ wrong indicator : {}", indicator);
          break;
        }
      }
    }

    /** Process top of book */
    {
     
      /* Update changed comonents */
      market.setChange(Component.BOOK_COMBINED);
     
      final DDF_MarketBookTop bookTop = message;
      visit(bookTop, market);
     
    }

    return null;
  }

  /**
   * via xml quote.
   *
   * @param message
   *            the message
   * @param market
   *            the market
   * @return the void
   */
  @Override
  public Void visit(final DDF_MarketSession message, final MarketDo market) {

    // ### process session

    // TODO are these trade fields?
    final SizeValue sizeLast = message.getSizeLast();
    final TimeValue timeLast = message.getTimeLast();

    // ### process snapshot

    final DDF_MarketSnapshot snapshot = message;
    final DDF_Indicator indicator = message.getIndicator();

    visit(snapshot, market, indicator);

    return null;
  }

  @Override
  public Void visit(final DDF_EOD_Commodity message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.DEFAULT_PREVIOUS);
   
    final MarketDoBar newBar = market.loadBar(MarketField.BAR_PREVIOUS);

    newBar.set(MarketBarField.OPEN, message.getPriceOpen());
    newBar.set(MarketBarField.HIGH, message.getPriceHigh());
    newBar.set(MarketBarField.LOW, message.getPriceLow());
    /* Note Last =/= Close in some cases */
    newBar.set(MarketBarField.CLOSE, message.getPriceLast());

    market.setBar(MarketBarType.PREVIOUS, newBar);

    return null;
  }

  @Override
  public Void visit(final DDF_EOD_EquityForex message, final MarketDo market) {
   
    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.DEFAULT_PREVIOUS);
   
    final MarketDoBar newBar = market.loadBar(MarketField.BAR_PREVIOUS);

    newBar.set(MarketBarField.OPEN, message.getPriceOpen());
    newBar.set(MarketBarField.HIGH, message.getPriceHigh());
    newBar.set(MarketBarField.LOW, message.getPriceLow());
    /* Note Last =/= Close in some cases */
    newBar.set(MarketBarField.CLOSE, message.getPriceLast());

    newBar.set(MarketBarField.VOLUME, message.getSizeVolume());

    market.setBar(MarketBarType.PREVIOUS, newBar);
   
    return null;
  }

  @Override
  public Void visit(final DDF_Prior_IndividCmdy message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.DEFAULT_PREVIOUS);
   
    final MarketDoBar newBar = market.loadBar(MarketField.BAR_PREVIOUS);

    newBar.set(MarketBarField.VOLUME, message.getSizeVolume());
    newBar.set(MarketBarField.INTEREST, message.getSizeOpenInterest());

    market.setBar(MarketBarType.PREVIOUS, newBar);
   
    return null;
  }

  /**
   * via feed message 21.
   *
   * @param message
   *            the message
   * @param market
   *            the market
   * @return the void
   */
  @Override
  public Void visit(final DDF_MarketSnapshot message, final MarketDo market) {

    market.clearChanges();
   
    final TimeValue time = message.getTime();

    /** Update SETTLE State */
    {

      final PriceValue priceSettle = message.getPriceSettle();

      if (isClear(priceSettle)) {
        // ",-, " : means remove old value
        //log.debug("Set State IS_SETTLED false inside visit
        //MarketSnapshot because priceSettle is clear");
        market.setState(MarketStateEntry.IS_SETTLED, false);
      } else if (isEmpty(priceSettle)) {
        // ",," : means leave alone
        // no change of current value
      } else {
        // ",12345," : means replace with new value
        //log.debug("Set State IS_SETTLED true inside visit
        //MarketSnapshot because priceSettle is not empty");
        market.setState(MarketStateEntry.IS_SETTLED, true);
      }

    }

    /** Update top of book */
    {

      /* Update changed comonents */
      market.setChange(Component.BOOK_COMBINED);
     
      final PriceValue priceBid = message.getPriceBid();
      final PriceValue priceAsk = message.getPriceAsk();

      /** XXX note: {@link MarketBook#ENTRY_TOP} */

      final MarketDoBookEntry entryBid = new DefBookEntry(
          MODIFY, Book.Side.BID,
          Book.Type.DEFAULT, ENTRY_TOP, priceBid, ValueConst.NULL_SIZE);
      final MarketDoBookEntry entryAsk = new DefBookEntry(
          MODIFY, Book.Side.ASK,
          Book.Type.DEFAULT, ENTRY_TOP, priceAsk, ValueConst.NULL_SIZE);

      applyTop(entryBid, time, market);
      applyTop(entryAsk, time, market);
     
    }

    /** Update CURRENT bar */
    {

      /* Update changed comonents */
      market.setChange(Component.DEFAULT_CURRENT);
     
      final MarketBarType type = CURRENT;

      final MarketDoBar bar = market.loadBar(type.field);

      final DDF_TradeDay tradeDay = message.getTradeDay();
      bar.set(MarketBarField.TRADE_DATE, tradeDay.tradeDate());

      final PriceValue priceOpen = message.getPriceOpen();
      final PriceValue priceHigh = message.getPriceHigh();
      final PriceValue priceLow = message.getPriceLow();
      final PriceValue priceClose = message.getPriceLast(); // XXX
      final PriceValue priceSettle = message.getPriceSettle();
      final SizeValue sizeVolume = message.getSizeVolume();

      applyBar(bar, MarketBarField.OPEN, priceOpen);
      applyBar(bar, MarketBarField.HIGH, priceHigh);
      applyBar(bar, MarketBarField.LOW, priceLow);
      applyBar(bar, MarketBarField.CLOSE, priceClose);
      applyBar(bar, MarketBarField.SETTLE, priceSettle);
      applyBar(bar, MarketBarField.VOLUME, sizeVolume);

      bar.set(MarketBarField.BAR_TIME, time);

      market.setBar(type, bar);

    }

    /** Update PREVIOUS bar */
    {

      /* Update changed comonents */
      market.setChange(Component.DEFAULT_PREVIOUS);
     
      final MarketBarType type = PREVIOUS;

      final MarketDoBar bar = market.loadBar(type.field);
      final PriceValue priceOpen = message.getPriceOpen();
      final PriceValue priceHigh = message.getPriceHigh();
      final PriceValue priceLow = message.getPriceLow();
      final PriceValue priceClose = message.getPriceLastPrevious();
      final PriceValue priceSettle = message.getPriceSettle();
      final SizeValue sizeVolume = message.getSizeVolumePrevious();
      final SizeValue sizeInterest = message.getSizeInterest(); // XXX

      applyBar(bar, MarketBarField.OPEN, priceOpen);
      applyBar(bar, MarketBarField.HIGH, priceHigh);
      applyBar(bar, MarketBarField.LOW, priceLow);
      applyBar(bar, MarketBarField.CLOSE, priceClose);
      applyBar(bar, MarketBarField.SETTLE, priceSettle);
      applyBar(bar, MarketBarField.VOLUME, sizeVolume);
      applyBar(bar, MarketBarField.INTEREST, sizeInterest);

      bar.set(MarketBarField.BAR_TIME, time);

      market.setBar(type, bar);

    }

    return null;
  }

  /**
   * via xml quote >> xml session
   */
  protected Void visit(final DDF_MarketSnapshot message,
      final MarketDo market, final DDF_Indicator indicator) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.DEFAULT_CURRENT);
    market.setChange(Component.DEFAULT_PREVIOUS);
   
    final DDF_Session session = message.getSession();

    final MarketBarType type = barTypeFrom(indicator, session);

    final MarketDoBar bar = market.loadBar(type.field);

    //
    final DDF_TradeDay tradeDay = message.getTradeDay();
    bar.set(MarketBarField.TRADE_DATE, tradeDay.tradeDate());
    //

    // extract

    final PriceValue priceOpen = message.getPriceOpen();
    final PriceValue priceHigh = message.getPriceHigh();
    final PriceValue priceLow = message.getPriceLow();
    final PriceValue priceClose = message.getPriceLast(); // XXX note: LAST
    final PriceValue priceSettle = message.getPriceSettle();
    final SizeValue sizeVolume = message.getSizeVolume();
    final SizeValue sizeInterest = message.getSizeInterest();

    // apply

    applyBar(bar, MarketBarField.OPEN, priceOpen);
    applyBar(bar, MarketBarField.HIGH, priceHigh);
    applyBar(bar, MarketBarField.LOW, priceLow);
    applyBar(bar, MarketBarField.CLOSE, priceClose);
    applyBar(bar, MarketBarField.SETTLE, priceSettle);
    applyBar(bar, MarketBarField.VOLUME, sizeVolume);
    applyBar(bar, MarketBarField.INTEREST, sizeInterest);

    //

    bar.set(MarketBarField.BAR_TIME, message.getTime());

    market.setBar(type, bar);
   
    /*
     * If a previous update, set in bar current.
     */
    if(type == MarketBarType.PREVIOUS) {
     
      market.loadBar(MarketBarType.CURRENT.field).set(
          MarketBarField.SETTLE_PREVIOUS, priceSettle);
     
    }
   
    return null;
  }

  @Override
  public Void visit(final DDF_MarketTrade message, final MarketDo market) {

    /* Update changed comonents */
    market.clearChanges();
    market.setChange(Component.TRADE);
   
    final DDF_MessageType tradeType = message.getMessageType();

    switch (tradeType) {
    case TRADE: {

      // message "27" : normal trade

      PriceValue price = message.getPrice();
      SizeValue size = message.getSize();

      // TODO review contract on how to clean partial values
      if (isClear(price) || isEmpty(price)) {
        price = ValueConst.NULL_PRICE;
        size = ValueConst.NULL_SIZE;
      }

      // TODO review contract on how to clean partial values
      if (isClear(size) || isEmpty(size)) {
        size = ValueConst.NULL_SIZE;
      }

      final DDF_Session ddfSession = message.getSession();
      final TimeValue time = message.getTime();
      final TimeValue date = message.getTradeDay().tradeDate();

      market.setTrade(ddfSession.type, ddfSession.session,
          ddfSession.sequencing, price, size, time, date);

    }
      break;

    case TRADE_VOL: {

      // message "2Z" : "do not know what to do", ignore for now

    }
      break;

    default:
      log.error("unsupported trade message type");
      break;

    }
   
    return null;
  }

  // ##################################

  protected void applyBar(final MarketDoBar bar,
      final MarketBarField<PriceValue> field, final PriceValue value) {

    if (isEmpty(value)) {
      // no change in market field value
      return;
    }

    if (isClear(value)) {
      // NULL_PRICE should be rendered as "price value not available"
      bar.set(field, ValueConst.NULL_PRICE);
      return;
    }

    bar.set(field, value);

  }

  protected void applyBar(final MarketDoBar bar,
      final MarketBarField<SizeValue> field, final SizeValue value) {

    if (isEmpty(value)) {
      // no change in market field value
      return;
    }

    if (isClear(value)) {
      // NULL_SIZE should be rendered as "size value not available"
      bar.set(field, ValueConst.NULL_SIZE);
      return;
    }

    bar.set(field, value);

  }

  /** currently does not differentiate between sources */
  protected MarketBarType barTypeFromCurrent(final DDF_Session session) {

    final MarketTradeSession tradeSession = session.session;

    switch (tradeSession) {

    case EXTENDED:
      return MarketBarType.CURRENT_EXT;
    default:
      return MarketBarType.CURRENT;
    }

  }

  /** currently only differentiate THIS day vs PAST day market */
  protected MarketBarType barTypeFrom(final DDF_Indicator indicator,
      final DDF_Session session) {

    switch (indicator) {
    default:
      log.error("wrong indicator : {}", indicator);
    case CURRENT:
      return barTypeFromCurrent(session);
    case PREVIOUS:
      return MarketBarType.PREVIOUS;
    }

  }

  protected void applyTop(/* local */MarketDoBookEntry entry,
      final TimeValue time, final MarketDo market) {

    /* ddf signals by special price values */
    final PriceValue price = entry.priceValue();

    /* ",," a.k.a comma-comma; ddf value not provided */
    if (isEmpty(price)) {
      return;
    }

    /* ",-," a.k.a comma-dash-comma; ddf command : remove */
    if (isClear(price)) {
      entry = new DefBookEntry(
          MarketBookAction.REMOVE, entry.side(),
          Book.Type.DEFAULT, MarketBook.ENTRY_TOP,
          ValueConst.NULL_PRICE, ValueConst.NULL_SIZE);
    }

    market.setBookUpdate(entry, time);

  }

}
TOP

Related Classes of com.barchart.feed.ddf.market.provider.MapperDDF

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.