- How to import custom API modules into Bookmap
- API documentation (javadoc)
- Developing with Bookmap API (step-by-step)
- Receive trades as Times & Sales with ability to "reconstruct" the size of the aggressive order
- Receive full market depth as Market-by-price (MBP) or Market-by-order (MBO)
- Unique: Receive recent history of market depth data
- Draw indicators on chart or indicators panel with unlimited resolution
- Implement automatic trading strategies
- Create custom settings panel
- Implement custom windows and widgets (detached from Bookmap chart)
- Simple, fast, and transparent
- Free access to API for all Bookmap users
- Use any Java supporting IDE for development
- Offer your custom module on marketplace (in progress) for other traders
- It's recommended to keep Bookmap updated.
- Your Bookmap license should be enabled for API. Until the self-enabling mechanism is ready, please send a request to [email protected] and include either your license key or Bookmap registration email.
Bookmap is required to block the API access for dxFeed US stocks data. It's a requirement of dxFeed and US stock exchanges because API gives access to "Non-display data". For further information please contact dxFeed directly via [email protected].
Introduction
The new Bookmap API (previously called L1/L2) is free for all Bookmap customers even for those who prefer the free Bookmap package. It allows seamless development of custom modules such as indicators, automated trading strategies, data export and recording, and more. These custom modules can be used with any connectivity without any change. Note: For Bookmap Connect or Quant solutions please visit the corresponding forum.
The API was developed by Bookmap team based on its experience with dozens of API's of trading platforms, data vendors, and exchanges. The resulting API combines unprecedented levels of both simplicity and transparency. This gives users an ability to develop within minutes or hours custom modules that utilize truly unfiltered and unaggregated market data (including full market depth) and may use complete trading functionality. The main advantages of Bookmap API are:
- Simplicity (see examples below).
- Transparency. For instance, custom modules that require market depth data may receive it from the beginning of the session and continue in real-time, i.e. not only from the moment of custom module activation. This is a unique feature, not available in other trading platforms API such as NT8.
- Performance. Bookmap can support hundreds of indicators and together they may add many millions of data points on a typical daily chart without noticeably affecting Bookmap performance.
The example package contains different types of custom modules.
Weighted Midprice indicator
This indicator provides a basic demonstration of Bookmap API usage by drawing a Size-Weighted mid-price on the main Bookmap chart. It subscribes to market depth data and manages itself the Order book. Whenever a trade occurs, it calculates the size-weighted mid-price and updates the indicator line, but it doesn't use the trade data itself. Alternatively, it could add new points every custom time period such as 100 milliseconds by implementing IntervalListener interface. Also, since it relies only on best bid/ask levels, it could implement BboListener interface instead of DepthDataListener. Here is this simplest indicator in action:
And here is its entire source code. Note that instead of this particular functionality, a custom module could similarly easy record the data in a custom format or export it to Excel in real-time, perform some other computations, or perhaps draw more than one indicator line.
Code: Select all
public class WeightedMidprice implements CustomModule, TradeDataListener, DepthDataListener {
Indicator indicator;
OrderBook orderBook = new OrderBook();
@Override
public void initialize(String alias, InstrumentInfo info, Api api) {
indicator = api.registerIndicator("Weighted Midprice", GraphType.PRIMARY, Color.WHITE);
}
@Override
public void onDepth(boolean isBid, int price, int size) {
orderBook.onDepth(isBid, price, size);
}
@Override
public void onTrade(double price, int size, TradeInfo tradeInfo) {
double bestBid = (double) orderBook.bids.firstKey();
int bestBidSize = orderBook.bids.firstEntry().getValue();
double bestAsk = (double) orderBook.asks.firstKey();
int bestAskSize = orderBook.asks.firstEntry().getValue();
double weightedMidprice = (bestBid * bestAskSize + bestAsk * bestBidSize) / (bestBidSize + bestAskSize);
indicator.addPoint(weightedMidprice);
}
}
Code: Select all
public class OrderBookBase {
public TreeMap<Integer, Integer> bids = new TreeMap<>(Collections.reverseOrder());
public TreeMap<Integer, Integer> asks = new TreeMap<>();
public int onDepth(boolean isBid, int price, int size) {
Map<Integer, Integer> book = isBid ? bids : asks;
Integer sizePrevious = (size == 0) ? book.remove(price) : book.put(price, size);
return (sizePrevious == null) ? 0 : sizePrevious;
}
}
Displays the total size at 10 bid price levels and 10 ask price levels. It demonstrates how to receive periodic updates via onBar() function which provides actual for the Bar's close Order Book and a Bar object. In addition to regular OHLCV, the Bar objects contains separate Buy and Sell volume and VWAP, and the total VWAP. In this example our indicator subscribes to bars period of 100 milliseconds and recalculates the Bid/Ask liquidity on every update. Here is the resulting indicator as two lines displayed on the indicators panel.
And here is the entire source code of this Liquidity Tracker indicator. In this case no additional code was necessary.
Code: Select all
public class LiquidityTracker implements CustomModule, BarDataListener {
Indicator indicatorBid;
Indicator indicatorAsk;
int depth = 10; // number of price levels
@Override
public void initialize(String alias, InstrumentInfo info, Api api) {
indicatorBid = api.registerIndicator("Liquidity Bid", GraphType.BOTTOM, Color.GREEN);
indicatorAsk = api.registerIndicator("Liquidity Ask", GraphType.BOTTOM, Color.RED);
}
@Override
public long getBarInterval() {
return Intervals.INTERVAL_100_MILLISECONDS;
}
@Override
public void onBar(OrderBook orderBook, Bar bar) {
int bidSizeDepth = getBookSizeSum(orderBook, true);
indicatorBid.addPoint(bidSizeDepth);
int askSizeDepth = getBookSizeSum(orderBook, false);
indicatorAsk.addPoint(askSizeDepth);
}
private int getBookSizeSum(OrderBook orderBook, boolean isBid) {
TreeMap<Integer, Long> levels = isBid ? orderBook.getBidMap() : orderBook.getAskMap();
Integer price = levels.firstKey();
int size = 0;
int n = Math.min(depth, levels.size());
for (int i = 0; i < n; i++) {
Long q = levels.get(price);
if (q != null) {
size += q;
}
price += isBid ? -1 : 1;
}
return size;
}
}
API modules can create entirely custom settings panel. It may include any control and display components including an ability to launch another Java application from it. Here is an example custom settings panel from ATR Trailing Stop indicator.
Its code is published in the example project. The API also provides an interface for saving the settings of custom modules and getting them when the module is launched again:
Code: Select all
public static class Settings {
// various settings of the custom module
}
Settings settings;
Api api;
@Override
public void initialize(String alias, InstrumentInfo info, Api api, InitialState initialState) {
this.api = api;
this.settings = api.getSettings(Settings.class);
}
@Override
public void stop() {
api.setSettings(settings); // save settings before exit
}