Placing Bracket and Cover Orders on the Exchange

This chapter introduces various types of bracket and cover orders that can be placed on exchanges via the broker APIs. The recipes include code for placing 12 types of orders and querying their statuses, canceling open orders, and exiting completed orders. These recipes will be a fundamental part of your algorithmic trading strategies. Understanding all of the types of orders and knowing which one to place for the given requirement is crucial for building a successful trading strategy.

Each order has four attributes that together define the order completely:

  • Order transaction type
  • Order type
  • Order code
  • Order variety

For placing an order, all four attributes should be known precisely. To know more about these attributes, refer to the introduction to Chapter 6, Placing Regular Orders on the Exchange.

The recipes in this chapter provide detailed flowcharts for each order type. Every order placed on the exchange goes through various states during its lifetime. To know more about the order states supported by the broker used in this chapter, refer to the introduction to Chapter 6, Placing Regular Orders on the Exchange.

In this chapter, we will cover the following recipes:

  • Placing a bracket limit order
  • Placing a bracket stoploss-limit order
  • Placing a bracket limit order with a trailing stoploss
  • Placing a bracket stoploss-limit order with a trailing stoploss
  • Placing a cover market order
  • Placing a cover limit order
Please make sure you try all of these recipes during live market hours with sufficient balance in your broking account. If these recipes are tried outside of market hours or with insufficient balance, your orders will be rejected by the broker. This means the orders would never reach the exchange and you would not get the expected response.

Technical requirements

You will need the following to successfully execute the recipes in this chapter:

  • Python 3.7+
  • Python packages: pyalgotrading ($ pip install pyalgotrading)

The latest Jupyter notebook for this chapter can be found on GitHub at https://github.com/PacktPublishing/Python-Algorithmic-Trading-Cookbook/tree/master/Chapter07.

The first thing needed for setting connectivity with the broker is getting the API keys. The broker will provide each customer with unique keys, typically as an api-key and api-secret key pair. These API keys are chargeable, usually on a monthly subscription basis. You need to get your copy of api-key and api-secret from the broker website before starting this. You can refer to Appendix I for more details.

The following steps will help you to set up the broker connection with Zerodha, which will be used by all of the recipes in this chapter. Please make sure you have followed these steps before trying out any recipe:

  1. Import the necessary modules:
>>> from pyalgotrading.broker.broker_connection_zerodha import BrokerConnectionZerodha
>>> from pyalgotrading.constants import *

All pyalgotrading constants are now available in your Python namespace.

  1. Get the api_key and api_secret keys from the broker. These are unique to you and will be used by the broker to identify your Demat account:
>>> api_key = "<your-api-key>"
>>> api_secret = "<your-api-secret>"
>>> broker_connection = BrokerConnectionZerodha(api_key,
api_secret)

We get the following output:

Installing package kiteconnect via pip. This may take a while...
Please login to this link to generate your request token: https://kite.trade/connect/login?api_key=<your-api-key>&v=3

If you are running this for the first time and kiteconnect is not installed, pyalgotrading will automatically install it for you. The final output of step 2 will be a link. Click on the link and log in with your Zerodha credentials. If the authentication is successful, you will see a link in your browser's address bar similar to https://127.0.0.1/?request_token=<alphanumeric-token>&action=login&status=success.

We have the following example:

https://127.0.0.1/?request_token=H06I6Ydv95y23D2Dp7NbigFjKweGwRP7&action=login&status=success
  1. Copy the alphanumeric-token and paste it in request_token:
>>> request_token = "<your-request-token>"
>>> broker_connection.set_access_token(request_token)

The broker_connection instance is now ready for performing API calls.

The pyalgotrading package supports multiple brokers and provides a connection object class per broker, with the same methods. It abstracts broker APIs behind a unified interface so users need not worry about the underlying broker API calls and can use all of the recipes in this chapter as is. Only the procedure to set up the broker connection would vary from broker to broker. You can refer to the pyalgotrading documentation for setting up the broker connection if you are not using Zerodha as your broker. For Zerodha users, the steps mentioned in the preceding section would suffice.

Placing a bracket limit order

