@Override public void openOrder(int orderId, Contract contract, Order order, OrderState orderState) { try { if (logger.isDebugEnabled()) logger.debug( "openOrder: {} {} {} {}", new Object[] { orderId, Util.toString(contract), Util.toString(order), Util.toString(orderState) }); OpenOrder openOrder = openOrdersById.get(orderId); if (openOrder != null) { if ((openOrder.isFilled() || (!openOrder.isOpen() && openOrder.getQuantityFilled() > 0)) && orderState.m_commission != Double.MAX_VALUE) { closeOpenOrder(openOrder, orderState.m_commission); } } else { if ("PendingSubmit".equals(orderState.m_status) || "PreSubmitted".equals(orderState.m_status) || "Submitted".equals(orderState.m_status)) { openOrder = toOpenOrder(contract, order); openOrdersById.put(orderId, openOrder); logger.info("Added {}", openOrder); } } } catch (Throwable t) { logger.error(t.getMessage(), t); } }
private void closeOpenOrder(OpenOrder openOrder, double commissionAmount) { openOrdersById.remove(openOrder.getOrderId()); if (Double.isNaN(commissionAmount) || commissionAmount <= 0.0) { commissionAmount = commission.calculate(openOrder.getQuantityFilled(), openOrder.getAvgFillPrice()); } openOrder.setCommission(commissionAmount); logger.info("{} {}", openOrder.isFilled() ? "Filled" : "Partially filled", openOrder); Position position = portfolio.getPosition(openOrder.getSymbol()); double[] values = position.update( openOrder.getFillDate(), openOrder.getQuantityFilled(), openOrder.getAvgFillPrice(), openOrder.getCommission()); logTrade(openOrder, position.getQuantity(), values[0], values[1], values[2]); for (OrderListener listener : orderListeners) { try { listener.onOrderFilled(openOrder, position); } catch (Throwable t) { logger.error(t.getMessage(), t); } } }
@Override public void orderStatus( int orderId, String status, int filled, int remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, String whyHeld) { try { if (logger.isDebugEnabled()) logger.debug( "orderStatus: {} {} {} {} {} {} {} {} {} {}", new Object[] { orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld }); if ("Cancelled".equals(status)) { OpenOrder openOrder = openOrdersById.remove(orderId); if (openOrder != null) { openOrder.setCancelled(); logger.info("Cancelled {}", openOrder); for (OrderListener listener : orderListeners) { try { listener.onOrderCancelled(openOrder); } catch (Throwable t) { logger.error(t.getMessage(), t); } } if ((openOrder.isFilled() || (!openOrder.isOpen() && openOrder.getQuantityFilled() > 0))) { closeOpenOrder(openOrder, 0); } } else { logger.warn("Cancelled order {}, no matching order found!", orderId); } } } catch (Throwable t) { // Do not allow exceptions come back to the socket -- it will cause // disconnects logger.error(t.getMessage(), t); } }
@Override public synchronized OpenOrder placeOrder( Symbol symbol, OrderType type, int quantity, double price, double stopPercent, String reference) { if (quantity == 0) { throw new IllegalArgumentException(String.format("Invalid quantity %s", quantity)); } if ((OrderType.LIMIT.equals(type) || OrderType.STOP_LIMIT.equals(type) || OrderType.TRAIL_LIMIT.equals(type)) && price <= 0) { throw new IllegalArgumentException(String.format("Invalid limit order price %s", price)); } if ((OrderType.STOP_MARKET.equals(type) || OrderType.STOP_LIMIT.equals(type) || OrderType.TRAIL_MARKET.equals(type) || OrderType.TRAIL_LIMIT.equals(type)) && stopPercent <= 0) { throw new IllegalArgumentException( String.format("Invalid stop order with stop percent %s", stopPercent)); } checkConnected(); OpenOrder openOrder = getOpenOrder(symbol, type); if (openOrder != null && !openOrder.isFilled() && !openOrder.isCancelled()) { throw new IllegalStateException( "OpenOrder for same strategy, symbol and type already exists: " + openOrder); } DateTime now = new DateTime(); double stopPrice = -1; double trailingStopOffset = -1; if (OrderType.STOP_MARKET.equals(type) || OrderType.STOP_LIMIT.equals(type) || OrderType.TRAIL_MARKET.equals(type) || OrderType.TRAIL_LIMIT.equals(type)) { Tick t = getLastTick(symbol); if (t == null) { t = getLastTick(symbol, now); if (t == null) { throw new IllegalStateException( String.format("Cannot set stop without tick data for symbol %s", symbol)); } } trailingStopOffset = Util.round(t.getMidPrice() * stopPercent, 10.0); if (quantity < 0) { stopPrice = t.getMidPrice() - trailingStopOffset; } else { stopPrice = t.getMidPrice() + trailingStopOffset; } stopPrice = Util.round(stopPrice, 2.0); } int orderId = nextValidOrderId.getAndIncrement(); openOrder = new OpenOrder( orderId, symbol, type, quantity, price, stopPrice, trailingStopOffset, new DateTime(), reference); openOrdersById.put(orderId, openOrder); Contract contract = makeContract(symbol); Order order = makeOrder(openOrder); logger.info("Placing order {}", openOrder); socket.placeOrder(orderId, contract, order); for (OrderListener listener : orderListeners) { try { listener.onOrderPlaced(openOrder); } catch (Throwable t) { logger.error(t.getMessage(), t); } } return openOrder; }