Introduction

In addition to the REST APIs, the E*TRADE Developer Platform provides a streaming data service that can push data out to an application, rather than requiring the application to poll for the data. This streaming data service is based on the Comet web-service architecture, which uses delayed responses or very long responses to break out of HTTP's single-page, request-response model.

The application begins a session by submitting an HTTP request to the streaming data service. The server sends back a response (containing one or more notifications) when triggered by relevant events, such as a completed order. The application issues fresh HTTP requests as needed to keep the session going.

In this way the application receives low-latency data, without any special message protocols, in a way that does not involve a lot of network traffic or processing.

E*TRADE uses this architecture to push notifications of changes in order status.

Notifications

Notifications are requested by the application on a per-account basis. Notifications are sent only for orders placed under the specified accounts.

A notification about a change in order status contains information about the specific order only; it does not contain information about other orders for the account. If an application requests notifications for an account, and places five orders using that account, then when those orders are executed at least five separate notifications are triggered.

Notification events
Notifications are triggered by changes to order status, including the following:
Event Description
Partial completion Order has been partially executed. The status is still live, but the quantity executed has changed.
Completion Order has been filled.
Cancellation Order has been cancelled.
Rejection Order has been rejected.
Notification details
Item Description
Account Number Numeric account ID
Order Number Sequential order number, unique within account
Order Status Order status: open, pending, executed, cancelled, cancel-requested, etc.
Symbol Security symbol
Order Possible values are:
• BUY
• SELL
• SHORT
• COVER
• BUY_TO_OPEN
• SELL_TO_CLOSE
• SELL_TO_OPEN
• BUY_TO_CLOSE
Quantity Quantity specified in the order. For stocks, this is a number of shares. For mutual funds, this is a dollar value or, if selling the entire position, "All I Own".
Quantity Filled Quantity that has been executed.
Price Possible values are:
• Market
• Market_On_Close
• Limit
• Stop
• Stop_Limit
Price Price for price type
Event Type See event types listed below.
Sample Notification

Below is a sample order update message.

<class>com.etrade.lmq.orderstatus.common.dto.OrderStatusResponse</class>
<quantityFilled>0</quantityFilled>
<accountNumber>83531504</accountNumber>
<price>0</price>
<symbol>AAPL</symbol>
<legStatus>OPEN</legStatus>
<orderNumber>130</orderNumber>
<priceType>TRIGGER_UNSPECIFIED</priceType>
<orderAction>BUY</orderAction>
<quantity>5</quantity>
<eventType>OPEN</eventType>
<orderStatus>OPEN</orderStatus>
Complex orders

The following rules describe how complex orders are treated by the streaming service.

  • Each leg of an order is pushed as the update is returned from the market. The legs can be pushed separately. Applications can correlate legs by using the orderNumber included in the update.
  • For Buy Writes, the order status update shows both legs of the order. For partial executions, the quantity filled is pushed for both the stock and the option.
  • For Spreads, the order status update shows both legs of the order. For partial executions, the quantity filled is pushed for both legs.
Trailing stops and conditional orders

For trailing stops and conditional orders, an order status is sent if those orders are triggered and executed. If a trailing stop is triggered, an order is sent to the market to execute (triggered orders are market orders), and the notification alerts the user once the order is executed (whether fully or partially).

When orders are cancelled (for example, "One-Cancels-All" orders), or when a user cancels a conditional order, the order is cancelled within the E*TRADE system and not at the exchange. Since the cancellation is a result of user action, no update message is sent.

Note that "Live" and "Open" are not valid statuses. Push events only occur when there is an execution (full or partial), cancellation, or rejection from the exchange.

Using Comet

Our Comet web architecture uses the Bayeux protocol as described in Comet documentation. There are significant differences between Comet 1.x and Comet 2.x. In the E*TRADE API v0, Comet 1.x is supported.

We use the CometD implementation, and to use the service you'll need to use the CometD libraries, available as shown here:
Resource Link
CometD libraries for JavaScript and Java http://cometd.org/documentation
CometD documentation for JavaScript http://cometd.org/documentation/cometd-javascript
CometD documentation for Java http://cometd.org/documentation/cometd-java
Comet service

The Comet service of the E*TRADE Developer Platform is accessible at this URL:

https://etwspush.etrade.com/apistream/cometd/oauth/

This service requires OAuth authorization, which is detailed in a separate section of the Developer Platform documentation. Requests to the service must include an OAuth header - i.e., the consumer key, access token, timestamp, nonce, signature method, and signature. If the OAuth token expires during the session (e.g., at midnight US Eastern time), subsequent HTTP requests from the application return authorization errors, not streaming updates, so updates effectively cease with the first update after the token expires - even though the subscription to the service is technically still in effect.

The general approach is to connect to the Comet service, subscribe to the update and error channels, specify which accounts to listen to for activity, and use callback functions to handle the messages that come in.

Channels
Here is a list of the channels used.
Channel Published by Description
/service/etws/join client Used for subscribing to channels, i.e., the order update channel and the two error channels
/etws/error service Used for higher-level error messages
/service/etws/error service Used for errors specific to the subscription
/service/etws/accountlisten client Used for specifying which accounts to listen to for order activity
/service/etws/accountunlisten client Used for specifying accounts to stop listening to
/service/etws/orderupdate service Used by service to transmit order status updates
Connecting requires that you publish to /service/etws/join with one of these two options:
Action Description
join cometd.publish("/service/etws/join", { type: 'join'});
reconnect cometd.publish("/service/etws/join", { type: 'reconnect'});
Sample code