Bracket orders are complex orders that are meant to help to make a profit when trade becomes favorable, or limit the loss when it becomes unfavorable, with predefined values. A bracket order is essentially a combination of three regular orders together—an initial order, a target order, and a stoploss order—which act together to help to achieve the specified profit or limit the loss. Along with the regular order parameters, a bracket order takes additional parameters—target, stoploss, and trailing stoploss (optional). The three regular orders are described as follows:

  • Initial order: This order is equivalent to a regular limit order or regular stoploss-limit order. Once placed, it remains in the 'OPEN' state until the market price reaches its trigger price value. Once the market crosses the trigger price value, this order moves from the 'OPEN' to 'COMPLETE' state and the target and stoploss orders are placed, which are described next.
  • Target order: This order is equivalent to a regular limit order, with its trigger price as the specified target value and transaction type opposite to that of the initial order. For a buy initial order, the target order is placed at a higher price than the initial order. This would be vice versa for a sell initial order. The quantity matches that of the initial order. So, if this order executes, it exits the position created by the initial order
  • Stoploss order: This order is equivalent to a regular stoploss-limit order, with the specified stoploss value as its trigger price and transaction type opposite to that of the initial order. For a buy initial order, the stoploss order is placed at a lower price than the initial order. This would be vice versa for a sell initial order. The quantity matches that of the initial order. So, if this order executes, it exits the position created by the initial order. If a trailing stoploss parameter is specified, every time the initial order price moves in the direction of the target order price, the stoploss order is modified in the direction of the initial order price by as many points as the value of trailing stoploss. This helps to further reduce the loss in case the price movement direction of the initial order changes.

Since a target order and a stoploss order are placed on opposite sides of an initial order, they form a bracket around the initial order, and hence this order is called a bracket order. Also, as the target and stoploss orders are on opposite sides, only one of them would get executed (which means its status would go from 'OPEN' to 'COMPLETE') at a given time, and when it does, the order (either the stoploss order or the target order) is automatically canceled. The target and stoploss orders are also collectively called child orders of the initial order, and the latter is called the parent order of the former.

A bracket order is usually meant for intraday trading unless otherwise supported by the broker. If the initial order or the child orders are not completed by the end of the trading session, they are automatically canceled or exited by the broker.

The following flowchart explains the workings of a bracket order:

The following are references to the state machine diagrams for a bracket limit order:
  • Initial order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Target order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.

You can use the bracket limit order when a buy bracket order has to be placed below the market price or a sell bracket order has to be placed above the market price. 

This recipe demonstrates the placing of the following bracket limit orders and querying their statuses:

  • The BUY, BRACKET, INTRADAYLIMIT order (without trailing stoploss)
  • The SELL, BRACKET, INTRADAYLIMIT order (without trailing stoploss)

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 'SBIN')
  1. Fetch the LTP. Place a BUY, BRACKET, INTRADAY, LIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp-1,
stoploss=2,
target=2)
>>> order1_id

We get the following output (your output may differ):

'2003030003491923'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'OPEN'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshot (some data may differ for you):

  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshot (some data may differ for you):

  1. Fetch the LTP. Place a SELL, BRACKET, INTRADAYLIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp+1,
stoploss=2,
target=2)
>>> order2_id

We get the following output (your output may differ):

'200303003639902'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'OPEN'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshot (some data may differ for you):

  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'COMPLETE'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshot (some data may differ for you):

How it works…

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('SBI'). 

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUY, BRACKET, INTRADAY, LIMIT order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.BRACKET here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.LIMIT here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • price: This is the limit price at which the order should be placed. We pass ltp-1 here, which means 1 unit price below ltp.
  • stoploss: This is the price difference from the initial order price, at which the stoploss order should be placed. It should be a positive int or float value. We pass 2 here.
  • target: This is the price difference from the initial order price, at which the target order should be placed. It should be a positive int or float value. We pass 2 here.

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the price parameter is passed a value of ltp-1. This means the order is placed below the market price, which is a necessary condition for placing buy limit orders. The stoploss parameter is specified as 2. This means the stoploss order would be placed at the price, which is two price units lower than the execution price of the initial order. Similarly, the target parameter is specified as 2. This means the target order would be placed at the price that is two price units higher than the execution price of the initial order. 

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'OPEN', a string. You can use order1_id to fetch the status of the placed order at any later point of time as well.

