Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrii_Ostapenko1 authored and Andrii_Ostapenko1 committed Oct 24, 2022
2 parents d7ba0bc + 364a151 commit 9019892
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 53 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ final OrderBook<OrderBookQuote> orderBook = OrderBookFactory.create();
<br>The following types are supported:
* *SINGLE_EXCHANGE* - order book from single exchange
* *CONSOLIDATED* - consolidated view on the market from multiple exchanges, you can see individual exchange sizes
* *SINGLE_EXCHANGE* - aggregated view of multiple exchanges, you can see combined size of each price level
* *AGGREGATED* - aggregated view of multiple exchanges, you can see combined size of each price level


- ***updateMode*** - What do we do with incremental update if we have empty order book?
Expand Down Expand Up @@ -166,6 +166,14 @@ final OrderBook<OrderBookQuote> orderBook = OrderBookFactory.create();
<br>Type: int
<br>Default Value is: ***32767***

- :1234: ***unreachableDepthMode*** - What do we do if we have quote level more than maxDepth? <br>\
<br>Since: ***1.0.17***
<br>Type: UnreachableDepthMode
<br>Default Value is: ***SKIP***
<br>The following types are supported:
* *SKIP* - let's skip quote
* *SKIP_AND_DROP* - let's skip quote and drop all quote for stock exchange


