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

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

/**
* 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.MarketBarField.BAR_TIME;
import static com.barchart.feed.base.bar.enums.MarketBarField.CLOSE;
import static com.barchart.feed.base.bar.enums.MarketBarField.HIGH;
import static com.barchart.feed.base.bar.enums.MarketBarField.LOW;
import static com.barchart.feed.base.bar.enums.MarketBarField.OPEN;
import static com.barchart.feed.base.bar.enums.MarketBarField.VOLUME;
import static com.barchart.feed.base.bar.enums.MarketBarType.CURRENT;
import static com.barchart.feed.base.bar.enums.MarketBarType.CURRENT_EXT;
import static com.barchart.feed.base.market.enums.MarketEvent.MARKET_UPDATED;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_BOOK_ERROR;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_BOOK_SNAPSHOT;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_BOOK_TOP;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_BOOK_UPDATE;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_CLOSE;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_CUVOL_SNAPSHOT;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_CUVOL_UPDATE;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_TRADE;
import static com.barchart.feed.base.market.enums.MarketEvent.NEW_VOLUME;
import static com.barchart.feed.base.market.enums.MarketField.BOOK;
import static com.barchart.feed.base.market.enums.MarketField.BOOK_TOP;
import static com.barchart.feed.base.market.enums.MarketField.MARKET_TIME;
import static com.barchart.feed.base.market.enums.MarketField.TRADE;
import static com.barchart.feed.base.trade.enums.MarketTradeField.PRICE;
import static com.barchart.feed.base.trade.enums.MarketTradeField.SEQUENCING;
import static com.barchart.feed.base.trade.enums.MarketTradeField.SESSION;
import static com.barchart.feed.base.trade.enums.MarketTradeField.SIZE;
import static com.barchart.feed.base.trade.enums.MarketTradeField.TRADE_TIME;
import static com.barchart.feed.base.trade.enums.MarketTradeField.TYPE;
import static com.barchart.feed.base.trade.enums.MarketTradeSequencing.NORMAL;
import static com.barchart.feed.base.trade.enums.MarketTradeSession.DEFAULT;
import static com.barchart.feed.base.trade.enums.MarketTradeSession.EXTENDED;

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

import com.barchart.feed.api.model.data.Book;
import com.barchart.feed.api.model.meta.Instrument;
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.MarketDoBook;
import com.barchart.feed.base.book.api.MarketDoBookEntry;
import com.barchart.feed.base.book.enums.UniBookResult;
import com.barchart.feed.base.cuvol.api.MarketDoCuvol;
import com.barchart.feed.base.cuvol.api.MarketDoCuvolEntry;
import com.barchart.feed.base.provider.VarMarket;
import com.barchart.feed.base.state.enums.MarketStateEntry;
import com.barchart.feed.base.trade.api.MarketDoTrade;
import com.barchart.feed.base.trade.enums.MarketTradeField;
import com.barchart.feed.base.trade.enums.MarketTradeSequencing;
import com.barchart.feed.base.trade.enums.MarketTradeSession;
import com.barchart.feed.base.trade.enums.MarketTradeType;
import com.barchart.feed.base.values.api.BooleanValue;
import com.barchart.feed.base.values.api.PriceValue;
import com.barchart.feed.base.values.api.SizeValue;
import com.barchart.feed.base.values.api.TimeValue;
import com.barchart.feed.base.values.provider.ValueBuilder;
import com.barchart.feed.base.values.provider.ValueConst;
import com.barchart.feed.ddf.message.provider.DDF_MessageService;
import com.barchart.util.common.anno.Mutable;
import com.barchart.util.value.api.Price;

/**
* Logic #1
*
* keep here value relations and event management logic only
**/
@Mutable
class VarMarketDDF extends VarMarket {

  public VarMarketDDF(final Instrument instrument) {
    super(instrument);
  }

  private static final Logger log = LoggerFactory
      .getLogger(VarMarketDDF.class);

  private final void updateMarket(final TimeValue time) {

    if(time.compareTo(get(MARKET_TIME)) > 0) {
      set(MARKET_TIME, time);
    }

    eventAdd(MARKET_UPDATED);

  }

  /*
   * This is just being used in VarMarketEntityDDF (non-Javadoc)
   *
   * @see com.barchart.feed.base.market.api.MarketDo#fireCallbacks()
   */
  @Override
  public void fireCallbacks() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void setInstrument(final Instrument newSymbol) {
    instrument = newSymbol;
  }

