Algorithmic Trading - Paper Trading

After building algorithmic trading strategies in Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, and successfully backtesting them with satisfactory results in the previous chapter, the next step is to paper trade the strategies in live markets.

Paper trading is the method of executing a trading strategy in the live market hours by simply recording trades coming from the strategy execution in real time. The trades are not executed with real money via a broker. Earlier, this recording of trades was done on paper, hence the name paper trading. These virtual trades can be used for analyzing the risk and return metrics. Typical paper trading metrics include profit and loss (P&L), maximum drawdown, the count of total trades, winning trades, losing trades, long trades and short trades, average profit per winning and losing trade, and more. Paper trading should be performed for at least a few trading days and until these metrics meet the necessary requirements, the entire process should be repeated, which consists of updating the strategy parameters and/or strategy implementation, followed by backtesting and paper trading.

The underlying idea behind paper trading is that the trading strategy can be executed in the live market, in a fashion almost similar to real trading, but without risking real money. Paper trading helps to ensure that the market scenarios from the past, for which backtesting was run, are still valid. If the market scenarios from the past do not prevail currently, even if backtesting results are profitable, paper trading results may turn out to be otherwise. This would suggest that the strategy parameters and/or strategy implementation needs more work before executing the strategy on real money.

For paper trading, a strategy configuration is required. It consists of multiple parameters, some of which are as follows:

  • Start and end times: The time duration within the current day for which paper trading should be run.
  • Financial instrument(s): One or more financial instruments for which paper trading should be performed.
  • Candle interval: One of the various possible candle intervals – for example, 1 minute, 15 minutes, hour, or day.
  • Strategy specific parameters: Values for custom parameters defined in the strategy.
  • Strategy mode: Either intraday or delivery. Intraday strategies punch intraday orders, which are squared-off at the end of the day. Delivery strategies punch delivery orders, which don't square-off at the end of the day and get carried forward to the next trading day.

