img

Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets

img
valuezone 20 March 2024

Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets

The Average Directional Movement indicator is a popular technical indicator that helps traders understand the strength of a trend. It’s particularly powerful for trading bots as it helps identify the type of market being experiences — and therefore which algorithm should be used.

For instance, when the ADX is low, this can indicate that market is trading in a range (known as trading sideways). This can indicate to your trading bot that it should NOT select a momentum-based trading algorithm. Alternatively, when the ADX is above 50, it can indicate that the market is gaining momentum…indicating a great time to switch to a momentum -based trading algorithm.

Adding this technical indicator to your trading bot can be a great way to help you automate more of your trading decision making.

You can read more about it here.

In this article, I’m going to show you how to add the ADX indicator to your trading bot.

About This Episode 🤖

In this article, I’m going to show you how to add the ADX to your auto trading bot. I’ll be demonstrating it on US Market data from Alpaca Markets, although you can also use it on any other candlestick data.

Legal Stuff ⚖️

  • DYOR. All trading is at your own risk. My goal is to provide you with the self-developed methods, systems, and tools I use — it is up to you to figure out if this solution works for you AND if I’ve provided credible content. Always DYOR (Do Your Own Research).
  • Not Financial Advice. At no point should you consider anything in these articles to be financial advice. Any opinions expressed are about the technical aspects of the topic, not financial suitability.
  • Referrals. I receive no commissions for any of the products I mention in this blog. They’re all free (or have a free tier), and I simply provide links to simplify your learning experience.
  • AI Use. No AI was harmed in the creation of this blog. Some of the images are partially generated or enhanced through AI tools, we always use a real human to put them together. I do not use AI to generate the text, just spell check.

How to Prepare Your Trading Bot to Add Multiple Indicators

P.S. If you’ve added other indicators from my previous articles or YouTube videos, skip this step.

Technical indicators seem to be an ever-growing science. TA Lib alone has over 100 different technical indicators, and there are plenty of custom ones available.

Therefore, our trading bot must be able to handle multiple technical indicators

Step 1: Indicators.py

We’ll start by adding a file called indicators.py to our trading bot. This file will handle all of our indicators.

Add the file by navigating to your trading bot dev environment and adding a file called indicators.py

Step 2: Python Pandas

Python Pandas makes data analysis exceptionally simple. Given that a trading bot is ALL about the efficient and effective analysis of data, I can’t think of a better library to be adding to your trading bot. You’ll use it over and over again if you follow my content!

Adding it is straightforward.

  • Step 1: Open your requirements.txt
  • Step 2: Add the word pandas to the bottom
  • Step 3: Save
  • Step 4: Run the command pip install -r requirements.txt in your terminal

Step 3: Indicator Routing

Within the indicators.py file you added earlier, we’re going to add some indicator routing. We will take care of adding the actual indicator a bit later.

This indicator routing is responsible for the following:

  1. Selecting the indicator to route to based on anindicator_name string
  2. Ensuring that historical data has been provided
  3. Checking the input parameters for a specified indicator

Note. If you want to see what this indicator file looks like when it has tons of indicators, check out this file on the TradeOxy Trading Bot. It’s the same repo I reference in all my content.

Here’s the code to add this routing:

# Part of the Medium blog article, "Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets" by AppnologyJames
# URL to access article: https://appnologyjames.medium.com/step-by-step-guide-to-adding-the-adx-indicator-to-your-stock-trading-bot-with-python-ta-lib-and-f70e0d559ff6
# Main GitHub Trading Bot Repo: https://github.com/jimtin/tradeoxy-trading-bot
import talib
import pandas
def calc_indicator(indicator_name: str, historical_data: pandas.DataFrame, **kwargs) -> dict:
"""
Function to calculate a specified indicator
:param indicator_name: The name of the indicator to calculate
:param historical_data: The historical data to calculate the indicator from
:param kwargs: Any additional arguments to pass to the indicator function
"""
# Create a return dictionary
return_dictionary = {
"outcome": "unsuccessful",
"indicator": indicator_name,
"values": None,
"indicator_outcome": None
}
# Get the name of the indicator from the indicator name
indicator_name = indicator_name.lower()
# Add the ADX indicator
if indicator_name == "adx":
# Set the indicator to adx in the return dictionary
return_dictionary["indicator"] = "adx"
try:
# Check the kwargs for the ADX period
adx_period = kwargs["adx_period"]
# Get the ADX values
adx_data = calc_adx(
historical_data=historical_data,
timeperiod=adx_period
)
# Set the values in the return dictionary
return_dictionary["values"] = adx_data["values"]
# Set the indicator outcome in the return dictionary
return_dictionary["indicator_outcome"] = adx_data["indicator_outcome"]
# Set the outcome to successful
return_dictionary["outcome"] = "calculated"
except Exception as exception:
print(f"An exception occurred when calculating the ADX: {exception}")
raise exception
# If the indicator name not recognised, raise a ValueError
else:
raise ValueError(f"The indicator {indicator_name} is not recognised.")
# Return the indicator values
return return_dictionary
view rawindicators.py hosted with ❤ by GitHub
Code to add indicator routing to your trading bot in indicators.py. Part of the Medium blog article, “Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets” by Appnology James

Note the use of the **kwargs argument in the function. It’s a super powerful little Python feature 🚀

Add the ADX Technical Indicator to Your Trading Bot