  @Override
  public void setBookSnapshot(final MarketDoBookEntry[] entries, final TimeValue time) {

    assert entries != null;
    assert time != null;

    final MarketDoBook book = loadBook();

    book.setSnapshot(entries);

    setChange(Component.BOOK_COMBINED);
    eventAdd(NEW_BOOK_SNAPSHOT);

    book.setTime(time);
    updateMarket(time);

  }

  @Override
  public void setBookUpdate(final MarketDoBookEntry entry,
      final TimeValue time) {

    assert entry != null && time != null;

    final MarketDoBook book = loadBook();

    final UniBookResult result = book.setEntry(entry);

    switch (result) {
      case TOP:
        eventAdd(NEW_BOOK_TOP);
        // continue
      case NORMAL:
        eventAdd(NEW_BOOK_UPDATE);
        break;
      default:
        eventAdd(NEW_BOOK_ERROR);
        final CharSequence id = instrument.id().toString();
        final CharSequence comment = instrument.description();
        log.error("instrument : {} : {}", id, comment);
        log.error("result : {} ; entry : {} ;", result, entry);
        return;
    }

    book.setTime(time);
    setChange(Component.BOOK_COMBINED);
    updateMarket(time);

  }

  @Override
  public void setCuvolUpdate(final MarketDoCuvolEntry entry,
      final TimeValue time) {

    assert entry != null && time != null;

    makeCuvol(entry.priceValue(), entry.sizeValue(), time);

    updateMarket(time);

  }

  @Override
  public void setCuvolSnapshot(final MarketDoCuvolEntry[] entries,
      final TimeValue time) {

    assert entries != null && time != null;

    final MarketDoCuvol cuvol = loadCuvol();

    cuvol.clear();

    for (final MarketDoCuvolEntry entry : entries) {
      cuvol.add(entry.priceValue(), entry.sizeValue(), time);
    }

    setChange(Component.CUVOL);
    eventAdd(NEW_CUVOL_SNAPSHOT);

    updateMarket(time);

  }

  @Override
  public void setTrade(
      final MarketTradeType type,
      final MarketTradeSession session,
      final MarketTradeSequencing sequencing,
      final PriceValue price,
      final SizeValue size,
      final TimeValue time,
      final TimeValue date) {

    assert type != null;
    assert session != null;
    assert sequencing != null;
    assert price != null;
    assert size != null;
    assert time != null;
    assert date != null;
   
    // Update trade
    if (sequencing != MarketTradeSequencing.UNSEQUENCED_VOLUME) {

      final MarketDoTrade trade = loadTrade();

      trade.set(TYPE, type);
      trade.set(SESSION, session);
      trade.set(SEQUENCING, sequencing);
      trade.set(PRICE, price);
      trade.set(SIZE, size);
      trade.set(TRADE_TIME, time);
      trade.set(MarketTradeField.TRADE_DATE, date);

      setChange(Component.TRADE);
      eventAdd(NEW_TRADE);

      set(TRADE, trade);

    }

    applyTradeToBar(session, sequencing, price, size, time, date);

    makeCuvol(price, size, time);

    updateMarket(time);

  }

  @Override
  public void setSnapshot(
      final TimeValue tradeDate,
      final PriceValue open,
      final PriceValue high,
      final PriceValue low,
      final PriceValue close,
      final PriceValue settle,
      final PriceValue previousSettle,
      final SizeValue volume,
      final SizeValue interest,
      final BooleanValue isSettled,
      final TimeValue barTime) {
   
    final MarketBarType type = ensureBar(tradeDate);

    if (type.isNull())
      return;

    final MarketDoBar bar = loadBar(type.field);

    applyBar(bar, MarketBarField.OPEN, open);
    applyBar(bar, MarketBarField.HIGH, high);
    applyBar(bar, MarketBarField.LOW, low);
    applyBar(bar, MarketBarField.CLOSE, close);
    applyBar(bar, MarketBarField.SETTLE, settle);
    applyBar(bar, MarketBarField.CLOSE_PREVIOUS, previousSettle);
    applyBar(bar, MarketBarField.VOLUME, volume);
    applyBar(bar, MarketBarField.INTEREST, interest);
   
    if (isSettled != null)
      bar.set(MarketBarField.IS_SETTLED, isSettled);

    if (barTime != null)
      bar.set(MarketBarField.BAR_TIME, barTime);

    setBar(type, bar);

  }