A paper trading engine is required to perform paper trading on a given strategy. In this chapter, you will use the paper trading engine provided by AlgoBulls (https://algobulls.com), an algorithmic trading platform that makes its services available via its developer options. It provides a Python package called pyalgotrading (https://github.com/algobulls/pyalgotrading) to make use of these services.

You have already coded two algorithmic trading strategies in Chapter 8, Algorithmic Trading Strategies – Coding Step by Step. Recall that the strategy descriptions are as follows: 

  • EMA-Regular-Order strategy: A strategy based on the technical indicator EMA and regular orders. (The first six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step.)
  • MACD-Bracket-Order strategy: A strategy based on the technical indicator of MACD and bracket orders. (The latter six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step.)
These strategies are also available as part of a Python package, pyalgostrategypool. You can install it using pip, as follows: $ pip install pyalgostrategypool.

You can also check them out on GitHub (https://github.com/algobulls/pyalgostrategypool). 

As you have followed Chapter 8Algorithmic Trading Strategies – Coding Step by Step, you have uploaded these two strategies to your AlgoBulls account. In this chapter, you will fetch these strategies from your AlgoBulls account and perform paper trading on them. After paper trading, you will get strategy execution logs and various reports – namely, a P&L report, a statistics report, and an order history. These logs and reports help validate the strategy performance and prepare it for real trading. By using pyalgotrading, you ensure that you focus on developing and validating the strategy via paper trading without worrying about the ecosystem needed for the strategy execution. 

This chapter includes step-by-step recipes for both the previously mentioned strategies, from setting up a connection with the AlgoBulls platform, fetching the strategy, and running paper trading jobs to fetching the execution logs and fetching various types of reports.

In this chapter, you will cover the following recipes:

  • EMA-Regular-Order strategy – fetching the strategy
  • EMA-Regular-Order strategy – paper trading the strategy
  • EMA-Regular-Order strategy – fetching paper trading logs in real time
  • EMA-Regular-Order strategy – fetching a paper trading report – P&L table
  • EMA-Regular-Order strategy  – fetching a paper trading report – statistics table
  • EMA-Regular-Order strategy  – fetching a paper trading report – order history
  • MACD-Bracket-Order strategy – fetching the strategy
  • MACD-Bracket-Order strategy – paper trading the strategy
  • MACD-Bracket-Order strategy – fetching paper trading logs in real time
  • MACD-Bracket-Order strategy – fetching a paper trading report – P&L table
  • MACD-Bracket-Order strategy  – fetching a paper trading report – statistics table
  • MACD-Bracket-Order strategy  – fetching a paper trading report - order history

Paper trading is meaningful only if run during the live market hours, unlike backtesting, which can be run at any time. Please make sure you try out the recipes of this chapter during the live market hours.

Technical requirements

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

  • Python 3.7+
  • Python package:
  • 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/Chapter10.

EMA-Regular-Order strategy – fetching the strategy

In this recipe, you will fetch the strategy class, StrategyEMARegularOrder, from your account on the AlgoBulls platform, which you will have uploaded while going through the EMA-Regular-Order strategy – uploading the strategy on the AlgoBulls trading platform recipe in Chapter 8, Algorithmic Trading Strategies – Coding Step by Step. This recipe starts by setting up a connection to the AlgoBulls platform, querying all the available strategies in your account, and fetching details of the required strategy class, StrategyEMARegularOrder.

Make sure you have gone through the first six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Stepto get a complete picture of the strategy class used, StrategyEMARegularOrder.

How to do it…

We execute the following steps for this recipe:

  1. Import the necessary modules:
>>> from pyalgotrading.algobulls import AlgoBullsConnection
  1. Create a new AlgoBulls connection object:
>>> algobulls_connection = AlgoBullsConnection()
  1. Fetch the authorization URL:
>>> algobulls_connection.get_authorization_url()

We get the following output:

Please login to this URL with your AlgoBulls credentials and get your developer access token: https://app.algobulls.com/user/login
'https://app.algobulls.com/user/login'
  1. Log in to the preceding link with your AlgoBulls credentials, fetch your token, and set it here (refer to Appendix II for more details):
>>> algobulls_connection.set_access_token(
'80b7a69b168c5b3f15d56688841a8f2da5e2ab2c')
  1. Fetch and display all strategies you have created and uploaded so far:
>>> all_strategies = algobulls_connection.get_all_strategies()
>>> all_strategies

We get the following output. Your output may differ (make sure you have followed the recipes in Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a similar output):

  1. Fetch and display the strategy code for the first strategy:
>>> strategy_code1 = all_strategies.iloc[0]['strategyCode']
>>> strategy_code1

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

'49287246f9704bbcbad76ade9e2091d9'
  1. Before paper trading your strategy, you can inspect it to ensure you have the right strategy:
>>> strategy_details1 = 
algobulls_connection.get_strategy_details(strategy_code1)
>>> print(strategy_details1)

We get the following output:

class StrategyEMARegularOrder(StrategyBase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.timeperiod1 = self.strategy_parameters['timeperiod1']
self.timeperiod2 = self.strategy_parameters['timeperiod2']

self.main_order = None

def initialize(self):
self.main_order = {}

@staticmethod
def name():
return 'EMA Regular Order Strategy'
….
def strategy_exit_position(self, candle, instrument,
sideband_info):
if sideband_info['action'] == 'EXIT':
self.main_order[instrument].exit_position()
self.main_order[instrument] = None
return True

return False

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/strategy_ema_regular_order.py

How it works…

You import the necessary modules in step 1. In step 2, an instance of the AlgoBullsConnection class is created, named algobulls_connection. In step 3, you get the authorization URL using the get_authorization_url() method of the algobulls_connection object. This prints the authorization URL. You should visit this URL from your web browser to sign in to the AlgoBulls platform and fetch your developer access token. (You can find more details with screenshots in Appendix II on fetching developer access tokens from the AlgoBulls platform.) You copy the access token and set it in step 4 using the set_access_token() method of algobulls_connection. If the token is accepted, a successful connection is set up with the AlgoBulls platform.

In step 5, you fetch all strategies you have created and uploaded on the AlgoBulls platform so far. You use the get_all_strategies() method for this step and assign it to a new variable, all_strategies. This variable is a pandas.DataFrame object with the strategyCode and strategyName columns. This table holds information on the strategy codes and strategy names you have uploaded previously. If you have followed the EMA-Regular-Order strategy – uploading the strategy on the AlgoBulls trading platform recipe from Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, you will find a strategy with the name EMA-Regular-Order strategy. In step 6, you assign the strategy code of the EMA-Regular-Order strategy strategy to a new variable, strategy_code1. The strategy code is shown in the output of this step. This strategy code is unique for every strategy on the AlgoBulls platform.

Finally, in step 7, you ensure that the strategy referred by strategy_code1 is indeed the one you have uploaded earlier (in the EMA-Regular-Order strategy – uploading the strategy on the AlgoBulls trading platform recipe in Chapter 8Algorithmic Trading Strategies – Coding Step by Step). You use the get_strategy_details() method of the algobulls_connection object to inspect the strategy. This method takes strategy code as an argument. You pass strategy_code1 here. This method returns the entire class code as a string. You assign it to a new variable, strategy_details1, and display it.

If you would like to change the class code referred to by strategy_code1, as shown in step 7, please refer to the There's more… section of the EMA-Regular-Order strategy – uploading the strategy on the AlgoBulls trading platform recipe in Chapter 8Algorithmic Trading Strategies – Coding Step by Step.

EMA-Regular-Order strategy – paper trading the strategy

In this recipe, you will perform paper trading on the EMA-Regular-Order strategy. You must have fetched this strategy from your account on the AlgoBulls platform in the previous recipe. You will leverage the paper trading functionality facilitated by pyalgotrading for this recipe, which in turn submits a paper trading job on the AlgoBulls platform.

Once submitted, paper trading will be run by the AlgoBulls paper trading engine. You can query the status any time to know the state of the paper trading job. The job goes through the following states, in the following given order: 

  • 'STARTING' (intermediate state)
  • 'STARTED' (stable state)
  • 'STOPPING' (intermediate state)
  • 'STOPPED' (stable state)

On submitting a job, it starts with an intermediate state, 'STARTING'. In this state, the AlgoBulls paper trading engine will fetch the strategy and get the execution environment ready, which may take a couple of minutes. Once done, the job moves to the 'STARTED' state. The paper trading strategy happens in this stage. Here, it stays as long as it takes for paper trading to complete. Once done, the job moves to an intermediate state, 'STOPPING'. In this state, the AlgoBulls paper trading engine cleans up the resources allocated for this job, which usually takes less than a minute. Finally, the job moves to the 'STOPPED' state.

If you have already submitted a strategy paper trading job, you cannot submit another job for the same strategy until the first job completes. This means you have to wait for the first job to move to the 'STOPPED' state. If the first job is long-running and you would like to stop it immediately, you can submit a stop job request via pyalgotrading. You need to ensure the job is in the 'STARTED' state before submitting the request.

The following state machine diagram demonstrates the various states and transitions of a paper trading job during its lifetime on the AlgoBulls platform:

After submitting a paper trading job, you can fetch logs and reports for the strategy execution in real time. The logs and reports help validate the strategy performance and debug any potential issues.

Make sure you have gone through the first six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step to get a complete picture of the strategy class used, StrategyEMARegularORder.

Getting ready

Make sure the algobulls_connection and strategy_code1 objects are available in your Python namespace. Refer to the first recipe of this chapter to set up the algobulls_connection and strategy_code1 objects.

How to do it…

We execute the following steps for this recipe:

  1. Import the necessary modules:
>>> from datetime import time
>>> from pyalgotrading.constants import *
  1. Search for an instrument using its trading symbol as a keyword. Assign the returned object to instruments:
>>> instruments = algobulls_connection.search_instrument('SBIN')
>>> instruments

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

[{'id': 7, 'value': 'NSE:SBIN'}]
  1. Get value for the instrument of choice from instruments:
>>> instrument = instruments[0]['value']
>>> instrument

We get the following output:

'NSE:SBIN'

  1. Submit a paper trading job for strategy_code1:
>>> algobulls_connection.papertrade(strategy_code=strategy_code1, 
start_time=time(hour=9, minute=15),
end_time=time(hour=15, minute=30),
instrument=instrument,
lots=1,
strategy_parameters={
'timeperiod1': 5,
'timeperiod2': 12
},
candle_interval=CandleInterval.MINUTES_15)

We get the following output:

Setting Strategy Config... Success.
Submitting PAPERTRADING job... Success.
  1. Check the status of the submitted paper trading job:
>>> algobulls_connection.get_papertrading_job_status(
strategy_code1)

We get the following output:

{'data': 'STARTING'}
  1. Check the status of the submitted job again after some time:
>>> algobulls_connection.get_papertrading_job_status(
strategy_code1)

We get the following output:

{'data': 'STARTED'}

How it works…

In step 1, you import the time class from the datetime module and all the constants from the pyalgotrading.constants module. In step 2, you fetch the instrument for which you would like to paper trade the strategy, EMA-Regular-Order strategy, using the search_instrument() method of the algobulls_connection object. The search_instrument() method accepts a search string as an argument, which should be the trading symbol, in part or complete, of the instrument you are interested in. You pass 'SBIN' here. This function returns a list with details of instruments that match the search string. There could be multiple instruments that could have the search string in their trading symbols. In step 3, you fetch the value of the first matched instrument and assign it to a new variable, instrument.

In step 4, you submit a paper trading job using the papertrade() method of the algobulls_connection() object. It takes the following arguments:

  • strategy_code: The strategy code of the strategy for which paper trading has to be performed. This should be a string. You pass strategy_code1 here.
  • start_time: Today's time from when paper trading should be started. Should be a datetime.time object. Here, you pass an object holding the value 9 hours 15 – time(hour=9, minute=15). Refer to the first recipe of this book for details on creating a time object.
  • end_time: Today's time until when paper trading should be performed. This object should hold a time value ahead of the value held by start_time. Should be a datetime.time instance. Here, you pass an object holding the value 15 hours 30 – time(hour=15, minute=30).
  • instrument: The financial instrument for which paper trading should be run. Historical data will be fetched for this instrument. Should be a string. You pass instrument here.
  • lots: The number of lots for which paper trading should be performed. This should be an integer. The quantity is calculated by the strategy as number of lots × lot size of the financial instrument. You pass 1 here.
  • strategy_parameters: The parameter names and values expected by the strategy. This should be a dictionary, with parameter-name and parameter-value as key-value pairs. You pass the following parameters here:
  • timeperiod1: 5
  • timeperiod2: 12 

(Recall that parameters for EMA-Regular-Order strategy have been defined in its __init__() method, as shown in the first recipe of Chapter 8Algorithmic Trading Strategies – Coding Step by Step).

  • candle_interval: The candle interval for the historical data fetched for paper trading. This should be an enum of the type CandleInterval. You pass CandleInterval.MINUTES_15 here. (The CandleInterval enum provides various enums for candle intervals, some of which are MINUTE_1, MINUTES_3 , MINUTES_5, MINUTES_10, MINUTES_15, MINUTES_30, HOUR, and DAY.)

If the job submission is successful, you will see Success messages printed by the papertrade() function. 

Once a job is submitted, it takes a while to start. After starting, it may take some time to finish depending on the duration of paper trading specified using the start_time and end_time arguments. Usually, paper trading is run for the entire trading day, which means the job would be running for 6–8 hours.

In step 5, you fetch the job status using the get_papertrading_job_status() method of the algobulls_connection object. You pass strategy_code1 as the argument here. This method returns a dictionary with a single key-value pair, the data and the job status. If you query the status immediately after placing the job, you get 'STARTING' as the status. In step 6, you query the status again after some time, and if the job has started, you get the status as 'STARTED'.

A successful submission implies that the minimum inputs needed to paper trade a strategy have been passed in the required format. It, however, does not ensure that the strategy will run without errors. The strategy execution may still run into errors during paper trading. To debug execution issues, you would need to fetch the output logs, which is explained in the next recipe. Possible reasons for errors could be either bugs in the strategy class Python code or an incomplete strategy_parameters dictionary passed to the papertrade() function.

There's more…

If a job is running for a long time and you would like to stop it before its completion, you can use the stop_papertrading_job() method of the algobulls_connection object. This method accepts strategy code as an argument. You pass strategy_code1 here. This method submits a stop request to the AlgoBulls paper trading engine. If the request is accepted, you see a Success message here:

>>> algobulls_connection.stop_papertrading_job(strategy_code1)
Stopping PAPERTRADING job... Success.

If you query the status after submitting the stop request, you get the status as 'STOPPING':

>>> algobulls_connection.get_papertrading_job_status(strategy_code1)
{'data': 'STOPPING'}

If you query the status again after some time, and if the job has stopped, you get the status as 'STOPPED':

>>> algobulls_connection.get_papertrading_job_status(strategy_code1)
{'data': 'STOPPED'}

EMA-Regular-Order strategy – fetching paper trading logs in real time

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, every event that occurs and decisions taken by the AlgoBulls paper trading engine are recorded with exact timestamps in the form of textual logs. Some examples of recorded activities include the given strategy config, every new candle generated at regular intervals, trades punched by your strategy, the entry and exit of the positions created by these trades, waits for new candles, and so on. These logs are quintessential in validating the strategy behavior and debugging behavioral or performance issues that are frequently encountered while developing a strategy. 

In this recipe, you will fetch paper trading logs for your strategy. The logs start coming up as soon as your submitted paper trading job reaches the 'STARTED' state (refer to the preceding recipe for more information on the states of a paper trading job). The AlgoBulls platform allows you to fetch logs in real time, even while the paper trading job is still going on. You can get insights into the strategy execution without having to wait for the paper trading job to complete. This is helpful as paper trading jobs are usually long-running. The pyalgotrading package provides a simple method to fetch the execution logs for a given strategy.

Make sure you have gone through the first six recipes of Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyEMARegularOrder.

Getting ready

Make sure the algobulls_connection and strategy_code1 objects are available in your Python namespace. Refer to the first recipe of this chapter to set up the algobulls_connection and strategy_code1 objects.

How to do it…

We execute the following steps for this recipe:

  1. Fetch the paper trading execution logs for strategy_code1:
>>> logs = algobulls_connection.get_papertrading_logs(
strategy_code1)
>>> print(logs)

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

[2020-07-09 09:12:18] Logs not available yet. Please retry in sometime.
  1. Fetch the paper trading execution logs for strategy_code1 again after some time:
>>> logs = algobulls_connection.get_papertrading_logs(
strategy_code1)
>>> print(logs)

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

...
########################################
INITIALIZING ALGOBULLS CORE (v3.2.0 SECURE MODE)...
########################################
[2020-07-09 09:12:31] Welcome ALGOBULLS VIRTUAL USER!
[2020-07-09 09:12:31] Reading strategy…

[PT] [2020-07-09 09:15:00] [INFO] [tls] STARTING ALGOBULLS CORE…
...
[PT] [2020-07-09 10:30:00] [CRITICAL] [order] [PLACING NEW ORDER] [2020-07-09 10:30:00] [96c24ca4b3e448f381fc5c2bc52f7a29] [BUY] [NSE:SBIN] [QTY:1] [QTY PENDING: 1] [ENTRY PRICE: 194.7] [PRICE:None] [TRIGGER PRICE:None] [ORDER_TYPE_REGULAR] [ORDER_CODE_INTRADAY] [ORDER_VARIETY_MARKET] [ORDER_POSITION_ENTER]

[PT] [2020-07-09 15:30:00] [INFO] [clock] Candle generation has been stopped...
[PT] [2020-07-09 15:30:00] [INFO] [tls] Received event END OF MARKET. Stopping Trading Core Engine...
[PT] [2020-07-09 15:30:00] [INFO] [tls] Exiting all open positions with order code: ORDER_CODE_INTRADAY (if any)...
[PT] [2020-07-09 15:30:00] [CRITICAL] [tls] [User: ALGOBULLS VIRTUAL USER] Trading session completed
...

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/sample/papertrading/strategy_ema_regular_order/logs.txt

How it works…

In step 1, you use the get_papertrading_logs() method of the algobulls_connection object to fetch the strategy paper trading logs in real time. This method accepts strategy code as an argument. You pass strategy_code1 here. The return data is a string. If you try this step immediately after submitting the job, you get a string that says the logs are not ready yet ([2020-07-09 09:14:18] Logs not available yet. Please retry in sometime.). This happens if the paper trading job is in the 'STARTING' state.

In step 2, you fetch the logs again after some time. If the job is out of the 'STARTING' state, you start getting your strategy execution logs. You get the entire paper trading logs every time you call the get_papertrading_logs() function.

There's more...

Once the paper trading job moves to the 'STOPPED' state, no new logs are generated. You can fetch the complete logs any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), these logs will no longer be accessible via the get_papertrading_logs() method. You can save the fetched logs to a file if you'd like to refer to it at a later point in time.

EMA-Regular-Order strategy – fetching a paper trading report – profit and loss table

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs, the AlgoBulls paper trading engine also generates a P&L table in real time. This table holds information on every trade punched by the strategy. It also has details on the mapping between entry and exit orders and the trade P&L and cumulative P&L, sorted chronologically, with the latest order first. This table gives an insight into the overall strategy performance with the help of individual and cumulative P&L numbers. The entry-exit order mapping also helps validate the strategy behavior. 

In this recipe, you will fetch the P&L table report for your strategy. This report is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the P&L table in real time, even while the paper trading job is still going on. You can get insights into the strategy performance without having to wait for the paper trading job to complete. This is helpful as paper trading jobs are usually long-running. The pyalgotrading package provides a simple method to fetch the P&L table for a given strategy.

Make sure you have gone through the first six recipes of Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyEMARegularOrder.

Getting ready

Make sure the algobulls_connection and strategy_code1 objects are available in your Python namespace. Refer to the first recipe of this chapter to set up the algobulls_connection and strategy_code1 objects.

How to do it…

Fetch the paper trading P&L report for strategy_code1:

>>> algobulls_connection.get_papertrading_report_pnl_table(strategy_code1)

We get the following output. Your output may differ (note that the following output has been split into multiple tables for representation purposes. You will see a single wide table in your Jupyter notebook):

How it works…

In this recipe, you use the get_papertrading_report_pnl_table() method of the algobulls_connection object to fetch the paper trading P&L table in real time. This method accepts strategy code as an argument. You pass strategy_code1 here. The return data is a pandas.DataFrame object with multiple columns, described as follows:

  • instrument: Financial instrument for which trade was entered.
  • entry_timestamp: The timestamp at which the entry order was placed. (Note that it may remain in the 'OPEN' state for a while before it goes to the 'COMPLETE' state. The time for this state transition can be found using the order history table, explained in the sixth recipe of this chapter.)
  • entry_transaction_type: The entry order transaction type (either BUY or SELL).
  • entry_quantity: The entry order quantity.
  • entry_price: The price at which the entry order gets executed and goes to the 'COMPLETE' state.
  • exit_timestamp: The timestamp at which the exit order was placed. (Note that it may remain in the 'OPEN' state for a while before it goes to 'COMPLETE' state.)
  • exit_transaction_type: The exit order transaction type (either BUY or SELL).
  • exit_quantity: The exit order quantity.
  • exit_price: The price at which the exit order gets executed and goes to the 'COMPLETE' state.
  • pnl_absolute: The difference between the exit order execution price and entry order execution price. Mathematically, this is (exit_price - entry_price)*exit_quantity for a long trade and (entry_price - exit_price)*exit_quantity for a short trade. A positive value would imply that the trade is a profit-making trade. A negative value would imply that the trade is a loss-making trade.
  • pnl_percentage: The percentage of profit or loss with respect to the entry price. Mathematically, this is pnl_absolute / entry_price / exit_quantity x 100.
  • pnl_cumulative_absolute: Cumulative profit or loss. Mathematically, this is the sum of all the pnl_absolute values of the previous trades. This number gives a direct insight into the strategy performance against the simulation time.
  • pnl_cumulative_percentage: The percentage of cumulative profit or loss with respect to the entry price. Mathematically, this is pnl_cumulative / entry_price / exit_quantity x 100.

There's more...

Once the paper trading job moves to the 'STOPPED' state, the P&L table report will not update anymore. You can fetch the complete P&L report any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), this report will no longer be accessible via the get_papertrading_report_pnl_table() method. You can save the fetched report to a .csv file if you'd like to refer to it at a later point in time.

EMA-Regular-Order strategy – fetching a paper trading report – statistics table

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs and the P&L table, the AlgoBulls paper trading engine also generates a summary from the P&L table in real time. This summary is a table of statistics containing various statistical numbers, such as Net P&L (absolute and percentage), Max Drawdown (absolute and percentage), the count of total trades, winning trades, losing trades, long trades, and short trades, maximum gain and minimum gain (or maximum loss), and the average profit per winning and losing trade. This table gives an instant overview of the overall strategy performance.

In this recipe, you will fetch the statistics table report for your strategy. This report is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the statistics table in real time, even while the paper trading job is still going on. You can get insights into the strategy performance without having to wait for the paper trading job to complete. This is helpful as paper trading jobs are usually long-running. The pyalgotrading package provides a simple method to fetch the statistics table for a given strategy.

Make sure you have gone through the first six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyEMARegularOrder.

Getting ready

Make sure the algobulls_connection and strategy_code1 objects are available in your Python namespace. Refer to the first recipe of this chapter to set up the algobulls_connection and strategy_code1 objects.

How to do it…

Fetch the paper trading statistics report for strategy_code1:

>>> algobulls_connection.get_papertrading_report_statistics(strategy_code1)

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

How it works…

In this recipe, you use the get_papertrading_report_statistics() method of the algobulls_connection object to fetch the paper trading statistics table in real time. This method accepts strategy code as an argument. You pass strategy_code1 here. The return data is a pandas.DataFrame object with two columns—highlight_type and highlight_value—and multiple rows. The rows are described as follows:

  • Net PnL: The cumulative paper trading P&L. This is also the pnl_cumulative_absolute value of the first entry in the P&L table.
  • Net PnL %: The cumulative paper trading P&L percentage. This is also the pnl_cumulative_percentage value of the first entry in the P&L table.
  • Max Drawdown: The lowest value in the pnl_cumulative column of the P&L table. This indicates the maximum loss your strategy has encountered during the execution.
  • Max Drawdown %: Mathematically, this is (Max Drawdown) / (corresponding entry_price/exit_quantity x 100).
  • Number of Trades: Total trades (entry and exit counted as one) during the session.
  • Number of Wins: The count of trades where the trade P&L was non-negative.
  • Number of Losses: The count of trades where the trade P&L was negative.
  • Number of Long Trades: The count of trades where the entry transaction type was 'BUY'.
  • Number of Short Trades: The count of trades where the entry transaction type was 'SELL'.
  • Max Gain: The P&L of the trade with the maximum P&L value among all trades.
  • Min Gain: The P&L of the trade with the minimum P&L value among all trades.
  • Avg. Profit per winning trade: Mathematically, this is (Total P&L of winning trades) / (Count of winning trades).
  • Avg. Profit per losing trade: Mathematically, this is (Total P&L of losing trades) / (Count of losing trades).

There's more...

If the statistics table is fetched while the paper trading job is still running, the previously mentioned numbers will be intermediate numbers, based on the trades completed until that time. The numbers may change as more trades are punched until the paper trading job completes.

Once the paper trading job moves to the 'STOPPED' state, the statistics table will not change anymore. You can fetch the complete statistics table any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), this table will no longer be accessible via the get_papertrading_report_statistics() method. You can save the fetched report table to a .csv file if you'd like to refer to it at a later point in time.