- :1234: ***initialExchangesPoolSize*** - How large initial pool size for stock exchanges should be?<br>
Supported for AGGREGATED and CONSOLIDATED order book type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,19 @@ public static <Quote extends OrderBookQuote> OrderBook<Quote> create(final Order
break;
case LEVEL_TWO:
final GapMode gapMode = opt.getGapMode().orElse(Defaults.GAP_MODE);
final UnreachableDepthMode unreachableDepthMode = opt.getUnreachableDepthMode().orElse(Defaults.UNREACHABLE_DEPTH_MODE);
final int initialDepth = opt.getInitialDepth().orElse(Defaults.INITIAL_DEPTH);
final int maxDepth = opt.getMaxDepth().orElse(Defaults.MAX_DEPTH);
final Integer exchangePoolSize = opt.getInitialExchangesPoolSize().orElse(Defaults.INITIAL_EXCHANGES_POOL_SIZE);
switch (orderBookType) {
case SINGLE_EXCHANGE:
book = L2OrderBookFactory.newSingleExchangeBook(symbol, initialDepth, maxDepth, gapMode, updateMode);
book = L2OrderBookFactory.newSingleExchangeBook(symbol, initialDepth, maxDepth, gapMode, updateMode, unreachableDepthMode);
break;
case AGGREGATED:
book = L2OrderBookFactory.newAggregatedBook(symbol, exchangePoolSize, initialDepth, maxDepth, gapMode, updateMode);
book = L2OrderBookFactory.newAggregatedBook(symbol, exchangePoolSize, initialDepth, maxDepth, gapMode, updateMode, unreachableDepthMode);
break;
case CONSOLIDATED:
book = L2OrderBookFactory.newConsolidatedBook(symbol, exchangePoolSize, initialDepth, maxDepth, gapMode, updateMode);
book = L2OrderBookFactory.newConsolidatedBook(symbol, exchangePoolSize, initialDepth, maxDepth, gapMode, updateMode, unreachableDepthMode);
break;
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,7 @@ public short binarySearchNextLevelByPrice(final Quote find) {

@Override
public boolean hasLevel(final short level) {
if (level >= maxDepth || level < 0) {
return false;
} else if (data.size() > level) {
if (data.size() > level) {
return Objects.nonNull(data.get(level));
}
return false;
Expand Down Expand Up @@ -235,12 +233,7 @@ public boolean isFull() {
//TODO add doc !!
@Override
public boolean isGap(final short level) {
if (!hasLevel(level)) {
return depth() != level || // If trying to add to end
level >= getMaxDepth() || // If we're using maxDepth parameter.
(depth() == level && isFull()); //Receive incorrect level after snapshot. More than max depth
}
return false;
return !hasLevel(level) && level > depth();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
package com.epam.deltix.orderbook.core.impl;

import com.epam.deltix.orderbook.core.api.MarketSide;
import com.epam.deltix.orderbook.core.options.Defaults;
import com.epam.deltix.orderbook.core.options.GapMode;
import com.epam.deltix.orderbook.core.options.Option;
import com.epam.deltix.orderbook.core.options.UpdateMode;
import com.epam.deltix.orderbook.core.options.*;
import com.epam.deltix.timebase.messages.universal.*;
import com.epam.deltix.util.annotations.Alphanumeric;
import com.epam.deltix.util.collections.generated.ObjectList;
Expand All @@ -40,6 +37,7 @@ abstract class AbstractL2MultiExchangeProcessor<Quote extends MutableOrderBookQu
//Parameters
protected final GapMode gapMode;
protected final UpdateMode updateMode;
protected final UnreachableDepthMode unreachableDepthMode;
protected final ObjectPool<Quote> pool;
protected final short initialDepth;
protected final int maxDepth;
Expand All @@ -55,12 +53,14 @@ abstract class AbstractL2MultiExchangeProcessor<Quote extends MutableOrderBookQu
final int maxDepth,
final ObjectPool<Quote> pool,
final GapMode gapMode,
final UpdateMode updateMode) {
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
this.initialDepth = (short) initialDepth;
this.maxDepth = maxDepth;
this.pool = pool;
this.gapMode = gapMode;
this.updateMode = updateMode;
this.unreachableDepthMode = unreachableDepthMode;
this.exchanges = new MutableExchangeListImpl<>(initialExchangeCount);
this.asks = L2MarketSide.factory(initialExchangeCount * initialDepth, Defaults.MAX_DEPTH, QuoteSide.ASK);
this.bids = L2MarketSide.factory(initialExchangeCount * initialDepth, Defaults.MAX_DEPTH, QuoteSide.BID);
Expand Down Expand Up @@ -122,6 +122,20 @@ public Quote processL2EntryNewInfo(final L2EntryNewInfo l2EntryNewInfo) {

final L2MarketSide<Quote> marketSide = exchange.getMarketSide(side);

// TODO: 6/30/2022 need to refactor return value
// Duplicate
if (level >= marketSide.getMaxDepth()) {
switch (unreachableDepthMode) {
case SKIP_AND_DROP:
clear();
return null;
case SKIP:
default:
return null;
}
// Unreachable quote level
}

// TODO: 6/30/2022 need to refactor return value
// Duplicate
if (marketSide.isGap(level)) {
Expand All @@ -138,7 +152,7 @@ public Quote processL2EntryNewInfo(final L2EntryNewInfo l2EntryNewInfo) {
}
}

if (marketSide.isFull()) { //Remove worst quote
if (marketSide.hasLevel(level)) { //Remove worst quote
removeQuote(marketSide.getWorstQuote(), side);
}

Expand Down Expand Up @@ -262,7 +276,7 @@ public L2Processor<Quote> getOrCreateExchange(final long exchangeId) {
Option<MutableExchange<Quote, L2Processor<Quote>>> exchangeHolder = exchanges.getById(exchangeId);
if (!exchangeHolder.hasValue()) {
final L2SingleExchangeQuoteProcessor<Quote> processor =
new L2SingleExchangeQuoteProcessor<>(exchangeId, initialDepth, maxDepth, pool, gapMode, updateMode);
new L2SingleExchangeQuoteProcessor<>(exchangeId, initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
exchanges.add(new MutableExchangeImpl<>(exchangeId, processor));
exchangeHolder = exchanges.getById(exchangeId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.epam.deltix.dfp.Decimal;
import com.epam.deltix.orderbook.core.options.GapMode;
import com.epam.deltix.orderbook.core.options.UnreachableDepthMode;
import com.epam.deltix.orderbook.core.options.UpdateMode;
import com.epam.deltix.timebase.messages.TypeConstants;
import com.epam.deltix.timebase.messages.universal.L2EntryUpdateInfo;
Expand All @@ -38,8 +39,9 @@ class L2AggregatedQuoteProcessor<Quote extends MutableOrderBookQuote> extends Ab
final int maxDepth,
final ObjectPool<Quote> pool,
final GapMode gapMode,
final UpdateMode updateMode) {
super(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode);
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
super(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.epam.deltix.dfp.Decimal64Utils;
import com.epam.deltix.orderbook.core.options.GapMode;
import com.epam.deltix.orderbook.core.options.UnreachableDepthMode;
import com.epam.deltix.orderbook.core.options.UpdateMode;
import com.epam.deltix.timebase.messages.universal.L2EntryUpdateInfo;
import com.epam.deltix.timebase.messages.universal.QuoteSide;
Expand All @@ -34,8 +35,9 @@ class L2ConsolidatedQuoteProcessor<Quote extends MutableOrderBookQuote> extends
final int maxDepth,
final ObjectPool<Quote> pool,
final GapMode gapMode,
final UpdateMode updateMode) {
super(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode);
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
super(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode,unreachableDepthMode);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.epam.deltix.orderbook.core.api.OrderBookQuote;
import com.epam.deltix.orderbook.core.options.GapMode;
import com.epam.deltix.orderbook.core.options.Option;
import com.epam.deltix.orderbook.core.options.UnreachableDepthMode;
import com.epam.deltix.orderbook.core.options.UpdateMode;

/**
Expand Down Expand Up @@ -48,10 +49,11 @@ public static <Quote extends OrderBookQuote> OrderBook<Quote> newSingleExchangeB
final int initialDepth,
final int maxDepth,
final GapMode gapMode,
final UpdateMode updateMode) {
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
final ObjectPool<MutableOrderBookQuote> pool = new ObjectPool<>(initialDepth, MutableOrderBookQuoteImpl::new);
final QuoteProcessor<MutableOrderBookQuote> processor =
new L2SingleExchangeQuoteProcessor<>(initialDepth, maxDepth, pool, gapMode, updateMode);
new L2SingleExchangeQuoteProcessor<>(initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
return (OrderBook<Quote>) new OrderBookDecorator<>(symbol, processor);
}

Expand All @@ -73,10 +75,11 @@ public static <Quote extends OrderBookQuote> OrderBook<Quote> newConsolidatedBoo
final int initialDepth,
final int maxDepth,
final GapMode gapMode,
final UpdateMode updateMode) {
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
final ObjectPool<MutableOrderBookQuote> pool = new ObjectPool<>(initialExchangeCount * initialDepth, MutableOrderBookQuoteImpl::new);
final QuoteProcessor<MutableOrderBookQuote> processor =
new L2ConsolidatedQuoteProcessor<>(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode);
new L2ConsolidatedQuoteProcessor<>(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
return (OrderBook<Quote>) new OrderBookDecorator<>(symbol, processor);
}

Expand All @@ -98,10 +101,11 @@ public static <Quote extends OrderBookQuote> OrderBook<Quote> newAggregatedBook(
final int initialDepth,
final int maxDepth,
final GapMode gapMode,
final UpdateMode updateMode) {
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
final ObjectPool<MutableOrderBookQuote> pool = new ObjectPool<>(initialExchangeCount * initialDepth * 4, MutableOrderBookQuoteImpl::new);
final QuoteProcessor<MutableOrderBookQuote> processor =
new L2AggregatedQuoteProcessor<>(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode);
new L2AggregatedQuoteProcessor<>(initialExchangeCount, initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
return (OrderBook<Quote>) new OrderBookDecorator<>(symbol, processor);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ default DataModelType getQuoteLevels() {
default boolean process(final BaseEntryInfo pck) {
if (pck instanceof L2EntryNew) {
final L2EntryNew l2EntryNewInfo = (L2EntryNew) pck;
processL2EntryNewInfo(l2EntryNewInfo);
processL2EntryNewInfo(l2EntryNewInfo);
return true;
} else if (pck instanceof L2EntryUpdate) {
final L2EntryUpdate l2EntryUpdateInfo = (L2EntryUpdate) pck;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.epam.deltix.orderbook.core.options.GapMode;
import com.epam.deltix.orderbook.core.options.Option;
import com.epam.deltix.orderbook.core.options.UnreachableDepthMode;
import com.epam.deltix.orderbook.core.options.UpdateMode;
import com.epam.deltix.timebase.messages.universal.*;
import com.epam.deltix.util.collections.generated.ObjectList;
Expand All @@ -39,6 +40,8 @@ public class L2SingleExchangeQuoteProcessor<Quote extends MutableOrderBookQuote>

//Parameters
private final GapMode gapMode;

private final UnreachableDepthMode unreachableDepthMode;
private final UpdateMode updateMode;

/**
Expand All @@ -52,7 +55,9 @@ public L2SingleExchangeQuoteProcessor(final int initialDepth,
final int maxDepth,
final ObjectPool<Quote> pool,
final GapMode gapMode,
final UpdateMode updateMode) {
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
this.unreachableDepthMode = unreachableDepthMode;
this.asks = L2MarketSide.factory(initialDepth, maxDepth, ASK);
this.bids = L2MarketSide.factory(initialDepth, maxDepth, BID);
this.pool = pool;
Expand All @@ -66,8 +71,9 @@ public L2SingleExchangeQuoteProcessor(final long exchangeId,
final int maxDepth,
final ObjectPool<Quote> pool,
final GapMode gapMode,
final UpdateMode updateMode) {
this(initialDepth, maxDepth, pool, gapMode, updateMode);
final UpdateMode updateMode,
final UnreachableDepthMode unreachableDepthMode) {
this(initialDepth, maxDepth, pool, gapMode, updateMode, unreachableDepthMode);
getOrCreateExchange(exchangeId);
}

Expand Down Expand Up @@ -99,6 +105,18 @@ public Quote processL2EntryNewInfo(final L2EntryNewInfo l2EntryNewInfo) {
final L2MarketSide<Quote> marketSide = exchange.get().getProcessor().getMarketSide(side);
final short level = l2EntryNewInfo.getLevel();

if (level >= marketSide.getMaxDepth()) {
switch (unreachableDepthMode) {
case SKIP_AND_DROP:
clear();
return null;
case SKIP:
default:
return null;
}
// Unreachable quote level
}

// TODO: 6/30/2022 need to refactor return value
if (marketSide.isGap(level)) {
switch (gapMode) {
Expand All @@ -115,7 +133,9 @@ public Quote processL2EntryNewInfo(final L2EntryNewInfo l2EntryNewInfo) {
}

final Quote quote;
if (marketSide.isFull()) { // Check side is Full
if (level == marketSide.depth()) {// Add new worst quote
quote = pool.borrow();
} else if (marketSide.isFull()) { // Check side is Full and remove Worst quote
quote = marketSide.removeWorstQuote();
// Attention we remove worst quote bat not remove quote from multi exchange
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,20 @@ public interface BindOrderBookOptionsBuilder {
* @param value initial max depth.
* @return builder
* @see Defaults#MAX_DEPTH
* @see OrderBookType
*/
BindOrderBookOptionsBuilder maxDepth(int value);

/**
* What do we do if we have quote level more than maxDepth?.
* Supported for L2 quote level
*
* @param mode to use.
* @return builder
* @see Defaults#UNREACHABLE_DEPTH_MODE
* @see UnreachableDepthMode
*/
BindOrderBookOptionsBuilder unreachableDepthMode(UnreachableDepthMode mode);

/**
* How large initial pool size for stock exchanges should be?
* Supported for AGGREGATED and CONSOLIDATED order book type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ private Defaults() {
*/
public static final Integer MAX_DEPTH = 32767;

/**
* Default {@link UnreachableDepthMode}.
*/
public static final UnreachableDepthMode UNREACHABLE_DEPTH_MODE = UnreachableDepthMode.SKIP;

/**
* Initial pool size for stock exchanges.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* An enumeration of possible values for configuring the gaps in stock quotes.
* <p>
* Note: GapMode working only with INCREMENTAL_UPDATE
* Supported for L2
*
* @author Andrii_Ostapenko1
* @see com.epam.deltix.timebase.messages.universal.PackageType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ public interface OrderBookOptions {
*/
Option<Integer> getMaxDepth();

/**
* Stock quote unreachableDepth mode.
*
* @return unreachableDepth mode.
*/
Option<UnreachableDepthMode> getUnreachableDepthMode();

/**
* Initial pool size for stock exchanges.
*
Expand Down
Loading

0 comments on commit 9019892

Please sign in to comment.