In step 4, you fetch the order status again, and if the order is completed, you get the order status as 'COMPLETE'. Immediately after this, the target and stoploss orders are placed, at the prices mentioned earlier. The target order executes as a regular limit order. The stoploss order executes as a regular stoploss-limit order. When one of them gets executed and reaches the 'COMPLETE' state, the other order is automatically canceled by the broker, so it moves to the 'CANCELLED' state. Recall, both target and stoploss orders are on opposite sides of the initial order, so both target and stoploss orders cannot execute at the same time.

You can also verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshot shown in the outputs of step 3 and step 4.

In step 3, if you see the status as 'COMPLETE' instead of 'OPEN'; this could be due to high volatility. If you want the order to stay in the 'OPEN' state for a while, try placing the order further away from the market price.

The following are references for more details on the execution of the initial order, target order, and stoploss order:

  • Initial order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Target order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-limit order recipe in the previous chapter.

The other steps in this recipe follow the same pattern of placing an order and getting its status for different combinations of attributes:

  • Steps 5, 6, and 7: The SELL, BRACKET, INTRADAYLIMIT order

There's more…

You can exit a bracket order by exiting one of its child orders. The child order that you exit is executed at market price and moves to the COMPLETE state. The other child moves to the CANCELLED state.

For example, let's consider the case if you exit the stoploss order. In this case, the target order will be canceled and it will transition to the CANCELLED state. The stoploss order will be executed at market price and it will transition to the COMPLETE state. If you log in to the broker site with your credentials and go to the orders section, you can find the child order details as shown in the following screenshot. Some data may differ for you.

The following is the target order, for the initial order placed in step 2, before exiting the bracket order:

The following is the target order after exiting the bracket order:

This screenshot shows the stoploss order, for the initial order placed in step 2, before exiting:

The following screenshot shows the stoploss order after exiting:

Placing a bracket stoploss-limit order

Bracket orders are complex orders that are meant to help to make a profit when trade becomes favorable, or limit the loss when it becomes unfavorable, with predefined values. A bracket order is essentially a combination of three regular orders together —an initial order, a target order, and a stoploss order, which act together to help to achieve the specified profit or limit the loss. Along with the regular order parameters, a bracket order takes additional parameterstarget, stoploss, and trailing stoploss (optional). 

Please refer to the introduction of the Placing a bracket limit order recipe for an in-depth understanding of the working of bracket orders. You can use a bracket stoploss-limit order if you want to place a buy bracket order above the market price or a sell bracket order below the market price.

This recipe demonstrates the placing of the following bracket stoploss-limit orders and querying their statuses:

  • The BUY, BRACKET, INTRADAYSTOPLOSS_LIMIT order (without trailing stoploss)
  • The SELL, BRACKET, INTRADAYSTOPLOSS_LIMIT order (without trailing stoploss)
The following are references to the state machine diagrams for a bracket stoploss-limit order:
  • Initial order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.
  • Target order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 
'INDUSINDBK')
  1. Fetch the LTP. Place a BUY, BRACKET, INTRADAYSTOPLOSS_LIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument.segment)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.STOPLOSS_LIMIT,
quantity=1,
price=ltp+1,
trigger_price=ltp+1,
stoploss=2,
target=2)
>>> order1_id

We get the following output (your output may differ):

'200226003619998'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'TRIGGER PENDING'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'
  1. Fetch the LTP. Place a SELL, BRACKET, INTRADAY, STOPLOSS_LIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.STOPLOSS_LIMIT,
quantity=1,
price=ltp-1,
trigger_price=ltp-1,
stoploss=2,
target=2)
>>> order2_id

We get the following output (your output may differ):

'200226003620002'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'TRIGGER PENDING'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'COMPLETE'

How it works…

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('INDUSINDBK'). 

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUY, BRACKET, INTRADAYSTOPLOSS_LIMIT order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.BRACKET here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.STOPLOSS_LIMIT here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • price: This is the limit price at which the order should be placed. We pass ltp+1 here, which means 1 unit price above ltp.
  • trigger_price: This is the trigger price at which the order should be placed. We pass ltp+1 here, which means 1 unit price above ltp.
  • stoploss: This is the price difference from the Initial Order price, at which the stoploss order should be placed. It should be a positive int or float value. We pass 2 here.
  • target: This is the price difference from the Initial Order price, at which the target order should be placed. It should be a positive int or float value. We pass 2 here.

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the price and trigger_price parameters are passed a value of ltp+1. This means the order is placed above the market price, which is a necessary condition for placing buy stoploss-limit orders. The stoploss parameter is specified as 2. This means the stoploss order would be placed at the price that is 2 price units lower than the execution price of the initial order. Similarly, the target parameter is specified as 2. This means the target order would be placed at the price that is 2 price units higher than the execution price of the Initial Order. 

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'TRIGGER PENDING', a string. You can use order1_id to fetch the status of the placed order at any later point of time as well. In step 4, you fetch the order status again, and if the order is completed, you get the order status as 'COMPLETE'. Immediately after this, the target and stoploss orders are placed, at the prices mentioned earlier. The target order executes as a regular limit order. The stoploss order executes as a regular stoploss-limit order. When one of them gets executed and reaches the 'COMPLETE' state, the other order is automatically canceled by the broker, so it moves to the 'CANCELLED' state. Recall, both target and stoploss orders are on opposite sides of the initial order, so both target and stoploss orders cannot execute at the same time.