The following JavaScript examples demonstrate the basics of:

  • connecting to the service
  • subscribing to error messages and order status updates
  • listening to specific accounts for activity
  • unlistening to specific accounts

These samples require the CometD JavaScript library to work.

Connecting to the Service

This code establishes and re-establishes the connection to the service.

function _initialize()
{
  _cometd = $.cometd; // Use the default Comet object
  _cometUrl = "https://etwspush.etrade.com/apistream/cometd/oauth/";
  _metaSubscriptions = [];
  $.each(_metaSubscriptions, function(index, subscription) {
    _cometd.removeListener(subscription)
  });
  _metaSubscriptions.push(_cometd.addListener('/meta/handshake', this, _metaHandshake));
  _metaSubscriptions.push(_cometd.addListener('/meta/connect', this, _metaConnect));
  var oauthHeader = {Authorization: header};
  _cometd.init({url: _cometUrl, requestHeaders: oauthHeader});
}

function _metaHandshake(message)
{
  _handshook = message.successful;
  _connected = false;
}

function _metaConnect(message)
{
  var wasConnected = _connected;
  _connected = message.successful;
  if (wasConnected)
  {
    if (_connected)
    {
      // Normal operation, a long poll that reconnects
    }
    else
    {
      // Disconnected
    }
  }
  else
  {
    if (_connected)
    {
      // Connected
      baseSubscribe();
      if(_firstConnection){
        _cometd.publish("/service/etws/join", { type:'join'});
      }else{
        _cometd.publish("/service/etws/join", { type:'re-connect'});
      }
      _firstConnection = false;
    }
    else
    {
      // Could not connect
    }
  }
}
Handling Errors and Updates

This sample shows how callback functions are used to process messages from the error and orderupdate channels, described in the table of channels above.

function handleError(message)
{
  //Handle error
}

function handleUpdate(message)
{
  //Handle order status update message
}
Subscribing to Notification Channels

This sample code subscribes to the channels for system errors, service errors, and order status updates, using the subscribe() method from the Comet JavaScript library several times in a batch.

function baseSubscribe(){
  _cometd.startBatch();
  channel = _cometd.subscribe("/etws/error", this, handleError);
  channel = _cometd.subscribe("/service/etws/error", this, handleError);
  channel = _cometd.subscribe("/service/etws/orderupdate", this, handleUpdate);
  _cometd.endBatch();
}
Listening to Specific Accounts

Subscribing to the order-update channel is not sufficient for receiving order status updates. You must also specify which accounts to listen to. This is done by publishing to accountlisten. Specify a single account or a comma-separated list of accounts under the name "accounts", as shown in these examples.

Examples
cometd.publish("/service/etws/accountlisten", {accounts:83405188});
cometd.publish("/service/etws/accountlisten", {accounts:83405188,83405557,83412346});
Unlistening to Specific Accounts

To stop listening to order status updates for one or more accounts, publish to accountunlisten. Specify a single account or a comma-separated list of accounts under the name "accounts", as shown in these examples.

Examples
cometd.publish("/service/etws/accountunlisten", {accounts:83405188});
cometd.publish("/service/etws/accountunlisten", {accounts:83405188,83405557,83412346})
Sample Response

Here is a sample order update message:

{
  "class":"com.etrade.lmq.orderstatus.common.dto.OrderStatusResponse",
  "quantityFilled":0,
  "accountNumber":"83531504",
  "price":0,
  "symbol":"AAPL",
  "legStatus":"OPEN",
  "orderNumber":130,
  "priceType":"TRIGGER_UNSPECIFIED",
  "orderAction":"BUY",
  "quantity":5,
  "eventType":"OPEN",
  "orderStatus":"OPEN"
}
PLEASE READ THE IMPORTANT DISCLOSURES BELOW

By using E*TRADE API ("API") and accepting the terms of the Application Programming Interface License Agreement and the Application Programming Interface User Agreement, you agree that API may employ security policies, procedures and systems of Third Party providers which may or may not be less stringent and secure than the policies, procedures and systems of E*TRADE Securities LLC ("E*TRADE") or its affiliates. Material provided on API may have been produced by independent third parties not affiliated or endorsed by E*TRADE or its affiliates ("Third Party"). To the extent that API or Third Party providers express opinions or make recommendations, you understand that such opinions or recommendations are expressed by the Third Party provider and are not the opinions or recommendations of E*TRADE or its affiliates. E*TRADE is not responsible for the accuracy of market data displayed on API or made available by Third Party providers. There may be latency between the time an order (or other information) is submitted from API and the time the order is received by E*TRADE. The E*TRADE Two Second Execution Guarantee or any similar guarantee does not apply for orders placed through API and Third Party provider web sites. The E*TRADE CompleteTM Protection Guarantee does not apply. Orders created and submitted through API are not vetted until they are received by E*TRADE. It is possible that E*TRADE may reject an order placed through API. Please see the Application Programming Interface License Agreement and the Application Programming Interface User Agreement for more information.


The E*TRADE family of companies provides financial services including trading, investing, and related banking products and services to retail investors.


Securities products and services offered by E*TRADE Securities LLC, Member FINRA/SIPC.


System response and account access times may vary due to a variety of factors, including trading volumes, market conditions, system performance, and other factors.