{"id":2470,"date":"2023-10-24T17:58:57","date_gmt":"2023-10-24T17:58:57","guid":{"rendered":"https:\/\/eodhd.com\/financial-academy\/?p=2470"},"modified":"2025-02-05T11:59:16","modified_gmt":"2025-02-05T11:59:16","slug":"algorithmic-trading-with-average-directional-index-in-python","status":"publish","type":"post","link":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python","title":{"rendered":"Algorithmic Trading with Average Directional Index in Python"},"content":{"rendered":"\n<p>There are four different branches of technical indicators out there but the most popular ones are known as trend indicators. These indicators help traders in identifying the direction and strength of the market trend and trade along with them. In most cases, the indicators that come under the category of trend reveal good results unless we use them efficiently.<\/p>\n\n\n\n<p>In this article, we are going to explore one of the most popular trend indicators, the Average Directional Index (shortly known as ADX). We will first build some basic understanding of what ADX is all about and its calculation, then, move on to building the indicator from scratch and construct a trading strategy based on that indicator in Python. To evaluate our strategy, we will first backtest it with the Apple stock, and then to make more sense, we will compare our strategy returns with the SPY ETF returns (an ETF specifically designed to track the movement of the S&amp;P 500 index).<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Average True Range&nbsp;(ATR)<\/h2>\n\n\n\n<p>Before moving on to discovering ADX, it is essential to know what the Average True Range (ATR) is as it is involved in the calculation of the Average Directional Index (ADX).<\/p>\n\n\n\n<p>The Average True Range is a technical indicator that measures how much an asset moves on an average. It is a lagging indicator meaning that it takes into account the historical data of an asset to measure the current value but it\u2019s not capable of predicting the future data points. This is not considered as a drawback while using ATR as it\u2019s one of the indicators to track the volatility of a market more accurately. Along with being a lagging indicator, ATR is also a non-directional indicator meaning that the movement of ATR is inversely proportional to the actual movement of the market. To calculate ATR, it is requisite to follow two steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Calculate True Range (TR):<\/strong> A True Range of an asset is calculated by taking the greatest values of three price differences which are: market high minus market low, market high minus previous market close, and previous market close minus market low. It can be represented as follows:<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container\">\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\"><strong>MAX <\/strong>[ {<strong>HIGH - LOW<\/strong>}, {<strong>HIGH - P.CLOSE<\/strong>}, {<strong>P.CLOSE - LOW<\/strong>} ]\n\nwhere,\nMAX = Maximum values\nHIGH = Market High\nLOW = Market Low\nP.CLOSE = Previous market close<\/pre>\n<\/div><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Calculate ATR:<\/strong> The calculation for the Average True Range is simple. We just have to take a smoothed average of the previously calculated True Range values for a specified number of periods. The smoothed average is not just any SMA or EMA but an own type of smoothed average created by Wilder Wiles himself but there aren\u2019t any restrictions in using other MAs too. In this article, we will be using SMA to calculate ATR rather than the custom moving average created by the founder of the indicator just to make things simple. The calculation of ATR with a traditional setting of 14 as the number of periods can be represented as follows:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\"><strong>ATR 14<\/strong> = <strong>EMA 14<\/strong> [ <strong>TR <\/strong>]\n\nwhere,\nATR 14 = 14 Period Average True Range\nSMA 14 = 14 Period Simple Moving Average\nTR = True Range<\/pre>\n\n\n\n<p>While using ATR as an indicator for trading purposes, traders must ensure that they are cautious than ever as the indicator is very lagging. Now that we have an understanding of what the Average True Range is all about. Let\u2019s now dive into the main concept of this article, the Average Directional Index.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Average Directional Index&nbsp;(ADX)<\/h2>\n\n\n\n<p>ADX is a technical indicator that is widely used in measuring the strength of the market trend. Now, the ADX doesn\u2019t measure the direction of the trend, whether it\u2019s bullish or bearish, but just represents how strong the trend is. So, to identify the direction of the trend, ADX is combined with a Positive Directional Index (+ DI) and a Negative Directional Index (- DI). As the name suggests, the + DI measures the bullish or positive trend of the market, similarly, the &#8211; DI measures the bearish or negative trend of the market. The values of all the components are bound between 0 to 100, hence acting as an oscillator. The traditional setting of ADX is 14 as the lookback period.<\/p>\n\n\n\n<p>To calculate the values of ADX with 14 as the lookback period, first, the Positive (+ DM) and Negative Directional Movement (- DM) is determined. The + DM is calculated by finding the difference between the current high and the previous high, and similarly, the &#8211; DM is calculated by finding the difference between the previous low and the current low. It can be represented as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\">+ DM = CURRENT HIGH - PREVIOUS HIGH\n- DM = PREVIOUS LOW - CURRENT LOW<\/pre>\n\n\n\n<p>Then, an ATR with 14 as the lookback period is calculated. Now, using the calculated directional movement and the ATR values, the Positive Directional Index (+ DI) and the Negative Directional Index (- DI) are calculated. To determine the values of + DI, the value received by taking the Exponential Moving Average (EMA) of the Positive Directional Movement (+ DM) with 14 as the lookback period is divided by the previously calculated 14-day ATR and then, multiplied by 100. This same applies to determining the &#8211; DI too but instead of taking the 14-day EMA of + DM, the Negative Directional Movement (- DM) is taken into account. The formula to calculate both the + DI and the &#8211; DI can be represented as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\">+ DI14 = 100 * [ EMA 14 ( + DM ) \/ ATR 14 ]\n- DI14 = 100 * [ EMA 14 ( - DM ) \/ ATR 14 ]<\/pre>\n\n\n\n<p>The next step is to use the + DI and &#8211; DI to calculate the Directional Index. It can be determined by dividing the absolute value of the difference between the +DI and &#8211; DI by the absolute value of the total of + DI and &#8211; DI multiped by 100. The formula to calculate the Directional Index can be represented as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\"><strong>DI 14<\/strong> = | (<strong>+ DI 14<\/strong>) - (<strong>- DI 14<\/strong>) | \/ | (<strong>+ DI 14<\/strong>) + (<strong>- DI 14<\/strong>) | * <strong>100<\/strong><\/pre>\n\n\n\n<p>The final step is to calculate the ADX itself by utilizing the determined Directional Index values. The ADX is calculated by multiplying the previous Directional Index value with 13 (lookback period &#8211; 1) and adding it with the Directional Index, then multiplied by 100. The formula to calculate the values of ADX can be represented as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\"><strong>ADX 14<\/strong> = [ ( <strong>PREV DI 14<\/strong> * <strong>13 <\/strong>) + <strong>DI 14 <\/strong>] * <strong>100<\/strong><\/pre>\n\n\n\n<p>The ADX cannot be used as it is but needs to be smoothed. Since founded by Wilder Wiles (the founder of ATR too), the ADX is smoothed by a custom moving average we discussed before. We neglected using this custom moving average while calculating ATR as it is possible to use other types of moving averages but it is essential to use while smoothing ADX to get accurate values.<\/p>\n\n\n\n<p>That\u2019s the whole process of calculating the values of ADX. Now, let\u2019s discuss how a simple ADX-based trading strategy can be constructed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>About our trading strategy<\/strong><\/h3>\n\n\n\n<p>In this article, we are going to build a simple crossover strategy that reveals a buy signal whenever the ADX line crosses from below to above 25 and the + DI line is above the &#8211; DI line. Similarly, a sell signal is generated whenever the ADX line crosses from below to above 25 and the &#8211; DI line is above the + DI line. Our trading strategy can be represented as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-background\" style=\"background-color:#abb7c217\">IF P.ADX &lt; 25 AND C.ADX &gt; 25 AND + DI LINE &gt; - DI LINE ==&gt; BUY\nIF P.ADX &lt; 25 AND C.ADX &gt; 25 AND + DI LINE &lt; - DI LINE ==&gt; SELL<\/pre>\n\n\n\n<p>This concludes the theory part of this article. Now, let\u2019s code this indicator from scratch and build the discussed trading strategy out of it in python and backtest it with the Apple stock to see some exciting results. We will also compare our ADX crossover strategy returns with the returns of the SPY ETF to see how well our trading strategy has performed against a benchmark. Without further ado, let\u2019s dive into the coding part.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Implementation in&nbsp;Python<\/h2>\n\n\n\n<p>The coding part is classified into various steps as follows:<\/p>\n\n\n\n<p class=\"has-background\" style=\"background-color:#abb7c217\"><code><strong>1. Importing Packages<br>2. API Key Activation<br>3. Extracting Historical Stock Data<br>4. ADX Calculation<br>5. ADX Indicator Plot<br>6. Creating the Trading Strategy<br>7. Plotting the Trading Lists<br>8. Creating our Position<br>9. Backtesting<br>10. SPY ETF Comparison<\/strong><\/code><\/p>\n\n\n\n<p>We will be following the order mentioned in the above list and buckle up your seat belts to follow every upcoming coding part.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-1: Importing Packages<\/h3>\n\n\n\n<p id=\"65f4\">Importing the required packages into the Python environment is a non-skippable step. The primary packages are going to be eodhd for extracting historical stock data, Pandas for data formatting and manipulations, NumPy to work with arrays and for complex functions, and Matplotlib for plotting purposes. The secondary packages are going to be Math for mathematical functions and Termcolor for font customization (optional).<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\"># IMPORTING PACKAGES\n\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom termcolor import colored as cl\nfrom math import floor\nfrom eodhd import APIClient\n\nplt.rcParams['figure.figsize'] = (20,10)\nplt.style.use('fivethirtyeight')<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>With the required packages imported into Python, we can proceed to fetch historical data for Apple using EODHD&#8217;s <code>eodhd<\/code> Python library. Also, if you haven\u2019t installed any of the imported packages, make sure to do so using the&nbsp;<code>pip<\/code>&nbsp;command in your terminal.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"a9f4\">Step-2: API Key Activation<\/h3>\n\n\n\n<p id=\"c710\">It is essential to register the EODHD API key with the package in order to use its functions. If you don\u2019t have an EODHD API key, firstly, head over to their&nbsp;<a href=\"https:\/\/eodhd.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">website<\/a>, then, finish the&nbsp;<a href=\"https:\/\/eodhd.com\/register\" target=\"_blank\" rel=\"noreferrer noopener\">registration<\/a>&nbsp;process to create an EODHD account, and finally, navigate to the \u2018<a href=\"https:\/\/eodhd.com\/cp\/settings\" target=\"_blank\" rel=\"noreferrer noopener\">Settings<\/a>\u2019 page where you could find your secret EODHD API key. It is important to ensure that this secret API key is not revealed to anyone. You can activate the API key by following this code:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">api_key = '&lt;YOUR API KEY&gt;'\nclient = APIClient(api_key)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p id=\"fd3d\">The code is pretty simple. In the first line, we are storing the secret EODHD API key into the&nbsp;<code>api_key<\/code>&nbsp;and then in the second line, we are using the&nbsp;<code>APIClient<\/code>&nbsp;class provided by the&nbsp;<code>eodhd<\/code>&nbsp;package to activate the API key and stored the response in the&nbsp;<code>client<\/code>&nbsp;variable.<\/p>\n\n\n\n<p id=\"4634\">Note that you need to replace&nbsp;<code>&lt;YOUR API KEY&gt;<\/code>&nbsp;with your secret EODHD API key. Apart from directly storing the API key with text, there are other ways for better security such as utilizing environmental variables, and so on.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"8568\">Step-3: Extracting Historical Data<\/h3>\n\n\n\n<p id=\"ac40\">Before heading into the extraction part, it is first essential to have some background about historical or end-of-day data. In a nutshell, historical data consists of information accumulated over a period of time. It helps in identifying patterns and trends in the data. It also assists in studying market behavior. Now, you can easily extract the historical data of any tradeable assets using the&nbsp;<code>eod<\/code>&nbsp;package by following this code:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\"># EXTRACTING HISTORICAL DATA\n\ndef get_historical_data(ticker, start_date):\n    json_resp = client.get_eod_historical_stock_market_data(symbol = ticker, period = 'd', from_date = start_date, order = 'a')\n    df = pd.DataFrame(json_resp)\n    df = df.set_index('date')\n    df.index = pd.to_datetime(df.index)\n    return df\n\naapl = get_historical_data('AAPL', '2020-01-01')\naapl.tail()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p id=\"c103\">In the above code, we are using the&nbsp;<code>get_eod_historical_stock_market_data<\/code>&nbsp;function provided by the <code>eodhd<\/code> package to extract the split-adjusted historical stock data of Apple. The function consists of the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the&nbsp;<code>ticker<\/code>&nbsp;parameter where the symbol of the stock we are interested in extracting the data should be mentioned<\/li>\n\n\n\n<li>the&nbsp;<code>period<\/code>&nbsp;refers to the time interval between each data point (one-day interval in our case).<\/li>\n\n\n\n<li>the&nbsp;<code>from_date<\/code>&nbsp;and&nbsp;<code>to_date<\/code>&nbsp;parameters which indicate the starting and ending date of the data respectively. The format of the input should be \u201cYYYY-MM-DD\u201d<\/li>\n\n\n\n<li>the&nbsp;<code>order<\/code>&nbsp;parameter which is an optional parameter that can be used to order the dataframe either in ascending (<code>a<\/code>) or descending (<code>d<\/code>). It is ordered based on the dates.<\/li>\n<\/ul>\n\n\n\n<p id=\"a294\">After extracting the historical data, we are performing some data-wrangling processes to clean and format the data. The final dataframe looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"851\" height=\"463\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image-1.png\" alt=\"\" class=\"wp-image-2487\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step-4: ADX Calculation<\/h3>\n\n\n\n<p>In this step, we are going to calculate the values of ADX by following the method we discussed before.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">def get_adx(high, low, close, lookback):\n    plus_dm = high.diff()\n    minus_dm = low.diff()\n    plus_dm[plus_dm &lt; 0] = 0\n    minus_dm[minus_dm &gt; 0] = 0\n    \n    tr1 = pd.DataFrame(high - low)\n    tr2 = pd.DataFrame(abs(high - close.shift(1)))\n    tr3 = pd.DataFrame(abs(low - close.shift(1)))\n    frames = [tr1, tr2, tr3]\n    tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)\n    atr = tr.rolling(lookback).mean()\n    \n    plus_di = 100 * (plus_dm.ewm(alpha = 1\/lookback).mean() \/ atr)\n    minus_di = abs(100 * (minus_dm.ewm(alpha = 1\/lookback).mean() \/ atr))\n    dx = (abs(plus_di - minus_di) \/ abs(plus_di + minus_di)) * 100\n    adx = ((dx.shift(1) * (lookback - 1)) + dx) \/ lookback\n    adx_smooth = adx.ewm(alpha = 1\/lookback).mean()\n    return plus_di, minus_di, adx_smooth\n\naapl['plus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[0]).rename(columns = {0:'plus_di'})\naapl['minus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[1]).rename(columns = {0:'minus_di'})\naapl['adx'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[2]).rename(columns = {0:'adx'})\naapl = aapl.dropna()\naapl.tail()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1194\" height=\"407\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image-2.png\" alt=\"\" class=\"wp-image-2587\"\/><\/figure>\n\n\n\n<p><strong>Code Explanation:<\/strong> We are first defining a function named \u2018get_adx\u2019 that takes a stock\u2019s high (\u2018high\u2019), low (\u2018low\u2019), and close data (\u2018close\u2019) along with the lookback period (\u2018lookback\u2019) as parameters.<\/p>\n\n\n\n<p>Inside the function, we are first calculating and storing the + DM and &#8211; DM into the \u2018plus_dm\u2019 and \u2018minus_dm\u2019 respectively. Then comes the ATR calculation where we are first calculating the three differences and defined a variable \u2018tr\u2019 to store the highest values among the determined differences, then, we calculated and stored the values of ATR into the \u2018atr\u2019 variable.<\/p>\n\n\n\n<p>Using the calculated directional movements and ATR values, we are calculating the + DI and &#8211; DI and stored them into the \u2018plus_di\u2019 and \u2018minus_di\u2019 variables respectively. With the help of the previously discussed formula, we are calculating the Directional Index values and stored them into the \u2018dx\u2019 variable, and applied those values into the ADX formula to calculate the Average Directional Index values. Then, we defined a variable \u2018adx_smooth\u2019 to store the smoothed values of ADX. Finally, we are returning and calling the function to obtain the + DI, &#8211; DI, and ADX values of Apple with 14 as the lookback period.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-5: ADX&nbsp;Plot<\/h3>\n\n\n\n<p>In this step, we are going to plot the calculated ADX values of Apple to make more sense out of it. The main aim of this part is not on the coding section but instead to observe the plot to gain a solid understanding of the Average Directional Index.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)\nax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)\nax1.plot(aapl['close'], linewidth = 2, color = '#ff9800')\nax1.set_title('AAPL CLOSING PRICE')\nax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)\nax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)\nax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)\nax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')\nax2.legend()\nax2.set_title('AAPL ADX 14')\nplt.show()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1801\" height=\"884\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image-3.png\" alt=\"\" class=\"wp-image-2588\"\/><\/figure>\n\n\n\n<p>The above chart is divided into two panels: the upper panel with the closing prices of Apple and the lower panel with the components of ADX. Along with the components, a grey dashed line is plotted which is the threshold for the ADX plotted at a level of 25. As I said before, the ADX doesn&#8217;t track the direction of the trend but instead, the strength and it can be seen several times in the chart where the ADX line increases when the market shows a strong trend (either up or down) and decreases when the market bound to consolidate. This is the same case with both the directional index lines too. We could see that the + DI line increases when the market shows a sturdy uptrend and decreases during a downtrend and vice-versa for the &#8211; DI line.<\/p>\n\n\n\n<p>ADX is not only used to quantify the strength of a market trend but also becomes a handy tool to identify ranging markets (markets where the stock moves back and forth between specific high and low levels showing zero momentum). Whenever the lines move closer to each other, the market is observed to be ranging, similarly, the wider the space between the lines, the more the markets are trending. Those who are introduced to the chart of ADX for the very first time might confuse themselves since the movement of each line is indirectly proportional to the movement of the market.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-6: Creating the trading&nbsp;strategy<\/h3>\n\n\n\n<p>In this step, we are going to implement the discussed Average Directional Index trading strategy in Python.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">def implement_adx_strategy(prices, pdi, ndi, adx):\n    buy_price = []\n    sell_price = []\n    adx_signal = []\n    signal = 0\n    \n    for i in range(len(prices)):\n        if adx[i-1] &lt; 25 and adx[i] &gt; 25 and pdi[i] &gt; ndi[i]:\n            if signal != 1:\n                buy_price.append(prices[i])\n                sell_price.append(np.nan)\n                signal = 1\n                adx_signal.append(signal)\n            else:\n                buy_price.append(np.nan)\n                sell_price.append(np.nan)\n                adx_signal.append(0)\n        elif adx[i-1] &lt; 25 and adx[i] &gt; 25 and ndi[i] &gt; pdi[i]:\n            if signal != -1:\n                buy_price.append(np.nan)\n                sell_price.append(prices[i])\n                signal = -1\n                adx_signal.append(signal)\n            else:\n                buy_price.append(np.nan)\n                sell_price.append(np.nan)\n                adx_signal.append(0)\n        else:\n            buy_price.append(np.nan)\n            sell_price.append(np.nan)\n            adx_signal.append(0)\n            \n    return buy_price, sell_price, adx_signal\n\nbuy_price, sell_price, adx_signal = implement_adx_strategy(aapl['close'], aapl['plus_di'], aapl['minus_di'], aapl['adx'])<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Code Explanation:<\/strong> First, we are defining a function named \u2018implement_adx_strategy\u2019 which takes the stock prices (\u2018prices), and the components of ADX (\u2018pdi\u2019, \u2018ndi\u2019, \u2018adx\u2019) as parameters.<\/p>\n\n\n\n<p>Inside the function, we are creating three empty lists (buy_price, sell_price, and adx_signal) in which the values will be appended while creating the trading strategy.<\/p>\n\n\n\n<p>After that, we are implementing the trading strategy through a for-loop. Inside the for-loop, we are passing certain conditions, and if the conditions are satisfied, the respective values will be appended to the empty lists. If the condition to buy the stock gets satisfied, the buying price will be appended to the \u2018buy_price\u2019 list, and the signal value will be appended as 1 representing to buy the stock. Similarly, if the condition to sell the stock gets satisfied, the selling price will be appended to the \u2018sell_price\u2019 list, and the signal value will be appended as -1 representing to sell the stock.<\/p>\n\n\n\n<p>Finally, we are returning the lists appended with values. Then, we are calling the created function and stored the values into their respective variables. The list doesn\u2019t make any sense unless we plot the values. So, let\u2019s plot the values of the created trading lists.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-7: Plotting the trading&nbsp;signals<\/h3>\n\n\n\n<p>In this step, we are going to plot the created trading lists to make sense out of them.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)\nax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)\nax1.plot(aapl['close'], linewidth = 3, color = '#ff9800', alpha = 0.6)\nax1.set_title('AAPL CLOSING PRICE')\nax1.plot(aapl.index, buy_price, marker = '^', color = '#26a69a', markersize = 14, linewidth = 0, label = 'BUY SIGNAL')\nax1.plot(aapl.index, sell_price, marker = 'v', color = '#f44336', markersize = 14, linewidth = 0, label = 'SELL SIGNAL')\nax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)\nax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)\nax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)\nax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')\nax2.legend()\nax2.set_title('AAPL ADX 14')\nplt.show()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1801\" height=\"884\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image-4.png\" alt=\"\" class=\"wp-image-2589\"\/><\/figure>\n\n\n\n<p><strong>Code Explanation:<\/strong> We are plotting the Average Directional Index components along with the buy and sell signals generated by the trading strategy. We can observe that whenever the ADX line crosses from below to above 25 and the + DI line is above the &#8211; DI line, a green-colored buy signal is plotted in the chart. Similarly, whenever the ADX line crosses from below to above 25 and the + DI line is below the &#8211; DI line, a red-colored sell signal is plotted in the chart.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-8: Creating our&nbsp;Position<\/h3>\n\n\n\n<p>In this step, we are going to create a list that indicates 1 if we hold the stock or 0 if we don\u2019t own or hold the stock.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">position = []\nfor i in range(len(adx_signal)):\n    if adx_signal[i] &gt; 1:\n        position.append(0)\n    else:\n        position.append(1)\n        \nfor i in range(len(aapl['close'])):\n    if adx_signal[i] == 1:\n        position[i] = 1\n    elif adx_signal[i] == -1:\n        position[i] = 0\n    else:\n        position[i] = position[i-1]\n        \nclose_price = aapl['close']\nplus_di = aapl['plus_di']\nminus_di = aapl['minus_di']\nadx = aapl['adx']\nadx_signal = pd.DataFrame(adx_signal).rename(columns = {0:'adx_signal'}).set_index(aapl.index)\nposition = pd.DataFrame(position).rename(columns = {0:'adx_position'}).set_index(aapl.index)\n\nframes = [close_price, plus_di, minus_di, adx, adx_signal, position]\nstrategy = pd.concat(frames, join = 'inner', axis = 1)\n\nstrategy<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*SeKGBnJtF_rHEUmpGN8_3A.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><strong>Code Explanation:<\/strong> First, we are creating an empty list named \u2018position\u2019. We are passing two for-loops, one is to generate values for the \u2018position\u2019 list to just match the length of the \u2018signal\u2019 list. The other for-loop is the one we are using to generate actual position values. Inside the second for-loop, we are iterating over the values of the \u2018signal\u2019 list, and the values of the \u2018position\u2019 list get appended concerning which condition gets satisfied. The value of the position remains 1 if we hold the stock or remains 0 if we sold or don\u2019t own the stock. Finally, we are doing some data manipulations to combine all the created lists into one dataframe.<\/p>\n\n\n\n<p>From the output being shown, we can see that in the first row our position in the stock has remained 1 (since there isn\u2019t any change in the ADX signal) but our position suddenly turned to -1 as we sold the stock when the ADX trading signal represents a sell signal (-1). Our position will remain 0 until some changes in the trading signal occur. Now it\u2019s time to do implement some backtesting process!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-9: Backtesting<\/h3>\n\n\n\n<p>Before moving on, it is essential to know what backtesting is. Backtesting is the process of seeing how well our trading strategy has performed on the given stock data. In our case, we are going to implement a backtesting process for our Average Directional Index trading strategy over the Apple stock data.<\/p>\n\n\n\n<p><strong>Python Implementation:<\/strong><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">aapl_ret = pd.DataFrame(np.diff(aapl['close'])).rename(columns = {0:'returns'})\nadx_strategy_ret = []\n\nfor i in range(len(aapl_ret)):\n    returns = aapl_ret['returns'][i]*strategy['adx_position'][i]\n    adx_strategy_ret.append(returns)\n    \nadx_strategy_ret_df = pd.DataFrame(adx_strategy_ret).rename(columns = {0:'adx_returns'})\ninvestment_value = 100000\nadx_investment_ret = []\n\nfor i in range(len(adx_strategy_ret_df['adx_returns'])):\n    number_of_stocks = floor(investment_value\/aapl['close'][i])\n    returns = number_of_stocks*adx_strategy_ret_df['adx_returns'][i]\n    adx_investment_ret.append(returns)\n\nadx_investment_ret_df = pd.DataFrame(adx_investment_ret).rename(columns = {0:'investment_returns'})\ntotal_investment_ret = round(sum(adx_investment_ret_df['investment_returns']), 2)\nprofit_percentage = floor((total_investment_ret\/investment_value)*100)\nprint(cl('Profit gained from the ADX strategy by investing $100k in AAPL : {}'.format(total_investment_ret), attrs = ['bold']))\nprint(cl('Profit percentage of the ADX strategy : {}%'.format(profit_percentage), attrs = ['bold']))<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<p class=\"has-background\" style=\"background-color:#abb7c217\"><code><strong>Profit gained from the ADX strategy by investing $100k in AAPL : <strong>54719.46<\/strong><\/strong><br><strong>Profit percentage of the ADX strategy : 54%<\/strong><\/code><\/p>\n\n\n\n<p><strong>Code Explanation:<\/strong> First, we are calculating the returns of the Apple stock using the \u2018diff\u2019 function provided by the NumPy package and we have stored it as a dataframe into the \u2018aapl_ret\u2019 variable. Next, we are passing a for-loop to iterate over the values of the \u2018aapl_ret\u2019 variable to calculate the returns we gained from our ADX trading strategy, and these returns values are appended to the \u2018adx_strategy_ret\u2019 list. Next, we are converting the \u2018adx_strategy_ret\u2019 list into a dataframe and stored it into the \u2018adx_strategy_ret_df\u2019 variable.<\/p>\n\n\n\n<p>Next comes the backtesting process. We are going to backtest our strategy by investing a hundred thousand USD into our trading strategy. So first, we are storing the amount of investment into the \u2018investment_value\u2019 variable. After that, we are calculating the number of Apple stocks we can buy using the investment amount. You can notice that I\u2019ve used the \u2018floor\u2019 function provided by the Math package because, while dividing the investment amount by the closing price of Apple stock, it spits out an output with decimal numbers. The number of stocks should be an integer but not a decimal number. Using the \u2018floor\u2019 function, we can cut out the decimals. Remember that the \u2018floor\u2019 function is way more complex than the \u2018round\u2019 function. Then, we are passing a for-loop to find the investment returns followed by some data manipulation tasks.<\/p>\n\n\n\n<p>Finally, we are printing the total return we got by investing a hundred thousand into our trading strategy and it is revealed that we have made an approximate profit of fifty-four thousand USD in three years. That\u2019s not bad! Now, let\u2019s compare our returns with SPY ETF (an ETF designed to track the S&amp;P 500 stock market index) returns.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step-10: SPY ETF Comparison<\/h3>\n\n\n\n<p>This step is optional but it is highly recommended as we can get an idea of how well our trading strategy performs against a benchmark (SPY ETF). In this step, we are going to extract the data of the SPY ETF using the \u2018get_historical_data\u2019 function we created and compare the returns we get from the SPY ETF with our Average Directional Index strategy returns on Apple.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">def get_benchmark(start_date, investment_value):\n    spy = get_historical_data('SPY', start_date)['close']\n    benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})\n    \n    investment_value = investment_value\n    benchmark_investment_ret = []\n    \n    for i in range(len(benchmark['benchmark_returns'])):\n        number_of_stocks = floor(investment_value\/spy[i])\n        returns = number_of_stocks*benchmark['benchmark_returns'][i]\n        benchmark_investment_ret.append(returns)\n\n    benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})\n    return benchmark_investment_ret_df\n\nbenchmark = get_benchmark('2020-01-01', 100000)\n\ninvestment_value = 100000\ntotal_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)\nbenchmark_profit_percentage = floor((total_benchmark_investment_ret\/investment_value)*100)\nprint(cl('Benchmark profit by investing $100k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))\nprint(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))\nprint(cl('ADX Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p id=\"a4dd\"><strong>Output:<\/strong><\/p>\n\n\n\n<p class=\"has-background\" id=\"a4dd\" style=\"background-color:#abb7c217\"><code><strong>Benchmark profit by investing $100k : <strong>37538.96<\/strong><\/strong><br><strong>Benchmark Profit percentage : 37%<\/strong><br><strong>ADX Strategy profit is 17% higher than the Benchmark Profit<\/strong><\/code><\/p>\n\n\n\n<p id=\"7944\"><strong>Code Explanation:<\/strong>&nbsp;The code used in this step is almost similar to the one used in the previous backtesting step but, instead of investing in Apple, we are investing in SPY ETF by not implementing any trading strategies. From the output, we can see that our Average Directional Index trading strategy has outperformed the SPY ETF by 17%. That\u2019s good!<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3a56\">Final Thoughts!<\/h2>\n\n\n\n<p id=\"f627\">After a long process of crushing both theory and coding parts, we have successfully learned what the Average Directional Index is all about and how a simple ADX-based trading strategy can be implemented in Python.<\/p>\n\n\n\n<p id=\"b96b\">From my perspective, the full power of ADX is unleashed when it is accompanied by another technical indicator, especially with RSI to get quality entry and exit points for your trades. So, it is highly recommended to try improvising this article by tuning the ADX strategy accompanied by other technical indicators and backtesting it as many as possible. Doing this might help in achieving better results in the real-world market. That\u2019s it! Hope you learned something useful from this article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are four different branches of technical indicators out there but the most popular ones are known as trend indicators. These indicators help traders in identifying the direction and strength of the market trend and trade along with them. In most cases, the indicators that come under the category of trend reveal good results unless [&hellip;]<\/p>\n","protected":false},"author":18,"featured_media":2471,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[65,42],"tags":[],"coding-language":[30],"ready-to-go-solution":[56],"qualification":[31],"financial-apis-category":[36],"financial-apis-manuals":[39],"class_list":["post-2470","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backtesting-strategies-examples","category-stocks-data-analysis-examples","coding-language-python","ready-to-go-solution-eodhd-python-financial-library","qualification-experienced","financial-apis-category-stock-market-prices","financial-apis-manuals-end-of-day","has_thumb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.9 (Yoast SEO v26.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Algorithmic Trading with Average Directional Index in Python<\/title>\n<meta name=\"description\" content=\"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Algorithmic Trading with Average Directional Index in Python\" \/>\n<meta property=\"og:description\" content=\"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\" \/>\n<meta property=\"og:site_name\" content=\"Financial Academy\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/eodhistoricaldata\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-24T17:58:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-05T11:59:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"828\" \/>\n\t<meta property=\"og:image:height\" content=\"552\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Nikhil Adithyan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:site\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nikhil Adithyan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#article\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\"},\"author\":{\"name\":\"Nikhil Adithyan\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402\"},\"headline\":\"Algorithmic Trading with Average Directional Index in Python\",\"datePublished\":\"2023-10-24T17:58:57+00:00\",\"dateModified\":\"2025-02-05T11:59:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\"},\"wordCount\":3456,\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png\",\"articleSection\":[\"Backtesting Strategies Examples\",\"Stocks Data Analysis Examples\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\",\"name\":\"Algorithmic Trading with Average Directional Index in Python\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png\",\"datePublished\":\"2023-10-24T17:58:57+00:00\",\"dateModified\":\"2025-02-05T11:59:16+00:00\",\"description\":\"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.\",\"breadcrumb\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png\",\"width\":828,\"height\":552},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/eodhd.com\/financial-academy\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Algorithmic Trading with Average Directional Index in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"name\":\"Financial APIs Academy | EODHD\",\"description\":\"Financial Stock Market Academy\",\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\",\"name\":\"EODHD (EOD Historical Data)\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"width\":159,\"height\":82,\"caption\":\"EODHD (EOD Historical Data)\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/eodhistoricaldata\",\"https:\/\/x.com\/EOD_data\",\"https:\/\/www.reddit.com\/r\/EODHistoricalData\/\",\"https:\/\/eod-historical-data.medium.com\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402\",\"name\":\"Nikhil Adithyan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/eb53ce41bde412555cee22b8b4c09c2ff51625fff05ba3696b20cac7a7c0d938?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/eb53ce41bde412555cee22b8b4c09c2ff51625fff05ba3696b20cac7a7c0d938?s=96&d=mm&r=g\",\"caption\":\"Nikhil Adithyan\"},\"description\":\"Founder at BacktestZone | Streamlit Student Ambassador | FinTech &amp; Quantitative Finance enthusiast\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/author\/nikhiladithyan\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Algorithmic Trading with Average Directional Index in Python","description":"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python","og_locale":"en_US","og_type":"article","og_title":"Algorithmic Trading with Average Directional Index in Python","og_description":"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.","og_url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python","og_site_name":"Financial Academy","article_publisher":"https:\/\/www.facebook.com\/eodhistoricaldata","article_published_time":"2023-10-24T17:58:57+00:00","article_modified_time":"2025-02-05T11:59:16+00:00","og_image":[{"width":828,"height":552,"url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","type":"image\/png"}],"author":"Nikhil Adithyan","twitter_card":"summary_large_image","twitter_creator":"@EOD_data","twitter_site":"@EOD_data","twitter_misc":{"Written by":"Nikhil Adithyan","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#article","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python"},"author":{"name":"Nikhil Adithyan","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402"},"headline":"Algorithmic Trading with Average Directional Index in Python","datePublished":"2023-10-24T17:58:57+00:00","dateModified":"2025-02-05T11:59:16+00:00","mainEntityOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python"},"wordCount":3456,"publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","articleSection":["Backtesting Strategies Examples","Stocks Data Analysis Examples"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python","url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python","name":"Algorithmic Trading with Average Directional Index in Python","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/#website"},"primaryImageOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","datePublished":"2023-10-24T17:58:57+00:00","dateModified":"2025-02-05T11:59:16+00:00","description":"Learn about the Average Directional Index (ADX) and how it can help traders identify market trends and build effective trading strategies in Python.","breadcrumb":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#primaryimage","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","width":828,"height":552},{"@type":"BreadcrumbList","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/algorithmic-trading-with-average-directional-index-in-python#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/eodhd.com\/financial-academy\/"},{"@type":"ListItem","position":2,"name":"Algorithmic Trading with Average Directional Index in Python"}]},{"@type":"WebSite","@id":"https:\/\/eodhd.com\/financial-academy\/#website","url":"https:\/\/eodhd.com\/financial-academy\/","name":"Financial APIs Academy | EODHD","description":"Financial Stock Market Academy","publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/eodhd.com\/financial-academy\/#organization","name":"EODHD (EOD Historical Data)","url":"https:\/\/eodhd.com\/financial-academy\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","width":159,"height":82,"caption":"EODHD (EOD Historical Data)"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/eodhistoricaldata","https:\/\/x.com\/EOD_data","https:\/\/www.reddit.com\/r\/EODHistoricalData\/","https:\/\/eod-historical-data.medium.com\/"]},{"@type":"Person","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402","name":"Nikhil Adithyan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/eb53ce41bde412555cee22b8b4c09c2ff51625fff05ba3696b20cac7a7c0d938?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eb53ce41bde412555cee22b8b4c09c2ff51625fff05ba3696b20cac7a7c0d938?s=96&d=mm&r=g","caption":"Nikhil Adithyan"},"description":"Founder at BacktestZone | Streamlit Student Ambassador | FinTech &amp; Quantitative Finance enthusiast","url":"https:\/\/eodhd.com\/financial-academy\/author\/nikhiladithyan"}]}},"jetpack_featured_media_url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/image.png","jetpack_shortlink":"https:\/\/wp.me\/pdOdVT-DQ","jetpack_sharing_enabled":true,"acf":[],"_links":{"self":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/comments?post=2470"}],"version-history":[{"count":13,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2470\/revisions"}],"predecessor-version":[{"id":6240,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2470\/revisions\/6240"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media\/2471"}],"wp:attachment":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media?parent=2470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/categories?post=2470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/tags?post=2470"},{"taxonomy":"coding-language","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/coding-language?post=2470"},{"taxonomy":"ready-to-go-solution","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/ready-to-go-solution?post=2470"},{"taxonomy":"qualification","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/qualification?post=2470"},{"taxonomy":"financial-apis-category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-category?post=2470"},{"taxonomy":"financial-apis-manuals","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-manuals?post=2470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}