EMA-Regular-Order strategy – fetching a paper trading report – order history

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs, the P&L table, and statistics table, the AlgoBulls paper trading engine also generates an order history log in real time. This log contains state transitions of every order, along with the timestamps and additional information (if any) for each order state. The order history log is crucial in understanding how long it has taken for a trade to go from 'OPEN' to 'COMPLETE' or to the 'CANCELLED' state. For example, the MARKET orders would immediately go from an 'OPEN' to 'COMPLETE' state but the LIMIT orders may take a while, based on the market conditions, to go from an 'OPEN' to 'COMPLETE' state, or they may even get to 'CANCELLED'. All this information is available in the order history log. (Refer to the state machine diagrams in Chapter 6, Placing Orders on the Exchange, for more information on order state transitions.)

In this recipe, you will fetch the order history log for your strategy. This log is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the order history log in real time, even while the paper trading job is still going on. This helps us get details for orders in the end states without having to wait for the paper trading job to complete. The pyalgotrading package provides a simple method to fetch the order history log for a given strategy.

Make sure you have gone through the first six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyEMARegularOrder.

Getting ready

Make sure the algobulls_connection and strategy_code1 objects are available in your Python namespace. Refer to the first recipe of this chapter to set up the algobulls_connection and strategy_code1 objects.