  @Override
  public void setBar(final MarketBarType type, final MarketDoBar bar) {

    assert type != null;
    assert bar != null;

    set(type.field, bar);

    switch (type) {
      case CURRENT:
        setChange(Component.DEFAULT_PREVIOUS);
        break;
      case PREVIOUS:
        setChange(Component.DEFAULT_CURRENT);
        break;
      case CURRENT_EXT:
        setChange(Component.EXTENDED_CURRENT);
        break;
      default:
        break;
    }

    eventAdd(type.event);

    /* Don't update time based on previous bar */
    if(type == MarketBarType.PREVIOUS) {
      eventAdd(MARKET_UPDATED);
    } else {
      updateMarket(bar.get(BAR_TIME));
    }

  }

  //

  /** XXX eliminate: temp hack for ddf */
  @Override
  protected MarketDoBook loadBook() {

    MarketBook book = get(BOOK);

    if (book.isFrozen()) {

      Book.Type type = null;
      switch (instrument.liquidityType()) {
        default:
          type = Book.Type.NONE;
          break;
        case NONE:
          type = Book.Type.NONE;
          break;
        case DEFAULT:
          type = Book.Type.DEFAULT;
          break;
        case IMPLIED:
          type = Book.Type.IMPLIED;
          break;
        case COMBINED:
          type = Book.Type.COMBINED;
          break;
      }
      final SizeValue size = LIMIT;
      // TODO ValueConverter
      final Price tempStep = instrument.tickSize();
      final PriceValue step = ValueBuilder.newPrice(tempStep.mantissa(),
          tempStep.exponent());

      final VarBookDDF varBook = new VarBookDDF(instrument, type, size, step);
      final VarBookTopDDF varBookTop = new VarBookTopDDF(varBook);

      set(BOOK, varBook);
      set(BOOK_TOP, varBookTop);

      book = varBook;

    }

    return (MarketDoBook) book;

  }

  @Override
  public void setState(final MarketStateEntry entry, final boolean isOn) {

    assert entry != null;

    final com.barchart.feed.base.state.api.MarketState state = loadState();

    if (isOn) {
      state.add(entry);
    } else {
      state.remove(entry);
    }

  }

  @Override
  public void setChange(final Component c) {
    changeSet.add(c);
  }

  @Override
  public void clearChanges() {
    changeSet.clear();
  }

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

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

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

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

    bar.set(field, value);

  }

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

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

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

    bar.set(field, value);

  }

  private final void applyTradeToBar(final MarketTradeSession session,
      final MarketTradeSequencing sequencing, final PriceValue price,
      final SizeValue size, final TimeValue time, final TimeValue date) {

    MarketBarType barType = ensureBar(date);
    if (session == EXTENDED && barType == CURRENT)
      barType = CURRENT_EXT;

    final MarketDoBar bar = loadBar(barType.field);

    eventAdd(barType.event);

    final SizeValue volumeOld = bar.get(VOLUME);

    if (volumeOld.isNull()) {
      bar.set(VOLUME, size);
    } else {
      final SizeValue volumeNew = volumeOld.add(size);
      bar.set(VOLUME, volumeNew);
    }

    eventAdd(NEW_VOLUME);

    if (sequencing != MarketTradeSequencing.UNSEQUENCED_VOLUME) {

      // Only update last price for normal in-sequence trades unless null
      if (sequencing == NORMAL || bar.get(CLOSE).isNull()) {

        if (price.isNull()) {

          log.warn("null or zero price on trade message, not applying to bar");

        } else {

          // Set open if first trade
          if (bar.get(OPEN).isNull())
            bar.set(OPEN, price);

          bar.set(CLOSE, price);

          if (session == DEFAULT) {
            // events only for combo
            eventAdd(NEW_CLOSE);
          }

          // Update time
          bar.set(BAR_TIME, time);

        }

      }

      // Update high/low for sequential and non-sequential trades
      if (!price.isNull() && !price.isZero()) {

        final PriceValue high = bar.get(HIGH);
        if (high.isNull())
          bar.set(HIGH, price);
        else if (high.compareTo(price) < 0)
          bar.set(HIGH, price);

        final PriceValue low = bar.get(LOW);
        if (low.isNull())
          bar.set(LOW, price);
        else if (low.compareTo(price) > 0)
          bar.set(LOW, price);

      }

    }

  }

  private final void makeCuvol(final PriceValue price, final SizeValue size,
      final TimeValue time) {

    final MarketDoCuvol cuvol = loadCuvol();

    if (!cuvol.isNull()) {

      cuvol.add(price, size, time);

      setChange(Component.CUVOL);
      eventAdd(NEW_CUVOL_UPDATE);

    }

  }

}
TOP

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

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.