Placing Trade Orders on Blueshift®¶
Orders, trades, positions¶
Fractional trading support.
Blueshift now supports fractional trading, i.e. order quantity need
not be an integer and fractional amount is supported (if supported
by the broker). Some brokers (e.g. Crypto brokers) offer exclusively
fractional trading. For such cases, Blueshift will automatically
treat every order as fractional. For brokers which do not exclusivly
offer fractional trading (e.g. Equity brokers), you must specify a
fractional=True in the ordering API functions to
make it fractional.
On Blueshift®, we interpret the terms
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
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.
positions are the
key metrics by which a strategy keeps itself aware of its exposure.
For more on
Position, see the
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
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
marketand 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¶
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_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
For more on order placing APIs, refer the API doc.
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
This will return a
dict (a Python dictionary) with order IDs as the
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.
For more on order management APIs, refer the API doc.
For live brokers, in most cases, we support a
that will send exit request for all positions, after cancelling
all open orders.
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