How to do it…

Fetch the paper trading order history report for strategy_code1:

>>> order_history = 
algobulls_connection.get_papertrading_report_order_history(
strategy_code1)

We get the following output. Your output may differ:

+-------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|-------------+---------------------+----------------------------------+------|
| NSE_EQ:SBIN | 2020-07-09 10:30:00 | 96c24ca4b3e448f381fc5c2bc52f7a29 | BUY |
+-------------+---------------------+----------------------------------+------+
+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:30:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:30:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:30:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:30:00 | OPEN | |
| 4 | 2020-07-09 10:30:00 | COMPLETE | |
+----+---------------------+------------------------+-------+
+-------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|-------------+---------------------+----------------------------------+------|
| NSE_EQ:SBIN | 2020-07-09 10:45:00 | 3bbd433edd004630b122de07873864d7 | SELL |
+-------------+---------------------+----------------------------------+------+
+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:45:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:45:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:45:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:45:00 | OPEN | |
| 4 | 2020-07-09 10:45:00 | COMPLETE | |
+----+---------------------+------------------------+-------+
...

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/sample/papertrading/strategy_ema_regular_order/oms_order_history.log

How it works…

In this recipe, you use the get_papertrading_report_order_history() method of the algobulls_connection object to fetch order history logs in real time. This method accepts strategy code as an argument. You pass strategy_code1 here. The return data is a string, described as follows:

For every order, the log has the following information:

  • A descriptive table on the order, with the following columns:
  • INST: The financial instrument of the order
  • TIME: The time at which the order was placed
  • ID: The unique ID of the order
  • TT: The order transaction type (BUY or SELL)

A sample of the table is shown as follows: 