In step 3, if you see the status as 'COMPLETE' instead of 'TRIGGER PENDING', this could be due to high volatility. If you want the order to stay in the 'OPEN' state for a while, try placing the order further away from the market price.

The following are references to more details on the execution of the initial order, target order, and stoploss order:

  • Initial order: Refer to the Placing a regular stoploss-limit order recipe in the previous chapter.
  • Target order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-limit order recipe in the previous chapter.

You can verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshots shown in the Placing bracket limit orders on the exchange recipe.

The other steps in this recipe follow the same pattern of placing an order and getting its status for a different combination of attributes:

  • Steps 5, 6, and 7: The SELL, BRACKET, INTRADAYSTOPLOSS_LIMIT order

Placing a bracket limit order with trailing stoploss

Bracket orders are complex orders that are meant to help to make a profit when trade becomes favorable, or limit the loss when it becomes unfavorable, with predefined values. A bracket order is essentially a combination of three regular orders togetheran initial order, a target order, and a stoploss order, which act together to help to achieve the specified profit or limit the loss. Along with the regular order parameters, a bracket order takes additional parameterstarget, stoploss, and trailing stoploss (optional). 

Please refer to the introduction of the Placing a bracket limit order recipe for an in-depth understanding of the working of bracket orders.

You can use a bracket limit order if you want to place a buy bracket order below the market price or a sell bracket order above the market price. The trailing stoploss feature improvises the positioning of the stoploss order by modifying its price in the direction of the initial order price by as many points as the value of trailing stoploss. This happens every time the initial order price moves in the direction of the target order price. This helps to further reduce the loss in case the price movement direction of the initial order changes.

This recipe demonstrates the placing of the following bracket limit orders with a trailing stoploss and querying their statuses:

  • The BUY, BRACKET, INTRADAYLIMIT order with trailing stoploss
  • The SELLBRACKET, INTRADAYLIMIT order with trailing stoploss
The following are references to the state machine diagrams for a bracket limit order:
  • Initial order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Target order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 'FEDERALBNK')
  1. Fetch the LTP. Place a BUY, BRACKET, INTRADAYLIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp-1,
trigger_price=ltp-1,
stoploss=2,
target=2,
trailing_stoploss=1)
>>> order1_id

We get the following output (your output may differ):

'200226003620004'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'OPEN'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'
  1. Fetch the LTP. Place a SELLBRACKET, INTRADAYLIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp+1,
trigger_price=ltp+1,
stoploss=2,
target=2,
trailing_stoploss=1)
>>> order1_id

We get the following output (your output may differ):

'200226003620009'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'OPEN'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'COMPLETE'

How it works...

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('FEDERALBNK').

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUYBRACKET, INTRADAYLIMIT order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.BRACKET here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.LIMIT here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • price: This is the limit price at which the order should be placed. We pass ltp-1 here, which means 1 unit price below ltp.
  • stoploss: This is the price difference from the Initial Order price, at which the Stoploss Order should be placed. It should be a positive int or float value. We pass 2 here.
  • target: This is the price difference from the Initial Order price, at which the Target Order should be placed. It should be a positive int or float value. We pass 2 here.
  • trailing_stoploss: This is the price difference by which the stoploss order should be modified every time the market price moves in the direction of the target order. We pass 1 here.

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the price parameter is passed a value of ltp-1. This means the order is placed below the market price, which is a necessary condition for placing buy limit orders. The stoploss parameter is specified as 2. This means the stoploss order would be placed at the price that is two price units lower than the execution price of the initial order. Similarly, the target parameter is specified as 2. This means the target order would be placed at the price that is two price units higher than the execution price of the initial order. Finally, the trailing_stoploss parameter is specified as 1. This means, after the stoploss order is placed, the stoploss order would be modified and placed at a price higher than the previous price by one unit, every time the market price increases in multiples of one unit from the price of the initial order.