Let’s define the ADX technical indicator function.

P.S. If you want to read more about the ADX technical indicator and how it can indicate market direction, check out this article from Investopedia.

Here’s the code:

# Part of the Medium blog article, "Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets" by AppnologyJames
# URL to access article: https://appnologyjames.medium.com/step-by-step-guide-to-adding-the-adx-indicator-to-your-stock-trading-bot-with-python-ta-lib-and-f70e0d559ff6
# Main GitHub Trading Bot Repo: https://github.com/jimtin/tradeoxy-trading-bot
# Add the ADX indicator
def calc_adx(historical_data: pandas.DataFrame, timeperiod=14):
"""
Function to calculate the ADX indicator
:param historical_data: The historical data to calculate the ADX from
:param timeperiod: The time period for the ADX
"""
# Create a return dictionary
return_dictionary = {
"outcome": "unsuccessful",
"indicator": "adx",
"values": None,
"indicator_outcome": None
}
# Check that the time period is greater than 0
if timeperiod <= 2:
raise ValueError("The time period must be greater than 0.")
# Check that the length of the dataframe is greater than the time period
if len(historical_data) < timeperiod:
raise ValueError("The length of the dataframe must be greater than the time period.")
try:
# Get the ADX values
adx_values = talib.ADX(
historical_data["candle_high"],
historical_data["candle_low"],
historical_data["candle_close"],
timeperiod=timeperiod
)
except Exception as exception:
print(f"An exception occurred when calculating the ADX: {exception}")
raise exception
# Add the ADX values to the historical data
historical_data["adx"] = adx_values
# Set the outcome to successful
return_dictionary["outcome"] = "calculated"
# Create a new column called adx_signal and set the value to hold
historical_data["adx_signal"] = "hold"
# Set the adx_signal to strong when the ADX is greater than 25
historical_data.loc[historical_data["adx"] > 25, "adx_signal"] = "strong"
# Set the adx_signal to weak when the ADX is less than 25
historical_data.loc[historical_data["adx"] < 25, "adx_signal"] = "weak"
# Get the last row of the historical data and get the ADX signal. Set this to value of indicator_outcome in return_dictionary
return_dictionary["indicator_outcome"] = historical_data["adx_signal"].iloc[-1]
# Add the values to the return dictionary
return_dictionary["values"] = historical_data
# Return the dictionary
return return_dictionary
view rawindicators.py hosted with ❤ by GitHub
Code for the ADX technical indicator. Part of the Medium blog article, “Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets” by Appnology James

See the ADX Technical Indicator in Action

Update your app.py file in your trading bot to the following:

# Part of the Medium blog article, "Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets" by AppnologyJames
# URL to access article: https://appnologyjames.medium.com/step-by-step-guide-to-adding-the-adx-indicator-to-your-stock-trading-bot-with-python-ta-lib-and-f70e0d559ff6
# Main GitHub Trading Bot Repo: https://github.com/jimtin/tradeoxy-trading-bot
import alpaca_interactions as alpaca
import datetime
import indicators
# List of symbols
symbols = ["AAPL"]
max_number_of_candles = 1000
timeframe = "1hour"
indicator = "adx"
# Function to run the trading bot
def auto_run_trading_bot():
"""
Function to run the trading bot
"""
# Print Welcome to your very own trading bot
print("Welcome to your very own trading bot")
# Set the end date to yesterday
end_date = datetime.datetime.now() - datetime.timedelta(days=1) # Note that if you have a premium subscription you can remove this restriction
# Set the start date to one year ago
start_date = end_date - datetime.timedelta(days=365)
#### Calculate the an indicator ####
for symbol in symbols:
# Save the symbol text
symbol_text = symbol
# Convert symbol to a list
symbol = [symbol]
# Get the historical data for the symbol
symbol_historical_data = alpaca.get_historic_bars(
symbols=symbol,
timeframe=timeframe,
start_date=start_date,
end_date=end_date,
limit=max_number_of_candles
)
# Calculate the specified indicator
print(f"Calculating the {indicator} for {symbol_text}")
indicator_result = indicators.calc_indicator(
indicator_name=indicator,
historical_data=symbol_historical_data,
adx_period=14
)
# Branch based on indicator_result
if indicator_result["outcome"] == "calculated":
# Print succcess
print(f"The {indicator} was successfully calculated for {symbol_text}")
# Extract the values
values_dataframe = indicator_result["values"]
print(values_dataframe)
else:
# Print and error
print(f"An error occurred when calculating the {indicator} for {symbol_text}")
# Print the full message
print(indicator_result)
# Main function for program
if __name__ == "__main__":
auto_run_trading_bot()
view rawapp.py hosted with ❤ by GitHub
app.py file with ADX indicator in action. Part of the Medium blog article, “Step-by-Step Guide to Adding the ADX Indicator to Your Stock Trading Bot with Python, TA Lib, and Alpaca Markets” by Appnology James

To see what the ADX technical indicator looks like when it runs, here’s a quick YouTube short from my tradeoxy-trading-bot open source repo:

How Trading Bots Super Charge Your Analysis

The true power of trading bots is to hyperscale your analysis. For instance, even though you’ve built this little indicator in the last 10 minutes, you could EASILY do the following:

  • Analyze 10 stocks at once. Simply change the symbols variable to be a list
  • Change the timeframe. Simply change the timeframe line

All this and more is at your fingertips with a simple change of a line of code.