+-------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|-------------+---------------------+----------------------------------+------|
| NSE_EQ:SBIN | 2020-07-09 10:30:00 | 96c24ca4b3e448f381fc5c2bc52f7a29 | BUY |
+-------------+---------------------+----------------------------------+------+

This information will help you find this exact order in the strategy execution log.

  • An order state transition table, with the following columns:
  • TIME: The time at which the order is present in the state represented by the 'STATE' column.
  • STATE: The order enters into this state at the time mentioned in the 'TIME' column.
  • MSG: Additional message from the OMS for any unexpected state transitions. For example, orders that go to the REJECTED state have a message from the OMS stating the reason for their rejection. This column is usually empty.

A sample of the table is shown as follows:

+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:30:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:30:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:30:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:30:00 | OPEN | |
| 4 | 2020-07-09 10:30:00 | COMPLETE | |
+----+---------------------+------------------------+-------+

From this table, you can see that upon placing the order at 10:30 AM, it transitions to the 'COMPLETE' state immediately. This is expected as the order is a regular market order. (Refer to the first recipe of Chapter 6, Placing Regular Orders on the Exchange, for more details on regular market orders.)

There's more...

Once the paper trading job moves to the 'STOPPED' state, no new order history logs are generated. You can fetch the complete order history logs any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), these logs will no longer be accessible via the get_papertrading_report_order_history() method. You can save the fetched logs to a file if you'd like to refer to it at a later point in time.

MACD-Bracket-Order strategy – fetching the strategy

In this recipe, you will fetch the strategy class, StrategyMACDBracketOrder, from your account on the AlgoBulls platform, which you must have uploaded while going through the last recipe of Chapter 8Algorithmic Trading Strategies – Coding Step by Step. This recipe starts with setting up a connection to the AlgoBulls platform, querying all available strategies in your account  and fetching details of the required strategy class, StrategyMACDBracketOrder.

Make sure you have gone through the last six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

How to do it…

We execute the following steps for this recipe:

  1. Import the necessary modules:
>>> from pyalgotrading.algobulls import AlgoBullsConnection
  1. Create a new AlgoBulls connection object:
>>> algobulls_connection = AlgoBullsConnection()
  1. Fetch the authorization URL:
>>> algobulls_connection.get_authorization_url()

We get the following output:

Please login to this URL with your AlgoBulls credentials and get your developer access token: https://app.algobulls.com/user/login
'https://app.algobulls.com/user/login'
  1. Log in to the preceding link with your AlgoBulls credentials, fetch your token, and set it here (refer to Appendix II for more details):
>>> algobulls_connection.set_access_token(
'80b7a69b168c5b3f15d56688841a8f2da5e2ab2c')

  1. Fetch and display all strategies you have created and uploaded so far:
>>> all_strategies = algobulls_connection.get_all_strategies()
>>> all_strategies

We get the following output. Your output may differ (make sure you have followed the recipes in Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a similar output):

  1. Fetch and display the strategy code of the second strategy, the MACD-Bracket-Order strategy:
>>> strategy_code2 = all_strategies.iloc[1]['strategyCode']
>>> strategy_code2

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

'49287246f9704bbcbad76ade9e2091d9'
  1. Before paper trading your strategy, you can inspect your strategy to ensure you have the right strategy:
>>> strategy_details2 = 
algobulls_connection.get_strategy_details(strategy_code2)
>>> print(strategy_details2)

We get the following output:

