Skip to content

Placing Trade Orders on Blueshift®

Orders, trades, positions

On Blueshift®, we interpret the terms order, trade and position in a certain way. An order is what is generated by your trading algorithm. It is an intent to trade. An order, once created by a strategy is sent to a broker (either the backtesting engine or a real live broker) for execution. At the broker's end, this order will go through some checks and will be executed. This leads to some specific buying and selling - these are what we call trades. A single order can potentially generate multiple trades. As an outcome of these trades, your strategy ends up with certain assets - these are called positions.

It is natural to track orders by their order IDs, trades by their trade IDs and positions by their underlying assets.

On Blueshift® we do not always track the trades and support may not be available for all brokers. Orders and positions are the key metrics by which a strategy keeps itself aware of its exposure.

Placing orders

Trading capacity

Ordering functions will not check the capacity of the account to validate the order (e.g. cash, margin requirements etc.). You must check it yourself before placing any order.

To place an order, strategy needs to specify an asset, and the other order parameters. The most basic ordering function is order. It has the following signature

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
        Args:
            ``asset (object)``: asset on which the order to be placed.

            ``quantity (int)``: amount (> 0 is buy, < 0 is sale)

            ``limit_price (float)``: A limit price specification

            ``stop_price (float)`` : Stop-loss price specification (currently ignored)

        Returns:
            Str. An order ID as returned by the broker after a 
            successful order is placed. Else returns None.

Always check if the return value is None or a valid order id. We return None for the following cases

  • The order was invalid and was not placed with the broker
  • The order type was market and resulted in unwinding of existing position(s). This is the case where the broker does not support fungible orders1. In such cases, only an order for the residual amount will be created (if any) and order ID of the same will be returned.

At present only limit and market orders are supported. Stop loss specification will be ignored. The handling of limit and stop price specification is totally implementation depended. In case the broker supports limit orders, limit_price will be effective. In most current versions of broker implementation, the stop_price is ignored.

1
2
3
asset = symbol("AAPL")
order_id = order(asset, 10)   # a market order for 10 stocks of Apple Inc.
order_id = order(asset, 10, 208.8)   # a limit order at 208.8 or better.

The code snippets above places two orders, one at the market, the other at a limit price.

Order sizing functions

While order is the base function to trade, there are a bunch of other helper functions that does automatic order sizing. Most quant strategies will find this more useful than the raw order functions.

  • order_value(asset, value, limit_price): Place order for an asset with a specifc dollar value (instead of quantity).

  • order_percent(asset, percent, limit_price): Place order for an asset with a specifc precent of current portfolio value.

  • order_target(asset, quantity, limit_price): Place order for an asset with to target a specific quantity. If the existing amount in portfolio is less than this, buy orders will be generated. If it is more, sell orders will be placed. Else no change.

  • order_target_value(asset, value, limit_price): Similar to above, but target a particular dollar amount instead of quantity.

  • order_target_percent(asset, percent, limit_price): For targetting a position worth a specific percent of the portfolio value.

The last function - order_target_percent - is very useful. It combines the targetting along with automated sizing based on current portfolio value.

Automatic order sizing

These order sizing functions will take in to account current position, but not outstanding open orders. Be cautious.

Fetching and canceling open orders

To fetch the current open orders (orders still to be executed fully and are not cancelled/ rejected), use the API function get_open_orders. This will return a dict (a Python dictionary) with order IDs as the keys and order object as the value. To cancel the remaining part of an open order, use the API function cancel_order. Example below:

1
2
3
open_orders = get_open_orders()
for order_id in open_orders:
    cancel_order(order_id)

In many situations, this code snippet is very useful. Whenever we are rebalancing our portfolio to a particular signal, we usually want to ensure we do not send out duplicate orders for the ones that are already outstanding. We also do not want to leave the open orders as they signals might have changed their veracity. In such cases, it is best to query and cancel all open orders before placing fresh ones.

Squaring off

For live brokers, in most cases, we support a square_off function that will send exit request for all positions, after cancelling all open orders.


  1. This means issuing a buy and sell order of same amount on the same asset does not create a null positions, but two different positions, with potentially margins blocked for both. For such type of accounts, Blueshift® will first try to see if a new order can be filled by unwinding existing positions. An order for the remaining amount, if any, will be sent. This is only valid market orders.