So, for example, let's say the market price for the instrument was 100 at the time of placing this order, and so the target and stoploss orders would be placed at 102 and 98, respectively. Suppose the market price reaches 101, which is one unit higher than 100, then the stoploss order would be modified and placed at 99, which is again one unit higher than its previous price. By doing so, you have reduced your maximum loss from 2 to 1.

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'OPEN', a string. You can use order1_id to fetch the status of the placed order at any later point in time as well. In step 4, you fetch the order status again, and if the order is completed, you get the order status as 'COMPLETE'. Immediately after this, the target and stoploss orders are placed, at the prices mentioned earlier. The target order executes as a regular limit order. The stoploss order executes as a regular stoploss-limit order. When one of them gets executed and reaches the COMPLETE state, the other order is automatically canceled by the broker, so it moves to the CANCELLED state. Recall, both target and stoploss orders are on opposite sides of the initial order, so both target and stoploss orders cannot execute at the same time. The stoploss order may be modified by one price unit, as mentioned earlier.

In step 3, if you see the status as `COMPLETE` instead of `OPEN`, this could be due to high volatility. If you want the order to stay in the `OPEN` state for a while, try placing the order further away from the market price.

The following are references for more details on the execution of the initial order, target order, and stoploss order:

  • Initial order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Target order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-limit order recipe in the previous chapter.

You can verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshots shown in the Placing bracket limit orders on the exchange recipe.

The other steps in this recipe follow the same pattern of placing an order and getting its status for a different combination of attributes:

  • Steps 5, 6, and 7: The SELLBRACKET, INTRADAYLIMIT order with trailing stoploss

Placing a bracket stoploss-limit order with trailing stoploss

Bracket orders are complex orders that are meant to help to make a profit when trade becomes favorable, or limit the loss when it becomes unfavorable, with predefined values. A bracket order is essentially a combination of three regular orders togetheran initial order, a target order, and a stoploss order, which act together to help to achieve the specified profit or limit the loss. Along with the regular order parameters, a bracket order takes additional parameterstarget, stoploss, and trailing stoploss (optional). 

Please refer to the introduction of the Placing a bracket limit order recipe for an in-depth understanding of the working of bracket orders.

You can use a bracket stoploss-limit order if you want to place a buy bracket order above the market price or a sell bracket order below the market price. The trailing stoploss improvises the positioning of the stoploss order by modifying its price in the direction of the initial order price by as many points as the value of trailing stoploss, every time the initial order price moves in the direction of the target order price. This helps to further reduce the loss, in case the direction of the price movement of the initial order changes.

This recipe demonstrates the placing of the following bracket stoploss-limit orders with trailing stoploss and querying their statuses:

  • The BUY, BRACKET, INTRADAYSTOPLOSS_LIMIT order with trailing stoploss
  • The SELL, BRACKET, INTRADAYSTOPLOSS_LIMIT order with trailing stoploss
The following are references to the state machine diagrams for a bracket stoploss-limit order:
  • Initial order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.
  • Target order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-limit order recipe in the previous chapter.

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 'RBLBANK')
  1. Fetch the LTP. Place a BUY, BRACKET, INTRADAYSTOPLOSS_LIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.STOPLOSS_LIMIT,
quantity=1,
price=ltp+1,
trigger_price=ltp+1,
stoploss=2,
target=2,
trailing_stoploss=1)
>>> order1_id

We get the following output (your output may differ):

'200226003620011'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'TRIGGER PENDING'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'
  1. Fetch the LTP. Place a SELL, BRACKET, INTRADAYSTOPLOSS_LIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.BRACKET,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.STOPLOSS_LIMIT,
quantity=1,
price=ltp-1,
trigger_price=ltp-1,
stoploss=2,
target=2,
trailing_stoploss=1)
>>> order2_id

We get the following output (your output may differ):

'200226003620023'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'TRIGGER PENDING'
  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'COMPLETE'