class StrategyMACDBracketOrder(StrategyBase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.fastMA_period =
self.strategy_parameters['fastma_period']
self.slowMA_period =
self.strategy_parameters['slowma_period']
self.signal_period =
self.strategy_parameters['signal_period']
self.stoploss =
self.strategy_parameters['stoploss_trigger']
self.target = self.strategy_parameters['target_trigger']
self.trailing_stoploss =
self.strategy_parameters['trailing_stoploss_trigger']

self.main_order = None

def initialize(self):
self.main_order = {}

@staticmethod
def name():
return 'MACD Bracket Order Strategy'
….
def strategy_exit_position(self, candle, instrument,
sideband_info):
if sideband_info['action'] == 'EXIT':
self.main_order[instrument].exit_position()
self.main_order[instrument] = None
return True

return False

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/strategy_macd_bracket_order.py

How it works…

You import the necessary modules in step 1. In step 2, you create an instance of the AlgoBullsConnection class, named algobulls_connection. In step 3, you get the authorization URL using the get_authorization_url() method of the algobulls_connection object. This prints the authorization URL. You should visit this URL from your web browser to sign in to the AlgoBulls platform and fetch your developer access token. (You can find more details with screenshots in Appendix II on fetching developer access token from the AlgoBulls platform.) You copy the access token and set it in step 4 using the set_access_token() method of algobulls_connection. If the token is accepted, a successful connection is set up with the AlgoBulls platform.

In step 5, you fetch all strategies you have created and uploaded on the AlgoBulls platform so far. You use the get_all_strategies() method for this step and assign it to a new variable, all_strategies. This variable is a pandas.DataFrame object with the strategyCode and strategyName columns. This table holds information on the strategy codes and strategy names you have uploaded previously. If you have followed the MACD-Bracket-Order strategy – uploading the strategy on the AlgoBulls trading platform recipe from Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, you will find a strategy with the name MACD-Regular-Order strategy. In step 6, you assign the strategy code of the MACD-Regular-Order strategy strategy, to a new variable, strategy_code2. The strategy code is shown in the output of this step. This strategy code is unique for every strategy on the AlgoBulls platform.

Finally, in step 7, you ensure that the strategy referred by strategy_code2 is indeed the one you uploaded earlier (in the last recipe of Chapter 8Algorithmic Trading Strategies – Coding Step by Step). You use the get_strategy_details() method of the algobulls_connection object to inspect the strategy. This method takes strategy code as an argument. You pass strategy_code2 here. This method returns the entire class code as a string. You assign it to a new variable, strategy_details2, and display it.

If you would like to change the class code referred by strategy_code2, as shown in step 7, please refer to There's more… section of the last recipe in Chapter 8, Algorithmic Trading Strategies – Coding Step by Step.

MACD-Bracket-Order strategy – paper trading the strategy

In this recipe, you will perform paper trading on the MACD-Bracket-Order strategy strategy. You must have fetched this strategy from your account on the AlgoBulls platform in the preceding recipe of this chapter. You will leverage the paper trading functionality facilitated by pyalgotrading for this recipe, which in turn submits a paper trading job on the AlgoBulls platform. 

Once submitted, paper trading will be run by the AlgoBulls paper trading engine. You can query the status any time to know the state of the paper trading job. The job goes through the following states, in the following given order: 

  • 'STARTING' (intermediate state)
  • 'STARTED' (stable state)
  • 'STOPPING' (intermediate state)
  • 'STOPPED' (stable state)

On submitting a job, it starts with an intermediate state, 'STARTING'. In this state, the AlgoBulls paper trading engine will fetch the strategy and get the execution environment ready, which may take a couple of minutes. Once done, the job moves to the 'STARTED' state. The paper trading strategy happens in this stage. Here, it stays as long as it takes for paper trading to complete. Once done, the job moves to an intermediate state, 'STOPPING'. In this state, the AlgoBulls paper trading engine cleans up the resources allocated for this job, which usually takes less than a minute. Finally, the job moves to the 'STOPPED' state.

If you have already submitted a paper trading job for a strategy, you cannot submit another job for the same strategy until the first job completes. This means you have to wait for the first job to move to the 'STOPPED' state. If the first job is long-running and you would like to stop it immediately, you can submit a stop job request via pyalgotrading. You need to ensure the job is in the 'STARTED' state before submitting the request. 

After submitting a paper trading job, you can fetch logs and reports for the strategy execution in real time. The logs and reports help validate the strategy performance and debug any potential issues.

You can refer to the second recipe of this chapter for the state machine diagram of a paper trading job. It demonstrates the various states and transitions of a paper trading job during its lifetime on the AlgoBulls platform.

Make sure you have gone through the last six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

Getting ready

Make sure the algobulls_connection and strategy_code2 objects are available in your Python namespace. Refer to the MACD-Bracket-Order strategy – fetching the strategy recipe of this chapter to set up the algobulls_connection and strategy_code2 objects.

How to do it…

We execute the following steps for this recipe:

  1. Import the necessary modules:
>>> from datetime import time
>>> from pyalgotrading.constants import *
  1. Search for an instrument using its trading symbol as a keyword. Assign the returned object to instruments:
>>> instrument = algobulls_connection.search_instrument(
'TATASTEEL')
>>> instrument

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

[{'id': 1, 'value': 'NSE:TATASTEEL'}]
  1. Get value for the instrument of choice from instruments:
>>> instrument = instrument[0]['value']
>>> instrument

We get the following output:

'NSE:TATASTEEL'
  1. Submit a paper trading job for strategy_code2:
>>> algobulls_connection.papertrade(
strategy_code=strategy_code2,
start_time=time(hour=9, minute=15),
end_time=time(hour=15, minute=30),
instrument=instrument,
lots=1,
strategy_parameters={
'fastma_period': 26,
'slowma_period': 6,
'signal_period': 9,
'target_trigger': 0.01,
'stoploss_trigger': 0.01,
'trailing_stoploss_trigger': 1
},
candle_interval=CandleInterval.MINUTES_15)

We get the following output:

Setting Strategy Config... Success.
Submitting PAPERTRADING job... Success.
  1. Check the status of the submitted paper trading job:
>>> algobulls_connection.get_papertrading_job_status(
strategy_code2)
{'data': 'STARTING'}
  1. Check the status of the submitted paper trading job again after some time:
>>> algobulls_connection.get_papertrading_job_status(
strategy_code2)
{'data': 'STARTED'}

How it works…

In step 1, you import the time class from the datetime module and all constants from the pyalgotrading.constants module. In step 2, you fetch the instrument for which you would like to paper trade the strategy, MACD-Bracket-Order strategy, using the search_instrument() method of the algobulls_connection object. The search_instrument() method accepts a search string as an argument, which should be the trading symbol, in part or complete, of the instrument you are interested in. You pass 'TATASTEEL' here. This function returns a list with details of instruments that match the search string. There could be multiple instruments that could have the search string in their trading symbols. In step 3, you fetch the value of the first matched instrument and assign it to a new variable, instrument.

In step 4, you submit a paper trading job using the papertrade() method of the algobulls_connection() object. It takes the following arguments:

  • strategy_code: The strategy code of the strategy for which paper trading has to be performed. Should be a string. You pass strategy_code2 here.
  • start_time: Today's time from when paper trading should be started. Should be a datetime.time object. Here, you pass an object holding the value 9 hours 15 – time(hour=9, minute=15). Refer to the first recipe of this book for details on creating a time object.
  • end_time: Today's time until when paper trading should be performed. This object should hold a time value ahead of the value held by start_time. Should be a datetime.time instance. Here, you pass an object holding the value 15:30 hours – time(hour=15, minute=30).
  • instrument: The financial instrument for which paper trading should be run. Historical data will be fetched for this instrument. Should be a string. You pass instrument here.
  • lots: The number of lots for which paper trading should be performed. Should be an integer. The quantity is calculated by the strategy as number of lots × lot size of the financial instrument. You pass 1 here.
  • strategy_parameters: The parameter names and values expected by the strategy. Should be a dictionary, with parameter-name and parameter-value as key-value pairs. You pass the following parameters here:
  • fastma_period: 26
  • slowma_period: 6 
  • signal_period: 9
  • target_trigger: 0.01
  • stoploss_trigger: 0.01
  • trailing_stoploss_trigger: 1

(Recall that the parameters for MACD-Bracket-Order strategy have been defined in its __init__() method, as shown in the first recipe of Chapter 8Algorithmic Trading Strategies – Coding Step by Step).

  • candle_interval: The candle interval for the historical data fetched for paper trading. Should be an enum of the type CandleInterval. You pass CandleInterval.MINUTES_15 here. (The CandleInterval enum provides various enums for candle intervals, some of which are MINUTE_1, MINUTES_3 , MINUTES_5, MINUTES_10, MINUTES_15, MINUTES_30, HOUR, and DAY.)

If the job submission is successful, you will see Success messages printed by the papertrade() function. 

Once a job is submitted, it takes a while to start. After starting, it may take some time to finish depending on the duration of paper trading specified using the start_time and end_time arguments. Usually, paper trading is run for the entire trading day, which means the job would be running for 6–8 hours.

In step 5, you fetch the job status using the get_papertrading_job_status() method of the algobulls_connection object. You pass strategy_code2 as the argument here. This method returns a dictionary with a single key-value pair, the data and the job status. If you query the status immediately after placing the job, you get 'STARTING' as the status. In step 6, you query the status again after some time, and if the job has started, you get the status as 'STARTED'.

A successful submission implies that the minimum inputs needed to paper trade a strategy have been passed in the required format. It, however, does not ensure that the strategy will run without errors. The strategy execution may still run into errors during paper trading. To debug execution issues, you would need to fetch the output logs, which is explained in the next recipe. Possible reasons for errors could be either bugs in the strategy class Python code or an incomplete strategy_parameters dictionary passed to the papertrade() function.

There's more…

If a job is running for a long time and you would like to stop it before its completion, you can use the stop_papertrading_job() method of the algobulls_connection object. This method accepts strategy code as an argument. You pass strategy_code2 here. This method submits a stop request to the AlgoBulls paper trading engine. If the request is accepted, you see a Success message here:

>>> algobulls_connection.stop_papertrading_job(strategy_code2)
Stopping PAPERTRADING job... Success.

If you query the status after submitting the stop request, you get the status as 'STOPPING':

>>> algobulls_connection.get_papertrading_job_status(strategy_code2)
{'data': 'STOPPING'}

If you query the status again after some time, and if the job has stopped, you get the status as 'STOPPED':

>>> algobulls_connection.get_papertrading_job_status(strategy_code2)
{'data': 'STOPPED'}

MACD-Bracket-Order strategy – fetching paper trading logs in real time

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, every event that occurs and decisions taken by the AlgoBulls paper trading engine are recorded with exact timestamps in the form of textual logs. Examples of recorded activities include the given strategy config, every new candle generated at regular intervals, trades punched by your strategy, the entry and exit of positions created by these trades, waits for new candles, and so on. These logs are quintessential in validating the strategy behavior and debugging behavioral or performance issues that are frequently encountered while developing a strategy.

In this recipe, you will fetch paper trading logs for your strategy. The logs start coming up as soon as your submitted paper trading job reaches the 'STARTED' state (refer to the preceding recipe for more information on states of a paper trading job). The AlgoBulls platform allows you to fetch logs in real time, even while the paper trading job is still going on. You can get insights into the strategy execution without having to wait for the paper trading job to complete, which is helpful when jobs are long-running. The pyalgotrading package provides a simple method to fetch the execution logs for a given strategy.

Make sure you have gone through the last six recipes of Chapter 8Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

Getting ready

Make sure the algobulls_connection and strategy_code2 objects are available in your Python namespace. Refer to the MACD-Bracket-Order strategy – fetching the strategy recipe of this chapter to set up the algobulls_connection and strategy_code2 objects.

How to do it…

We execute the following steps for this recipe:

  1. Fetch the paper trading execution logs for strategy_code2:
>>> logs = algobulls_connection.get_papertrading_logs(
strategy_code2)
>>> print(logs)

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

[2020-07-09 09:14:12] Logs not available yet. Please retry in sometime.
  1. Fetch the paper trading execution logs for strategy_code2 again after some time:
>>> logs = algobulls_connection.get_papertrading_logs(
strategy_code2)
>>> print(logs)

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

...
########################################
INITIALIZING ALGOBULLS CORE (v3.2.0)...
########################################

[PT] [2020-07-09 09:15:00] [INFO] [tls] STARTING ALGOBULLS CORE…

[PT] [2020-07-09 09:45:00] [CRITICAL] [order] [PLACING NEW ORDER] [2020-07-09 09:45:00] [a310755e3d8b4a1ab4667882bf25751d] [BUY] [NSE:TATASTEEL] [QTY:1] [QTY PENDING: 1] [ENTRY PRICE: 345.0] [PRICE:345.0] [TRIGGER PRICE:None] [ORDER_TYPE_BRACKET] [ORDER_CODE_INTRADAY] [ORDER_VARIETY_LIMIT] [ORDER_POSITION_ENTER] [STOPLOSS TRIGGER:341.55] [TARGET TRIGGER:348.45] [TRAILING STOPLOSS TRIGGER:345.0]
...
[PT] [2020-07-09 15:30:00] [INFO] [clock] Candle generation has been stopped...
[PT] [2020-07-09 15:30:00] [INFO] [tls] Received event END OF MARKET. Stopping Trading Core Engine...
[PT] [2020-07-09 15:30:00] [INFO] [tls] Exiting all open positions with order code: ORDER_CODE_INTRADAY (if any)...
[PT] [2020-07-09 15:30:00] [CRITICAL] [tls] [User: ALGOBULLS VIRTUAL USER] Trading session completed

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/sample/papertrading/strategy_macd_bracket_order/logs.txt

How it works…

In step 1, you use the get_papertrading_logs() method of the algobulls_connection object to fetch the strategy paper trading logs in real time. This method accepts strategy code as an argument. You pass strategy_code2 here. The return data is a string. If you try this step immediately after submitting the job, you get a string that says the logs are not ready yet ([2020-07-09 09:14:12] Logs not available yet. Please retry in sometime.). This happens if the paper trading job is in the 'STARTING' state.

In step 2, you fetch the logs again after some time. If the job is out of the 'STARTING' state, you start getting your strategy execution logs. You get the entire paper trading logs every time you call the get_papertrading_logs() function.

There's more...

Once the paper trading job moves to the 'STOPPED' state, no new logs are generated. You can fetch the complete logs any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), these logs will no longer be accessible via the get_papertrading_logs() method. You can save the fetched logs to a file if you'd like to refer to it at a later point in time.

