package net.parasec.ob; import net.parasec.trading.bitstampws.BitstampClient; import net.parasec.trading.bitstampws.BitstampMessageHandler; import net.parasec.trading.bitstampws.Client; import net.parasec.trading.bitstampws.OrderEvent; import net.parasec.trading.ticker.core.wire.Direction; import net.parasec.trading.ticker.core.wire.OrderInfo; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; import org.apache.log4j.Level; import org.fusesource.jansi.AnsiConsole; import static org.fusesource.jansi.Ansi.*; public final class OrderBookStream implements BitstampMessageHandler<OrderEvent> { private final OrderBook ob = new LinkedOrderBook(); private String venue; private String symbol; private boolean real_time; public OrderBookStream(String venue, String symbol, boolean real_time) { this.venue = venue; this.symbol = symbol; this.real_time = real_time; } public OrderBook getOb() { return ob; } private int getLimitPrice(double price, String symbol) { return Util.asCents(price); } private long getVolume(double volume, String symbol) { return Util.asSatoshi(volume); } @Override public void onMessage(OrderEvent orderEvent) { OrderEvent.Order order = orderEvent.order; Direction direction = order.type == 0 ? Direction.BUY : Direction.SELL; long localTs = System.currentTimeMillis(); String exchangeOrderId = Long.toString(order.id); int limitPrice = getLimitPrice(order.price, symbol); long volume = getVolume(order.amount, symbol); long exchangeTimestamp = order.microTimestamp / 1000; OrderInfo orderInfo = new OrderInfo(exchangeOrderId, limitPrice, volume, exchangeTimestamp); net.parasec.trading.ticker.core.wire.OrderEvent.State state; switch (orderEvent.event) { case ORDER_CREATED: state = net.parasec.trading.ticker.core.wire.OrderEvent.State.CREATED; ob.addOrder(new net.parasec.trading.ticker.core.wire.OrderEvent(state, direction, symbol, venue, localTs, orderInfo)); break; case ORDER_UPDATED: state = net.parasec.trading.ticker.core.wire.OrderEvent.State.UPDATED; ob.modOrder(new net.parasec.trading.ticker.core.wire.OrderEvent(state, direction, symbol, venue, localTs, orderInfo)); break; case ORDER_DELETED: state = net.parasec.trading.ticker.core.wire.OrderEvent.State.DELETED; ob.delOrder(new net.parasec.trading.ticker.core.wire.OrderEvent(state, direction, symbol, venue, localTs, orderInfo)); } if (real_time) { AnsiConsole.system_out.println(ansi().a(ob).reset()); } System.err.println(ob.getState().toCsv()); } public static void main(final String[] args) throws Exception { BasicConfigurator.configure(); Logger.getRootLogger().setLevel(Level.ERROR); AnsiConsole.systemInstall(); int console_height = Integer.parseInt(args[0]); boolean real_time = Boolean.parseBoolean((args[1])); String symbol = args[2]; OrderBookStream orderBookStream = new OrderBookStream("bitstamp", symbol, real_time); orderBookStream.getOb().setConsoleHeight(console_height); Client client = new BitstampClient(); String subscriptionId = client.subscribeOrders(symbol, orderBookStream); try { OrderBook ob = orderBookStream.getOb(); while (true) { Thread.sleep(1000); if (!real_time) { AnsiConsole.system_out.println(ansi().eraseScreen(Erase.ALL).a(ob).reset()); } } } catch (InterruptedException e) { } } }