示例#1
0
  @Override
  public OrderResult Execute(Order order, IUserBalance balanceService, IStockInfo stockService) {
    OrderResult result = new OrderResult(order);
    Date submitted = order.getDateSubmitted();
    if (today.equals(submitted)) {
      StockInfo info = stockService.requestCurrentStockData(order.getStock().getStockSymbol());
      if (info != null) {
        attemptTrade(
            result,
            balanceService,
            stockService,
            today,
            info.getDayLow(),
            info.getDayHigh(),
            info.getVolume());
      }
    } else // SELL
    {
      Date lastEvaluated = order.getLastEvaluated();
      if (order
          .getDateSubmitted()
          .equals(
              lastEvaluated)) { // do not try to evaluate again the first day the Limit order was
                                // submitted
        lastEvaluated = getDateOneDayInTheFuture(lastEvaluated);
      }

      List<HistoricalStockInfo> infos =
          stockService.requestDailyHistoricalStockData(
              order.getStock().getStockSymbol(), lastEvaluated);
      if (infos != null && infos.size() > 0) {
        HistoricalStockInfo info;
        for (int i = infos.size() - 1; i >= 0; --i) {
          info = infos.get(i);
          attemptTrade(
              result,
              balanceService,
              stockService,
              info.getDate(),
              info.getDayLow(),
              info.getDayHigh(),
              info.getVolume());
          if (result.getCompleted() || result.getCancelled()) {
            break;
          }
        }
      }
    }

    return result;
  }
示例#2
0
  private void attemptTrade(
      OrderResult result,
      IUserBalance balanceService,
      IStockInfo stockService,
      Date date,
      double dayLow,
      double dayHigh,
      int volume) {
    Order order = result.getOrder();

    float quantity = order.getQuantity();
    if (quantity > volume) {
      return;
    }

    try {
      if (order.getAction() == OrderAction.BUY) {
        if (order.getLimitPrice() < dayLow) { // price was too high to buy today
          return;
        }

        double orderTotal = quantity * dayLow;
        double accountBalance = balanceService.getBalance(order.getUserName());
        if (accountBalance <= orderTotal) {
          quantity = (int) (accountBalance / dayLow);
          orderTotal = quantity * dayLow;
          result.setNote("Reduced quantity from " + order.getQuantity() + " to " + quantity);
        }

        if (quantity > 0 && accountBalance >= orderTotal) {
          try {
            balanceService.updateBalance(order.getUserName(), accountBalance - orderTotal);
            result.setCompleted(true);
            result.setQuantity(quantity);
            result.setSharePrice(dayLow);
            result.setDateTime(date);
          } catch (Exception ex) {
            // ignore
          }
        } else { // account balance is zero or not enough to purchase even one share
          result.setCancelled(true);
          result.setDateTime(date);
          result.setNote("Insufficient funds");
        }
      } else {
        if (order.getLimitPrice() > dayHigh) { // price was too low to sell today
          return;
        }

        double orderTotal = quantity * dayHigh;
        double accountBalance = balanceService.getBalance(order.getUserName());
        try {
          balanceService.updateBalance(order.getUserName(), accountBalance + orderTotal);
          result.setCompleted(true);
          result.setQuantity(quantity);
          result.setSharePrice(dayHigh);
          result.setDateTime(date);
        } catch (Exception ex) {
          // ignore
        }
      }
    } finally {
      // these apply on the first historical trade attempt (should be the same day the order was
      // submitted)
      if (!result.getCompleted() && !result.getCancelled()) {
        if ((order.getTimeInForce() == TimeInForce.DAY
                || order.getTimeInForce() == TimeInForce.FILLORKILL)
            && (today.after(date)
                || (today.equals(date) && !stockService.isWithinTradingHours()))) { // Cancel order
          result.setCancelled(true);
          result.setDateTime(date);
          result.setNote("Market closed");
        }

        if (order.getTimeInForce() == TimeInForce.IMMEDIATEORCANCEL) { // Cancel order
          result.setCancelled(true);
          result.setDateTime(date);
          result.setNote("Unable to fill immediately");
        }

        if (order.getTimeInForce() == TimeInForce.GOODUNTILCANCELED) {
          long diffInDays =
              (date.getTime() - order.getDateSubmitted().getTime()) / (1000 * 60 * 60 * 24);
          if (diffInDays > 120) {
            result.setCancelled(true);
            result.setDateTime(date);
            result.setNote("120 day limit reached");
          }
        }
      }
    }
  }