MACD-Bracket-Order strategy – fetching a paper trading report – profit and loss table

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs, the AlgoBulls paper trading engine also generates a P&L table in real time. This table holds information on every trade punched by the strategy. It also has details on the mapping between entry and exit orders and the trade P&L and cumulative P&L, sorted chronologically, with the latest order first. This table gives an insight into the overall strategy performance with the help of individual and cumulative P&L numbers. The entry-exit order mapping also helps validate the strategy behavior. 

In this recipe, you will fetch the P&L table report for your strategy. This report is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the P&L table in real time, even while the paper trading job is still going on. You can get insights into the strategy performance without having to wait for the paper trading job to complete. This is helpful as paper trading jobs are usually long-running. The pyalgotrading package provides a simple method to fetch the P&L table for a given strategy.

Make sure you have gone through the last six recipes of Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

Getting ready

Make sure the algobulls_connection and strategy_code2 objects are available in your Python namespace. Refer to the MACD-Bracket-Order strategy – fetching the strategy recipe of this chapter to set up the algobulls_connection and strategy_code2 objects.

How to do it…

Fetch the paper trading P&L report for strategy_code2:

>>> algobulls_connection.get_papertrading_report_pnl_table(strategy_code2)

We get the following output. Your output may differ (note that the following output has been split into multiple tables for representation purposes. You will see a single wide table in your Jupyter notebook):

How it works…

In this recipe, you use the get_papertrading_report_pnl_table() method of the algobulls_connection object to fetch the paper trading P&L table in real time. This method accepts strategy code as an argument. You pass strategy_code2 here. The return data is a pandas.DataFrame object with multiple columns, described as follows:

  • instrument: The financial instrument for which trade was entered.
  • entry_timestamp: The timestamp at which the entry order was placed. (Note that it may remain in the 'OPEN' state for a while before it goes to the 'COMPLETE' state. The time for this state transition can be found using the order history table, explained in the EMA-Regular-Order strategy – fetching the paper trading report – order history recipe of this chapter.)
  • entry_transaction_type: The entry order transaction type (either BUY or SELL).
  • entry_quantity: The entry order quantity.
  • entry_price: The price at which the entry order gets executed and goes to the 'COMPLETE' state.
  • exit_timestamp: The timestamp at which the exit order was placed. (Note that it may remain in the 'OPEN' state for a while before it goes to the 'COMPLETE' state.)
  • exit_transaction_type: The exit order transaction type (either BUY or SELL).
  • exit_quantity: The exit order quantity.
  • exit_price: The price at which the exit order gets executed and goes to the 'COMPLETE' state.
  • pnl_absolute: The difference between the exit order execution price and entry order execution price. Mathematically, this is (exit_price - entry_price)*exit_quantity for a long trade and (entry_price - exit_price)*exit_quantity for a short trade. A positive value would imply that the trade is a profit-making trade. A negative value would imply that the trade is a loss-making trade.
  • pnl_percentage: The percentage of profit or loss with respect to the entry price. Mathematically, this is pnl_absolute / entry_price / exit_quantity x 100.

  • pnl_cumulative_absolute: The cumulative profit or loss. Mathematically, this is the sum of all the pnl_absolute values of the previous trades. This number gives a direct insight into the strategy performance against the simulation time.
  • pnl_cumulative_percentage: The percentage of cumulative profit or loss with respect to the entry price. Mathematically, this is pnl_cumulative / entry_price / exit_quantity x 100.

There's more...

Once the paper trading job moves to the 'STOPPED' state, the P&L table report will not update anymore. You can fetch the complete P&L report any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), this report will no longer be accessible via the get_papertrading_report_pnl_table() method. You can save the fetched report to a .csv file if you'd like to refer to it at a later point in time.

MACD-Bracket-Order strategy – fetching a paper trading report – statistics table

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs and P&L table, the AlgoBulls paper trading engine also generates a summary from the P&L table in real time. This summary is a table of statistics containing various statistical numbers, such as Net P&L (absolute and percentage), Max Drawdown (absolute and percentage), the count of total trades, winning trades, losing trades, long trades, and short trades, maximum gain and minimum gain (or maximum loss), and the average profit per winning and losing trade. This table gives an instant overview of the overall strategy performance.

In this recipe, you will fetch the statistics table report for your strategy. This report is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the statistics table in real time, even while the paper trading job is still going on. You can get insights into the strategy performance without having to wait for the paper trading job to complete. This is helpful as paper trading jobs are usually long-running. The pyalgotrading package provides a simple method to fetch the statistics table for a given strategy.

Make sure you have gone through the last six recipes of Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

Getting ready

Make sure the algobulls_connection and strategy_code2 objects are available in your Python namespace. Refer to the MACD-Bracket-Order strategy – fetching the strategy recipe of this chapter to set up the algobulls_connection and strategy_code2 objects.

How to do it…

Fetch the paper trading statistics report for strategy_code2:

>>> algobulls_connection.get_papertrading_report_statistics(strategy_code2)

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

How it works…