How it works...

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('RBLBANK'). 

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUY, REGULAR, INTRADAYSTOPLOSS_LIMIT order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.BRACKET here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.STOPLOSS_LIMIT here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • price: This is the limit price at which the order should be placed. We pass ltp+1 here, which means 1 unit price above ltp.
  • trigger_price: This is the trigger price at which the order should be placed. We pass ltp+1 here, which means 1 unit price above ltp.
  • stoploss: This is the price difference from the initial order price, at which the stoploss order should be placed. It should be a positive int or float value. We pass 2 here.
  • target: This is the price difference from the Initial Order price, at which the Target Order should be placed. It should be a positive int or float value. We pass 2 here.
  • trailing_stoploss: This is the price difference by which the stoploss order should be modified every time the market price moves in the direction of the target order. We pass 1 here. 

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the price and trigger_price parameters are passed a value of ltp+1. This means the order is placed above the market price, which is a necessary condition for placing buy stoploss-limit orders. The stoploss parameter is specified as 2. This means the stoploss order would be placed at the price that is two price units lower than the execution price of the initial order. Similarly, the target parameter is specified as 2. This means the target order would be placed at the price that is two price units higher than the execution price of the initial order. Finally, the trailing_stoploss parameter is specified as 1. This means, after the stoploss order is placed, the stoploss order would be modified and placed at a price higher than the previous price by one unit, every time the market price increases in multiples of one unit from the price of the initial order.

So, for example, let's say the market price for the instrument was 100 at the time of placing this order, and so the target and stoploss orders would be placed at 102 and 98 respectively. Suppose the market price reaches 101, which is one unit higher than 100, then the stoploss order would be modified and placed at 99, which is again one unit higher than its previous price. By doing so, you have reduced your maximum loss from 2 to 1.

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'TRIGGER PENDING', a string. You can use order1_id to fetch the status of the placed order at any later point of time as well. In step 4, you fetch the order status again, and if the order is completed, you get the order status as 'COMPLETE'. Immediately after this, the target and stoploss orders are placed, at the prices mentioned earlier. The target order executes as a regular limit order. The stoploss order executes as a regular stoploss-limit order. When one of them gets executed and reaches the 'COMPLETE' state, the other order is automatically canceled by the broker, so it moves to the 'CANCELLED' state. Recall, both target and stoploss orders are on opposite sides of the initial order, so both target and stoploss orders cannot execute at the same time. The stoploss order may be modified by one price unit, as mentioned earlier.

In step 3, if you see the status as 'COMPLETE' instead of 'TRIGGER PENDING', this could be due to high volatility. If you want the order to stay in the 'TRIGGER PENDING' state for a while, try placing the order further away from the market price.

The following are references to more details on the execution of the target order and stoploss order:

  • Initial order: Refer to the Placing a regular stoploss-limit order recipe in the previous chapter.
  • Target order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-limit order recipe chapter in the previous chapter.

You can verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshots shown in the Placing bracket limit orders on the exchange recipe.

The other steps in this recipe follow the same pattern of placing an order and getting its status for a different combination of attributes:

  • Steps 5, 6and 7: The SELL, BRACKET, INTRADAYSTOPLOSS_LIMIT order

Placing a cover market order

Cover orders are complex orders that are meant to help to limit the loss within predefined values if trade becomes unfavorable. A cover order is essentially a combination of two regular orders togetheran initial order and a stoploss order:

  • Initial order: This order can be equivalent to a regular market order or regular limit order, depending on whether you are placing a cover market order or cover limit order. Once the order moves to the 'COMPLETE' state, the stoploss order is placed, which is described next.
  • Stoploss order: This order is equivalent to a regular stoploss-market order (the Placing a regular stoploss-market order recipe in the previous chapter), with the specified trigger price value as its trigger price and a transaction type opposite to that of the initial order. For a buy initial order, the stoploss order is placed at a lower price than the initial order. This would be vice versa for a sell initial order. The quantity matches that of the initial order. So, if this order executes, it exits the position created by the initial order.

Since the stoploss order is placed to cover the initial order from making unexpected losses, this order is called a cover order. Usually, the broker won't allow canceling the stoploss order once it is placed. It can only be exited via completion.

A cover order is usually meant for intraday trading unless otherwise supported by the broker. If the initial order or the stoploss order is not completed by the end of the trading session, they are automatically canceled or exited by the broker.

The following flowchart summarizes the preceding points and explains the working of a cover order:

You can use the cover market order when a cover order has to be placed at the market price.

This recipe demonstrates placing the following cover market orders and querying their statuses:

  • The BUY, COVER, INTRADAYMARKET order
  • The SELL, COVER, INTRADAYMARKET order
The following are references to the state machine diagrams for a cover market order:
  • Initial order: Refer to the state machine diagram from the Placing a regular market order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-market order recipe in the previous chapter.

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 
'BANKBARODA')
  1. Fetch the LTP. Place a BUY, COVER, INTRADAYMARKET order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.COVER,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.MARKET,
quantity=1,
trigger_price=ltp-1)
>>> order1_id

We get the following output (your output may differ):

'200303003717532'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshots (some data may differ for you):

  • The following screenshot shows the initial order:

  • The following screenshot shows the stoploss order:

  1. Fetch the LTP. Place a SELL, COVER, INTRADAYMARKET order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.COVER,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.MARKET,
quantity=1,
trigger_price=ltp+1)
>>> order2_id

We get the following output (your output may differ):

'200303003732941'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'TRIGGER PENDING'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshots (some data may differ for you):

  • The following screenshot shows the initial order:

  • The following screenshot shows the stoploss order:

How it works...

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('BANKBARODA'). 

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUY, COVER, INTRADAYMARKET order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.COVER here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.MARKET here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • trigger_price: This is the trigger price for the Stoploss Order. We pass ltp-1 here, which means one unit price below ltp.

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the trigger_price parameter is passed a value of ltp-1. This means the stoploss order is placed below the market price, which is a necessary condition for placing sell stoploss-market orders.

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'COMPLETE', a string. Immediately after this, the stoploss order is placed, at the price mentioned earlier. This order is then executed as a regular stoploss-market order. 

If the stoploss order is executed at any point in time, it would mean your trade has incurred a loss, but has safe-guarded you from making more losses. The stoploss order transitions to the 'COMPLETE' state and the position created by the cover order is exited. You can also verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshot shown in the output of step 3.

The following are references to more details on the execution of stoploss orders:
  • Initial order: Refer to the Placing a regular market order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-market order recipe in the previous chapter.

The other steps in this recipe follow the same pattern of placing an order and getting its status for a different combination of attributes:

  • Steps 4 and 5: The SELL, COVER, INTRADAYMARKET order

Placing a cover limit order

Cover orders are complex orders that are meant to help to limit the loss within predefined values if trade becomes unfavorable. A cover order is essentially a combination of two regular orders—an initial order and a stoploss order, which act together to help to limit the loss in case trade becomes unfavorable.

Please refer to the introduction of the Placing a cover market order recipe for an in-depth understanding of the working of cover orders. You can use a cover limit order if you want to place a buy cover order below the market price or a sell cover order above the market price. This recipe demonstrates the placing of the following cover limit orders and querying their statuses:

  • The BUY, COVER, INTRADAYLIMIT order
  • The SELL, COVER, INTRADAYLIMIT order
The following are references to the state machine diagrams for a cover limit order:
  • Initial order: Refer to the state machine diagram from the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the state machine diagram from the Placing a regular stoploss-market order recipe in the previous chapter.

Getting ready

Make sure the broker_connection object and constants from the pyalgotrading package are available in your Python namespace. Refer to the Technical requirements section of this chapter to set up this object.

How to do it…

We execute the following steps for this recipe:

  1. Fetch a financial instrument and assign it to instrument:
>>> instrument = broker_connection.get_instrument('NSE', 'YESBANK')
  1. Fetch the LTP. Place a BUY, COVER, INTRADAYLIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order1_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.BUY,
order_type=BrokerOrderTypeConstants.COVER,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp-0.5,
trigger_price=ltp-1)
>>> order1_id

We get the following output:

'200303003749622’
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'OPEN'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshots (some data may differ for you):

  • The following screenshot shows the initial order:

  • The following screenshot shows the stoploss order:

  1. Fetch and display the order status again after some time:
>>> broker_connection.get_order_status(order1_id)

We get the following output:

'COMPLETE'
  1. Fetch the LTP. Place a SELL, COVER, INTRADAYLIMIT order and display the order ID:
>>> ltp = broker_connection.get_ltp(instrument)
>>> order2_id = broker_connection.place_order(
instrument=instrument,
order_transaction_type=
BrokerOrderTransactionTypeConstants.SELL,
order_type=BrokerOrderTypeConstants.COVER,
order_code=BrokerOrderCodeConstants.INTRADAY,
order_variety=
BrokerOrderVarietyConstants.LIMIT,
quantity=1,
price=ltp+0.5,
trigger_price=ltp+1)
>>> order2_id

We get the following output (your output may differ):

'200303003751757'
  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'OPEN'

If you log in to the broker site with your credentials and go to the orders section, you can find your order details as shown in the following screenshots (some data may differ for you):

  • The following screenshot shows the initial order:

  • The following screenshot shows the stoploss order:

  1. Fetch and display the order status:
>>> broker_connection.get_order_status(order2_id)

We get the following output:

'COMPLETE'

How it works...

In step 1, you use the get_instrument() method of the BrokerConnectionZerodha class to fetch an instrument and assign it to a new attribute, instrument. This object is an instance of the Instrument class. The two parameters needed to call get_instrument are the exchange ('NSE') and the trading-symbol ('YESBANK').

In step 2, you fetch the LTP of the instrument using the get_ltp() method of the BrokerConnectionZerodha class and assign it to a new attribute, ltp. The instrument object is passed as the parameter here. Next, you use the place_order() method of the broker_connection object to place a BUY, COVER, INTRADAYLIMIT order on the exchange. The place_order() method is a wrapper on the broker-specific place order API. It takes the following attributes:

  • instrument: This is the financial instrument for which the order must be placed and should be an instance of the Instrument class. We pass instrument here.
  • order_transaction_type: This is the order transaction type and should be an enum of the type, BrokerOrderTransactionTypeConstants. We pass BrokerOrderTransactionTypeConstants.BUY here.
  • order_type: This is the order type and should be an enum of the type, BrokerOrderTypeConstants. We pass BrokerOrderTypeConstants.COVER here.
  • order_code: This is the order code and should be an enum of the type, BrokerOrderCodeConstants. We pass BrokerOrderCodeConstants.INTRADAY here.
  • order_variety: This is the order variety and should be an enum of the type, BrokerOrderVarietyConstants. We pass BrokerOrderVarietyConstants.LIMIT here.
  • quantity: This is the number of shares to be traded for the given instrument and should be a positive integer. We pass 1 here.
  • price: This is the limit price for the Initial Order. We pass ltp-0.5 here, which means 0.5 unit of a price below ltp.
  • trigger_price: This is the trigger price for the Stoploss Order. We pass ltp-1 here, which means one unit price below ltp.

(The attributes passed to the place_order() method are broker-agnostic constants, imported earlier from the pyalgotrading.constants module.)

On placing the order in step 2, you get an order ID from the broker, which you assign to a new attribute, order1_id. The order1_id object is a string. If the order placement is not successful for some reason, you may not get an order ID. Observe that the price parameter is passed a value of ltp-0.5. This means the initial order is placed below the market price, which is a necessary condition for placing buy limit orders. Also, observe that the trigger_price parameter is passed a value of ltp-1. This means the stoploss order is placed below price (which will be the market price at the time of placing the stoploss order), which is a necessary condition for placing sell stoploss-market orders. 

In step 3, you fetch the status of the placed order using the get_order_status() method of the broker_connection object. You pass order1_id as a parameter to the get_order_status() method. You get the order status as 'OPEN', a string. You can use order1_id to fetch the status of the placed order at any later point of time as well. In step 4, you fetch the order status again, and if the order is completed, you get the order status as 'COMPLETE'. Immediately after this, the stoploss order is placed, at the price mentioned earlier. This order is then executed as a regular stoploss-market order. 

If the stoploss order is executed at any point in time, it would mean your trade has incurred a loss, but has safe-guarded you from making more losses. The stoploss order transitions to the 'COMPLETE' state and the position created by the cover order is exited. You can also verify the successful placement of your order by logging in to the broking website and checking the orders section there. You should see data similar to the screenshot shown in the output of step 3.

The following are references to more details on the execution of the initial order and stoploss order:
  • Initial order: Refer to the Placing a regular limit order recipe in the previous chapter.
  • Stoploss order: Refer to the Placing a regular stoploss-market order recipe in the previous chapter.

The other steps in this recipe follow the same pattern of placing an order and getting its status for a different combination of attributes:

  • Steps 4 and 5: The SELL, COVER, INTRADAYLIMIT order
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.140.153