Пример #1
0
  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);
      }
    }
  }
Пример #2
0
  @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);
    }
  }
Пример #3
0
  @Override
  public void execDetails(int reqId, Contract contract, Execution execution) {
    try {
      if (logger.isDebugEnabled())
        logger.debug(
            "execDetails: {} {} {}",
            new Object[] {reqId, Util.toString(contract), Util.toString(execution)});

      OpenOrder openOrder = openOrdersById.get(execution.m_orderId);
      DateTime dt = DateTimeFormat.forPattern("yyyyMMdd  HH:mm:ss").parseDateTime(execution.m_time);
      if (openOrder != null) {
        int quantityChange = openOrder.isBuy() ? execution.m_shares : -execution.m_shares;
        openOrder.update(quantityChange, execution.m_price, dt);
        logExecution(openOrder, quantityChange);
      } else {
        logger.info(
            "Execution does not match any open order {} {}",
            Util.toString(contract),
            Util.toString(execution));
      }
    } catch (Throwable t) {
      // Do not allow exceptions come back to the socket -- it will cause
      // disconnects
      logger.error(t.getMessage(), t);
    }
  }
Пример #4
0
  @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);
    }
  }
Пример #5
0
 @Override
 public List<OpenOrder> getOpenOrders(Symbol symbol, OrderType orderType) {
   List<OpenOrder> openOrders = new ArrayList<OpenOrder>(openOrdersById.size());
   for (OpenOrder o : openOrdersById.values()) {
     if ((symbol == null || symbol.equals(o.getSymbol()))
         && (orderType == null || orderType.equals(o.getType()))) {
       openOrders.add(o);
     }
   }
   return openOrders;
 }
Пример #6
0
 @Override
 public OpenOrder getOpenOrder(Symbol symbol, OrderType orderType) {
   if (symbol == null) {
     throw new IllegalArgumentException("Symbol cannot be null");
   }
   if (orderType == null) {
     throw new IllegalArgumentException("OrderType cannot be null");
   }
   for (OpenOrder o : openOrdersById.values()) {
     if (symbol.equals(o.getSymbol()) && orderType.equals(o.getType())) {
       return o;
     }
   }
   return null;
 }
Пример #7
0
  @Override
  public void error(int reqId, int errorCode, String errorMsg) {
    try {
      Object req = openOrdersById.get(reqId);
      if (req == null) {
        super.error(reqId, errorCode, errorMsg);
        return;
      }
      OpenOrder openOrder = (OpenOrder) req;

      String message = errorCode + ": " + errorMsg;
      lastMessage = message;

      switch (errorCode) {
        case 161:
          // 161: Cancel attempted when order is not in a cancellable
          // state
          logger.warn("Received error for {}: {}", openOrder, message);
          break;
        case 202:
          // 202: Order Cancelled
          break;
        case 110:
          // 110: price does not conform to the minimum price variation
          // for this
          // contract
        default:
          openOrder.setFailed();
          openOrdersById.remove(reqId);
          logger.warn("Received error for {}: {}", openOrder, message);
      }
    } catch (Throwable t) {
      // Do not allow exceptions come back to the socket -- it will cause
      // disconnects
      logger.error(t.getMessage(), t);
    }
  }
Пример #8
0
 protected void logTrade(
     OpenOrder openOrder, int position, double costBasis, double realized, double unrealized) {
   Object[] params =
       new Object[] {
         openOrder.getFillDate(),
         "TRADE",
         openOrder.getAction(),
         openOrder.getType(),
         openOrder.getQuantityFilled(),
         openOrder.getSymbol(),
         openOrder.getSymbol().getCurrency(),
         openOrder.getAvgFillPrice(),
         position,
         Util.round(costBasis, 4),
         Util.round(realized, 4),
         Util.round(unrealized, 4),
         Util.round(openOrder.getCommission(), 4),
         openOrder.getReference() != null ? openOrder.getReference() : "",
         accountCode
       };
   blotter.info(
       MarkerFactory.getMarker("TRADE"), "{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}", params);
 }
Пример #9
0
 protected void logExecution(OpenOrder openOrder, int quantity) {
   Object[] params =
       new Object[] {
         openOrder.getFillDate(),
         "EXEC",
         openOrder.getAction(),
         openOrder.getType(),
         quantity,
         openOrder.getSymbol(),
         openOrder.getSymbol().getCurrency(),
         openOrder.getLastFillPrice(),
         "",
         "",
         "",
         "",
         "",
         openOrder.getReference() != null ? openOrder.getReference() : "",
         accountCode
       };
   blotter.info(
       MarkerFactory.getMarker("EXECUTION"),
       "{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}",
       params);
 }
Пример #10
0
 @Override
 public synchronized void cancelOrder(OpenOrder openOrder) {
   checkConnected();
   socket.cancelOrder(openOrder.getOrderId());
 }
Пример #11
0
  @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;
  }
Пример #12
0
 protected Order makeOrder(OpenOrder openOrder) {
   Order order = new Order();
   order.m_orderRef = openOrder.getReference() != null ? openOrder.getReference() : "";
   order.m_overridePercentageConstraints = true;
   order.m_totalQuantity = Math.abs(openOrder.getQuantity());
   if (openOrder.isBuy()) {
     order.m_action = "BUY";
   } else if (openOrder.isSell()) {
     order.m_action = "SELL";
   }
   if (openOrder.isMarket()) {
     order.m_orderType = "MKT";
   } else if (openOrder.isLimit()) {
     order.m_orderType = "LMT";
     order.m_lmtPrice = openOrder.getPrice();
   } else if (openOrder.isStopMarket()) {
     order.m_orderType = "STP";
     order.m_triggerMethod = 8; // midpoint
     order.m_auxPrice = openOrder.getStopPrice();
   } else if (openOrder.isStopLimit()) {
     order.m_orderType = "STPLMT";
     order.m_triggerMethod = 8; // midpoint
     order.m_lmtPrice = openOrder.getPrice();
     order.m_auxPrice = openOrder.getStopPrice();
   } else if (openOrder.isTrailMarket()) {
     order.m_orderType = "TRAIL";
     order.m_triggerMethod = 8; // midpoint
     order.m_auxPrice = openOrder.getTrailStopOffset();
   } else if (openOrder.isTrailLimit()) {
     order.m_orderType = "TRAILLMT";
     order.m_triggerMethod = 8; // midpoint
     order.m_lmtPrice = openOrder.getPrice();
     order.m_trailStopPrice = openOrder.getStopPrice();
     order.m_auxPrice = openOrder.getTrailStopOffset();
   }
   return order;
 }