In this recipe, you use the get_papertradig_report_statistics() method of the algobulls_connection object to fetch the paper trading statistics table in real time. This method accepts strategy code as an argument. You pass strategy_code2 here. The return data is a pandas.DataFrame object with two columns—highlight_type and highlight_value—and multiple rows. The rows are described as follows:

  • Net PnL: The cumulative paper trading P&L. This is also the pnl_cumulative_absolute value of the first entry in the P&L table.
  • Net PnL %: The cumulative paper trading P&L percentage. This is also the pnl_cumulative_percentage value of the first entry in the P&L table.
  • Max Drawdown: The lowest value in the pnl_cumulative column of the P&L table. This indicates the maximum loss your strategy has encountered during the execution.
  • Max Drawdown %: Mathematically, this is (Max Drawdown) / (corresponding entry_price )/ exit_quantity × 100.
  • Number of Trades: Total trades (entry and exit counted as one) during the session.
  • Number of Wins: The count of trades where the trade P&L was non-negative.
  • Number of Losses: The count of trades where the trade P&L was negative.
  • Number of Long Trades: The count of trades where the entry transaction type was 'BUY'.
  • Number of Short Trades: The count of trades where the entry transaction type was 'SELL'.
  • Max Gain: The P&L of the trade with maximum P&L value among all trades.
  • Min Gain: The P&L of the trade with the minimum P&L value among all trades.
  • Avg. Profit per winning trade: Mathematically, this is (Total P&L of winning trades) / (Count of winning trades).
  • Avg. Profit per losing trade: Mathematically, this is (Total P&L of losing trades) / (Count of losing trades).

There's more...

If the statistics table is fetched while the paper trading job is still running, the previously mentioned numbers would be intermediate numbers, based on the trades completed until that time. The numbers may change as more trades are punched until the paper trading job completes.

Once the paper trading job moves to the 'STOPPED' state, the statistics table will not change anymore. You can fetch the complete statistics table any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), this table will no longer be accessible via the get_papertrading_report_statistics() method. You can save the fetched report to a .csv file if you'd like to refer to it at a later point in time.

MACD-Bracket-Order strategy – fetching a paper trading report – order history

After submitting a paper trading job on the AlgoBulls platform, the AlgoBulls paper trading engine starts executing the strategy. During the execution, along with the logs, P&L table, and statistics table, the AlgoBulls paper trading engine also generates an order history log in real time. This log contains state transitions of every order, along with the timestamps and additional information (if any) for each order state. The order history log is crucial in understanding how long it has taken for a trade to go from 'OPEN' to 'COMPLETE' or to the 'CANCELLED' state. For example, the MARKET orders would immediately go from an 'OPEN' to 'COMPLETE' state but the LIMIT orders may take a while, based on the market conditions, to go from an 'OPEN' to 'COMPLETE' state, or they may even get to the 'CANCELLED' state. All this information is available in the order history log. (Refer to the state machine diagrams in Chapter 6, Placing Regular Orders on the Exchange, for more information on order state transitions.)

In this recipe, you will fetch the order history log for your strategy. This log is available as soon as the first trade is punched by your strategy after you submit a paper trading job. The AlgoBulls platform allows you to fetch the order history log in real time, even while the paper trading job is still going on. This helps us get details for orders in the end states without having to wait for the paper trading job to complete. The pyalgotrading package provides a simple method to fetch the order history log for a given strategy.

Make sure you have gone through the last six recipes of Chapter 8, Algorithmic Trading Strategies – Coding Step by Step, to get a complete picture of the strategy class used, StrategyMACDBracketOrder.

Getting ready

Make sure the algobulls_connection and strategy_code2 objects are available in your Python namespace. Refer to the MACD-Bracket-Order strategy – fetching the strategy recipe of this chapter to set up the algobulls_connection and strategy_code2 objects.

How to do it…

Fetch the paper trading order history report for strategy_code2:

>>> order_history = 
algobulls_connection.get_papertrading_report_order_history(
strategy_code2)
>>> print(order_history)

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


+------------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|------------------+---------------------+----------------------------------+------|
| NSE_EQ:TATASTEEL | 2020-07-09 10:00:00 | 56970bffe8be4650a71857bc4472e6c8 | SELL |
+------------------+---------------------+----------------------------------+------+
+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:00:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:00:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:00:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:00:00 | OPEN | |
| 4 | 2020-07-09 10:15:00 | COMPLETE | |
+----+---------------------+------------------------+-------+
+------------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|------------------+---------------------+----------------------------------+------|
| NSE_EQ:TATASTEEL | 2020-07-09 10:00:00 | 0a06e41aac0744adb45bb4d3d2e19728 | SELL |
+------------------+---------------------+----------------------------------+------+
+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:00:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:00:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:00:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:00:00 | TRIGGER PENDING | |
| 4 | 2020-07-09 10:15:00 | CANCEL PENDING | |
| 5 | 2020-07-09 10:15:00 | CANCELLED | |
+----+---------------------+------------------------+-------+
...

The complete output is not shown here. Please visit the following link to read the complete output: https://github.com/algobulls/pyalgostrategypool/blob/master/pyalgostrategypool/sample/papertrading/strategy_macd_bracket_order/oms_order_history.log

How it works…

In this recipe, you use the get_papertrading_report_order_history() method of the algobulls_connection object to fetch order history logs in real time. This method accepts strategy code as an argument. You pass strategy_code2 here. The return data is a string, described as follows:

For every order, the log has the following information:

  • A descriptive table on the order, with the following mentioned columns:
  • INST: The financial instrument of the order
  • TIME: The time at which the order was placed
  • ID: The unique ID of the order
  • TT: The order transaction type (BUY or SELL)

A sample of the table is shown as follows: 

+------------------+---------------------+----------------------------------+------+
| INST | TIME | ID | TT |
|------------------+---------------------+----------------------------------+------|
| NSE_EQ:TATASTEEL | 2020-07-09 10:00:00 | 0a06e41aac0744adb45bb4d3d2e19728 | SELL |
+------------------+---------------------+----------------------------------+------+

This information will help you find this exact order in the strategy execution log.

  • An order state transition table, with the following mentioned columns:
  • TIME: The timestamp at which the order enters into the state represented by the STATE column.
  • STATE: The order enters into this state at the timestamp mentioned in the TIME column.
  • MSG: Additional message from OMS for any unexpected state transitions. For example, orders that go to the REJECTED state have a message from the OMS stating the reason for their rejection. This column is usually empty.

A sample of the table is shown as follows:

+----+---------------------+------------------------+-------+
| | TIME | STATE | MSG |
|----+---------------------+------------------------+-------|
| 0 | 2020-07-09 10:00:00 | PUT ORDER REQ RECEIVED | |
| 1 | 2020-07-09 10:00:00 | VALIDATION PENDING | |
| 2 | 2020-07-09 10:00:00 | OPEN PENDING | |
| 3 | 2020-07-09 10:00:00 | TRIGGER PENDING | |
| 4 | 2020-07-09 10:15:00 | CANCEL PENDING | |
| 5 | 2020-07-09 10:15:00 | CANCELLED | |
+----+---------------------+------------------------+-------+

From this table, you can see that upon placing the order at 10:00 AM, it transitions to the  TRIGGER PENDING state. It stays there for 15 minutes before transitioning to the CANCELLED state. This is expected as the order is a bracket limit order.

There's more...

Once the paper trading job moves to the STOPPED state, no new order history logs are generated. You can fetch the complete order history logs any time before you submit the next paper trading job for the same strategy. If a new paper trading job is submitted (for the same strategy), these logs will no longer be accessible via the get_papertrading_report_order_history() method. You can save the fetched logs to a file if you'd like to refer to it at a later point in time.

..................Content has been hidden....................

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