{"id":4545,"date":"2024-01-15T09:30:49","date_gmt":"2024-01-15T09:30:49","guid":{"rendered":"https:\/\/eodhd.com\/financial-academy\/?p=4545"},"modified":"2025-02-05T12:52:40","modified_gmt":"2025-02-05T12:52:40","slug":"backtesting-a-killer-mean-reversion-trading-strategy-with-python","status":"publish","type":"post","link":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python","title":{"rendered":"Backtesting a Killer Mean Reversion Trading Strategy with Python"},"content":{"rendered":"\n<p>There is an ocean of strategies existing in the algo trading space, but what&#8217;s tough is filtering and choosing the most reliable and profitable ones out of them. In this article, we are going to build one such strategy (a mean-reversion strategy to be specific) that ticks all the boxes of a &#8220;good strategy&#8221; and backtest it on Python to analyze its results and profitability. We&#8217;ll be using <a href=\"https:\/\/eodhd.com\/financial-apis\/us-stock-market-tick-data-api\/\" target=\"_blank\" rel=\"noreferrer noopener\">EODHD&#8217;s stock tick data API<\/a> accessed via the EODHD python package for effective backtesting. So without further ado, let&#8217;s dive into the article!<\/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\"><strong>The <strong>Backtesting a Mean-Reversion Strategy<\/strong> Description<\/strong><\/h2>\n\n\n\n<p>Before moving on to the coding part, it&#8217;s essential to have a good background about the strategy we are going to build today. The strategy is a mean-reversion trading strategy which means it&#8217;s a strategy that relies on the idea that the stock price will return to its average or normal price after a certain point (usually an extreme price movement). <\/p>\n\n\n\n<p>One of the best indicators used for analyzing mean reversions is the Relative Strength Index (RSI) indicator. We&#8217;ll be incorporating this indicator along with SMA to create our own custom mean-reversion trading strategy.<\/p>\n\n\n\n<p>We enter the market if: the RSI 10 is lower than 30 and the market is greater than the SMA 200<\/p>\n\n\n\n<p>We exit the market if: the RSI 10 is greater than 70 and the market is below the SMA 200<\/p>\n\n\n\n<p>Though our strategy is barely complex and lies more on the simplistic side, it&#8217;s still a highly effective trading strategy. Now, let&#8217;s move on to the coding part to see if our strategy proves this point.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1\/6:<\/strong> <strong>Importing Packages<\/strong><\/h3>\n\n\n\n<p>The first and foremost step in this process of creating a mean-reversion trading strategy is 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, and Pandas TA-Lib for calculating technical indicators. The secondary packages are going to be Math for mathematical functions, Datetime for working with dates, and Termcolor for font customization (optional).<\/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 pandas as pd\nfrom eodhd import APIClient\nimport pandas_ta as ta\nfrom datetime import datetime\nfrom termcolor import colored as cl\nimport math <\/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 Tesla using EODHD&#8217;s eodhd Python library. Also, if you haven\u2019t installed any of the imported packages, make sure to do so using the&nbsp;pip&nbsp;command in your terminal.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"a9f4\"><strong>Step 2\/6:<\/strong> <strong>API Key Activation<\/strong><\/h3>\n\n\n\n<p id=\"c710\">The second step in this process of creating a mean-reversion trading strategy is API key activation. 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 ACTIVATION\n\napi_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;api_key&nbsp;and then in the second line, we are using the&nbsp;APIClient&nbsp;class provided by the&nbsp;eodhd&nbsp;package to activate the API key and stored the response in the&nbsp;client&nbsp;variable.<\/p>\n\n\n\n<p id=\"4634\">Note that you need to replace&nbsp;&lt;YOUR API KEY&gt;&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\"><strong>Step 3\/6:<\/strong> <strong>Extracting Historical Data<\/strong><\/h3>\n\n\n\n<p>The third step in this process of creating a mean-reversion trading strategy is extracting the stock data. In this article, we&#8217;ll be utilizing the EODHD Stock Tick API which provides granular tick data for all US equities spanning across all exchanges. It includes current and delisted companies, encompassing approximately&nbsp;80,000 tickers,&nbsp;and 16,000+ securities&nbsp;are&nbsp;updated daily. The total data size is approximately&nbsp;10 terabytes. The dataset begins from&nbsp;January 1st, 2008, and is updated until the current date. The following code extracts the tick data of Apple via the eodhd package:<\/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 has-link-color wp-elements-299ef09e9c1fcc378d1510659affe7a1\"><code lang=\"python\" class=\"language-python\"># EXTRACTING HISTORICAL DATA\n\nhist_json = client.get_stock_market_tick_data(from_timestamp = '1694354400', to_timestamp = '1694455200', symbol = 'AAPL')\ndf = pd.DataFrame(hist_json)\n\ndf.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>The above code uses the get_stock_market_tick_data function provided by the eodhd package to extract the tick data of Apple. The function contains three parameters: from_timestamp &#8211; the starting date of the data in UNIX format, to_timestamp &#8211; the ending date of the data in UNIX format, and symbol &#8211; the ticker of the stock. Here, we are extracting the data from September 10 14.00 to September 11 18.00 and this is the output of the code:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1217\" height=\"355\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/AAPL_stock_tick_data.png\" alt=\"\" class=\"wp-image-4575\"\/><\/figure>\n\n\n\n<p>The data contains five columns: ex &#8211; the exchange the stock is listed in (Q denotes NASDAQ), mkt &#8211; the market where the trade took place, price &#8211; the stock price during that transaction, seq &#8211; trade sequence number, shares &#8211; the number of shares in the transaction, sl &#8211; sales condition, sub_mkt &#8211; the sub-market where the trade took place, and ts &#8211; timestamp.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 4\/6:<\/strong> <strong>Data Wrangling<\/strong><\/h3>\n\n\n\n<p>The fourth step in this process of creating a mean-reversion trading strategy is data wrangling. Data wrangling is the process of processing and manipulating the data to make it even more accessible and usable. Let&#8217;s start off by removing the unwanted columns in our dataframe. Apart from the timestamp and stock price, we won&#8217;t be requiring any other columns. So let&#8217;s remove them.<\/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 has-link-color wp-elements-a4bd3784853d32822cbd8163f3b2aec1\"><code lang=\"python\" class=\"language-python\">aapl_df = df[['price', 'ts']]\n<\/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>Next, it can be noticed that the timestamp column is in UNIX format which is usually tough to work with. So let&#8217;s change it to the standard date and time format:<\/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 has-link-color wp-elements-fe32ba453ef712540e1a12464ceb1614\"><code lang=\"python\" class=\"language-python\">aapl_df.ts = aapl_df.ts.apply(lambda x: x\/1000)\naapl_df.ts = aapl_df.ts.apply(lambda x: datetime.utcfromtimestamp(x))<\/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>I&#8217;m not going to dive deep into this code but the outline is we&#8217;re using apply and lambda functions to perform some data manipulations, and on top of that, we are using the datetime package for the conversion. Here&#8217;s the final processed dataframe:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"777\" height=\"421\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Processed_AAPL_stock_tick_data.png\" alt=\"\" class=\"wp-image-4577\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 5\/6:<\/strong> <strong>RSI &amp; SMA Calculation<\/strong><\/h3>\n\n\n\n<p>The fifth step in this process of creating a mean-reversion trading strategy is calculating the technical indicators. In this step, we are going to calculate the necessary indicators to build our trading strategy. We can write the code from scratch to calculate the indicators but it&#8217;s a time-intensive process. So we are going to use the Pandas TA-Lib package which automatically calculates the indicators for the given data. The following code calculates the RSI and SMA of Apple stock:<\/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 has-link-color wp-elements-7b7bfd6f3293c9155d9b51508a1cf2bc\"><code lang=\"python\" class=\"language-python\"># RSI &amp; SMA CALCULATION\n\naapl_df['sma200'] = ta.sma(aapl_df.price, length = 200)\naapl_df['rsi10'] = ta.rsi(aapl_df.price, length = 10)\naapl_df = aapl_df.dropna().reset_index().drop('index', axis = 1)\n\naapl_df.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>As per the trading strategy we discussed earlier in this article, we are calculating the Relative Strength Index with the lookback period as 10 and the SMA as 200. This is the output of the above code:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1413\" height=\"480\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/AAPL_rsi_sma_df.png\" alt=\"\" class=\"wp-image-4581\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 6\/6:<\/strong> <strong>Backtesting the Mean-Reversion Trading Strategy<\/strong> in Python<\/h3>\n\n\n\n<p>The sixth and final step in this process of creating a mean-reversion trading strategy is backtesting the strategy. This is the most exciting part of the article where we are going to see if our trading strategy actually works or not. The following code implements our mean-reversion trading strategy and backtests it on the Apple stock tick data we extracted:<\/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 has-link-color wp-elements-a42bc60851cfcb9aa9cf1775fc9dc42a\"><code lang=\"python\" class=\"language-python\"># CREATING &amp; BACKTESTING THE STRATEGY\n\ndef implement_strategy(aapl_df, investment):\n    \n    in_position = False\n    equity = investment\n    \n    for i in range(3, len(aapl_df)):\n        if aapl_df['rsi10'][i] &lt; 30 and aapl_df['price'][i] &gt; aapl_df['sma200'][i] and in_position == False:\n            no_of_shares = math.floor(equity\/aapl_df.price[i])\n            equity -= (no_of_shares * aapl_df.price[i])\n            in_position = True\n            print(cl('BUY: ', color = 'green', attrs = ['bold']), f'{no_of_shares} Shares are bought at ${aapl_df.price[i]} on {aapl_df.ts[i]}')\n        elif aapl_df['rsi10'][i] &gt; 70 and aapl_df['price'][i] &lt; aapl_df['sma200'][i] and in_position == True:\n            equity += (no_of_shares * aapl_df.price[i])\n            in_position = False\n            print(cl('SELL: ', color = 'red', attrs = ['bold']), f'{no_of_shares} Shares are bought at ${aapl_df.price[i]} on {aapl_df.ts[i]}')\n    if in_position == True:\n        equity += (no_of_shares * aapl_df.price[i])\n        print(cl(f'\\nClosing position at {aapl_df.price[i]} on {aapl_df.ts[i]}', attrs = ['bold']))\n        in_position = False\n\n    earning = round(equity - investment, 2)\n    roi = round(earning \/ investment * 100, 2)\n    print('')\n    print(cl(f'EARNING: ${earning} ; ROI: {roi}%', attrs = ['bold']))\n    \nimplement_strategy(aapl_df, 100000)<\/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>This code is heavily inspired by the backtesting code written by&nbsp;<a href=\"https:\/\/medium.com\/u\/1a7b4287ab33?source=post_page-----6930bb344856--------------------------------\" target=\"_blank\" rel=\"noreferrer noopener\">Yong Hong Tan<\/a>&nbsp;in his article about the SuperTrend indicator. A shoutout to him for this amazing code. The backtesting results are pretty interesting. The strategy generated tons and tons of trades, even within a millisecond time interval between the trades. This can be an indication that our strategy might be generating false signals. But leaving that aside, here&#8217;s the result of the backtesting process:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"826\" height=\"87\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Breakout_strategy_backtesting_result.png\" alt=\"\" class=\"wp-image-4582\"\/><\/figure>\n\n\n\n<p>It looks like our strategy managed to attain a positive ROI of 3.39% in a day which is not bad at all. This is great news.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>In this article, we learned to construct a very simple yet effective mean-reversion trading strategy. We backtested the strategy on Apple&#8217;s stock tick data extracted using <a href=\"https:\/\/eodhd.com\/financial-apis\/us-stock-market-tick-data-api\/\" target=\"_blank\" rel=\"noreferrer noopener\">EODHD&#8217;s stock tick data API<\/a>.<\/p>\n\n\n\n<p>Though we went through an extensive process of coding, there is still a lot of scope for improvements. For example, as we discussed before, the strategy generated a lot of false trading signals which can be very dangerous in the real world. So we need to fine-tune the strategy parameters and maybe tweak some logic before deploying it into the real-world. To make the backtesting results more reliable, transaction costs can be mounted for each trade the program executes. Then, several risk management approaches can be deployed to ensure a safe method of trading. These are some ways to improve the overall framework and there are many more to be explored.<\/p>\n\n\n\n<p>With that said, you&#8217;ve reached the end of the article. Hope you learned something new and useful today. Thank you very much for your time. Happy backtesting!<\/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","protected":false},"excerpt":{"rendered":"<p>A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and APIs<\/p>\n","protected":false},"author":18,"featured_media":4564,"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,1,59,61],"tags":[],"coding-language":[30],"ready-to-go-solution":[56],"qualification":[31,32],"financial-apis-category":[36],"financial-apis-manuals":[74],"class_list":["post-4545","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backtesting-strategies-examples","category-fundamental-analysis-examples","category-technical-analysis-examples","category-trading-indicators-implimentations","coding-language-python","ready-to-go-solution-eodhd-python-financial-library","qualification-experienced","qualification-guru","financial-apis-category-stock-market-prices","financial-apis-manuals-ticks","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>Backtesting a Killer Mean Reversion Trading Strategy with Python | EODHD APIs Academy<\/title>\n<meta name=\"description\" content=\"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs\" \/>\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\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Backtesting a Killer Mean Reversion Trading Strategy with Python\" \/>\n<meta property=\"og:description\" content=\"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs\" \/>\n<meta property=\"og:url\" content=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-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=\"2024-01-15T09:30:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-05T12:52:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1\" \/>\n\t<meta property=\"og:image:height\" content=\"1\" \/>\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=\"8 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\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#article\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\"},\"author\":{\"name\":\"Nikhil Adithyan\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402\"},\"headline\":\"Backtesting a Killer Mean Reversion Trading Strategy with Python\",\"datePublished\":\"2024-01-15T09:30:49+00:00\",\"dateModified\":\"2025-02-05T12:52:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\"},\"wordCount\":1485,\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png\",\"articleSection\":[\"Backtesting Strategies Examples\",\"Fundamental Analysis Examples\",\"Technical Analysis Examples\",\"Trading Indicators Implimentations\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\",\"name\":\"Backtesting a Killer Mean Reversion Trading Strategy with Python | EODHD APIs Academy\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png\",\"datePublished\":\"2024-01-15T09:30:49+00:00\",\"dateModified\":\"2025-02-05T12:52:40+00:00\",\"description\":\"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs\",\"breadcrumb\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png\",\"caption\":\"Backtesting a Killer Mean Reversion Trading Strategy with Python\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/eodhd.com\/financial-academy\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backtesting a Killer Mean Reversion Trading Strategy with 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":"Backtesting a Killer Mean Reversion Trading Strategy with Python | EODHD APIs Academy","description":"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs","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\/backtesting-a-killer-mean-reversion-trading-strategy-with-python","og_locale":"en_US","og_type":"article","og_title":"Backtesting a Killer Mean Reversion Trading Strategy with Python","og_description":"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs","og_url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python","og_site_name":"Financial Academy","article_publisher":"https:\/\/www.facebook.com\/eodhistoricaldata","article_published_time":"2024-01-15T09:30:49+00:00","article_modified_time":"2025-02-05T12:52:40+00:00","og_image":[{"url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","width":1,"height":1,"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":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#article","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python"},"author":{"name":"Nikhil Adithyan","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/67681e71050cf7d8d0efb91fee5f0402"},"headline":"Backtesting a Killer Mean Reversion Trading Strategy with Python","datePublished":"2024-01-15T09:30:49+00:00","dateModified":"2025-02-05T12:52:40+00:00","mainEntityOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python"},"wordCount":1485,"publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","articleSection":["Backtesting Strategies Examples","Fundamental Analysis Examples","Technical Analysis Examples","Trading Indicators Implimentations"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python","url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python","name":"Backtesting a Killer Mean Reversion Trading Strategy with Python | EODHD APIs Academy","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/#website"},"primaryImageOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","datePublished":"2024-01-15T09:30:49+00:00","dateModified":"2025-02-05T12:52:40+00:00","description":"A comprehensive process of backtesting a mean-reversion trading strategy with the help of Python and EODHD APIs","breadcrumb":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#primaryimage","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","caption":"Backtesting a Killer Mean Reversion Trading Strategy with Python"},{"@type":"BreadcrumbList","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/backtesting-a-killer-mean-reversion-trading-strategy-with-python#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/eodhd.com\/financial-academy\/"},{"@type":"ListItem","position":2,"name":"Backtesting a Killer Mean Reversion Trading Strategy with 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\/2024\/01\/Backtesting_a_Killer_Mean_Reversion_Trading_Strategy_with_Python.png","jetpack_shortlink":"https:\/\/wp.me\/pdOdVT-1bj","jetpack_sharing_enabled":true,"acf":[],"_links":{"self":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/4545","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=4545"}],"version-history":[{"count":7,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/4545\/revisions"}],"predecessor-version":[{"id":6270,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/4545\/revisions\/6270"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media\/4564"}],"wp:attachment":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media?parent=4545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/categories?post=4545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/tags?post=4545"},{"taxonomy":"coding-language","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/coding-language?post=4545"},{"taxonomy":"ready-to-go-solution","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/ready-to-go-solution?post=4545"},{"taxonomy":"qualification","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/qualification?post=4545"},{"taxonomy":"financial-apis-category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-category?post=4545"},{"taxonomy":"financial-apis-manuals","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-manuals?post=4545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}