{"id":131257,"date":"2023-01-17T20:20:33","date_gmt":"2023-01-17T20:20:33","guid":{"rendered":"https:\/\/blog.finxter.com\/?p=1065786"},"modified":"2023-01-17T20:20:33","modified_gmt":"2023-01-17T20:20:33","slug":"bitcoin-trading-moving-averages-or-hodl-a-python-script-uncovers-the-answer","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2023\/01\/17\/bitcoin-trading-moving-averages-or-hodl-a-python-script-uncovers-the-answer\/","title":{"rendered":"Bitcoin \u2013 Trading Moving Averages or HODL? A Python Script Uncovers the Answer!"},"content":{"rendered":"\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-top\" data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;1065786&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;top&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;1&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Rate this post&quot;,&quot;legend&quot;:&quot;5\\\/5 - (1 vote)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;width&quot;:&quot;142.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n<div class=\"kksr-stars\">\n<div class=\"kksr-stars-inactive\">\n<div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"kksr-stars-active\" style=\"width: 142.5px;\">\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\"> 5\/5 &#8211; (1 vote) <\/div>\n<\/p><\/div>\n<p>I&#8217;ve always wondered if a slow and high-level trading strategy focusing on long-term trends could outperform a buy-and-hold strategy.<\/p>\n<p>To answer this question, I created a Python script that would utilize a momentum-based strategy to tell me when to buy and when to sell Bitcoin. <\/p>\n<p>Despite my busy life and doubts that day trading would be a successful venture, I was eager to find out if this simple program could beat the market. I can run the Python code daily to decide whether to buy or sell BTC. <\/p>\n<p class=\"has-base-background-color has-background\"><strong>What would have happened if I had used the following strategy between the turbulent years 2020 and 2022 in Bitcoin?<\/strong> Read on to find out! <img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/14.0.0\/72x72\/1f447.png\" alt=\"\ud83d\udc47\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n<h2>General Idea<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"495\" height=\"881\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-165.png\" alt=\"\" class=\"wp-image-1066579\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-165.png 495w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-165-169x300.png 169w\" sizes=\"auto, (max-width: 495px) 100vw, 495px\" \/><\/figure>\n<\/div>\n<p>The idea of this algorithm is to allow traders to automate their Bitcoin trading decisions using two moving averages. <\/p>\n<p class=\"has-base-background-color has-background\"><img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/14.0.0\/72x72\/1f449.png\" alt=\"\ud83d\udc49\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/> <strong>Finxter Academy<\/strong>: <a href=\"https:\/\/academy.finxter.com\/course\/setting-up-binance-and-development-environment-3\/\" data-type=\"URL\" data-id=\"https:\/\/academy.finxter.com\/course\/setting-up-binance-and-development-environment-3\/\" target=\"_blank\" rel=\"noreferrer noopener\">Complete Python Trading Course (Binance) &#8212; Simple Moving Average<\/a><\/p>\n<p>The algorithm will enter buy positions when the shorter-term moving average (<code>MA1<\/code>) is higher than the longer-term moving average (<code>MA2<\/code>) indicating a positive momentum of the Bitcoin price, and enter sell positions when the shorter-term moving average is lower than the longer-term moving average indicating a negative momentum of the Bitcoin price. <\/p>\n<p>When the moving averages cross, the algorithm will close any existing positions and reverse the trading direction.<\/p>\n<h2>Algorithm Steps<\/h2>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-166-1024x683.png\" alt=\"\" class=\"wp-image-1066580\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-166-1024x683.png 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-166-300x200.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-166-768x512.png 768w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-166.png 1113w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<p>My strategy follows these simple steps:<\/p>\n<ol>\n<li>Initialize two moving averages, <code>MA1<\/code> and <code>MA2<\/code>, with different lookback periods.<\/li>\n<li>Calculate the current value of each moving average.<\/li>\n<li>If <code>MA1 > MA2<\/code>, enter a buy position in the Bitcoin market.<\/li>\n<li>If <code>MA1 &lt; MA2<\/code>, enter a sell position in the Bitcoin market.<\/li>\n<li>Monitor the market for any changes in the moving averages.<\/li>\n<li>When the moving averages cross, close any existing positions and reverse the trading direction (buy if previously selling, sell if previously buying).<\/li>\n<li>Repeat steps 2 to 6.<\/li>\n<\/ol>\n<h2>Python Program to Automate It<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"684\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-167-1024x684.png\" alt=\"\" class=\"wp-image-1066593\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-167-1024x684.png 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-167-300x200.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-167-768x513.png 768w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-167.png 1113w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<p>The following program implements these steps in practice by pulling the Bitcoin price data from an online API, calculating the moving averages (short- and long-term), and trading based on whether the short-term MA is below or above the long-term MA. <\/p>\n<p>I&#8217;ll explain the code in a minute!<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport requests # Get Bitcoin Price Data\nURL = 'https:\/\/www.alphavantage.co\/query?function=DIGITAL_CURRENCY_DAILY&amp;symbol=BTC&amp;market=USD&amp;apikey=APIKEY'\nresponse = requests.get(URL) data = response.json() daily_data = data[\"Time Series (Digital Currency Daily)\"] # Convert JSON to DataFrame\ndf = pd.DataFrame(daily_data)\ndf = df.T # Create two Moving Averages\nMA1 = 20\nMA2 = 50\ndf['MA1'] = df['1a. open (USD)'].rolling(MA1).mean()\ndf['MA2'] = df['1a. open (USD)'].rolling(MA2).mean() # Initialize variables\nposition = 0\nmy_usd = 10000\nmy_btc = 0 print('Initial balance:', str(my_usd), 'USD') # Backtest Algorithm\nfor i in range(len(df)): # Get price price = float(df['1a. open (USD)'].iloc[i]) # Buy position if df['MA1'].iloc[i] > df['MA2'].iloc[i] and position == 0: position = 1 my_btc = price \/ my_usd my_usd = 0 print('Buying at', price, 'on', df.index[i]) # Sell position elif df['MA1'].iloc[i] &lt; df['MA2'].iloc[i] and position == 1: position = 0 my_usd = price * my_btc my_btc = 0 print('Selling at', price, 'on', df.index[i]) print('Final balance:', str(my_usd + my_btc * price)) initial_btc = float(df['1a. open (USD)'].iloc[0]) \/ 10000\nvalue_today = initial_btc * float(df['1a. open (USD)'].iloc[-1])\nprint('Final balance (buy and hold):', str(value_today))\n<\/pre>\n<h2>Code Explanation<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"684\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-168-1024x684.png\" alt=\"\" class=\"wp-image-1066595\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-168-1024x684.png 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-168-300x200.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-168-768x513.png 768w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-168.png 1113w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<p>This code implements the algorithm described above. <\/p>\n<p>The first portion of the code is getting the daily Bitcoin price data from the API and converting it into a <a href=\"https:\/\/blog.finxter.com\/how-to-create-a-dataframe-in-pandas\/\" data-type=\"post\" data-id=\"16764\" target=\"_blank\" rel=\"noreferrer noopener\">DataFrame<\/a>. <\/p>\n<p>Next, the code creates two moving averages, <code>MA1<\/code> and <code>MA2<\/code>, based on the open price of Bitcoin. Then, the code initializes the position variable to 0.<\/p>\n<p>The backtest algorithm then runs a loop to iterate through the DataFrame to identify when conditions are met to buy or sell. If the shorter-term <code>MA1<\/code> is higher than the longer-term <code>MA2<\/code>, the code will enter a buy position. <\/p>\n<p>Similarly, if the shorter-term <code>MA1<\/code> is lower than the longer-term <code>MA2<\/code>, the code will enter a sell position. We don&#8217;t assume short selling so &#8220;selling&#8221; on an empty position just means waiting for the next buy opportunity.<\/p>\n<p>Finally, if the <code>MA1<\/code> and <code>MA2<\/code> cross, the code will close any existing position and reverse the trading direction.<\/p>\n<h2>Backtesting the Strategy<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"587\" height=\"881\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-169.png\" alt=\"\" class=\"wp-image-1066596\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-169.png 587w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-169-200x300.png 200w\" sizes=\"auto, (max-width: 587px) 100vw, 587px\" \/><\/figure>\n<\/div>\n<p>Let&#8217;s have a look at an example run &#8212; note to read this from bottom to top! <img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/14.0.0\/72x72\/1f447.png\" alt=\"\ud83d\udc47\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"1,22,23\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Initial balance: 10000 USD\nBuying at 20905.58 on 2022-11-07\nSelling at 18809.13 on 2022-09-26\nBuying at 21826.87 on 2022-09-12\nSelling at 19331.28 on 2022-07-13\nBuying at 28424.71 on 2022-06-12\nSelling at 41941.7 on 2022-03-10\nBuying at 42380.87 on 2022-02-07\nSelling at 36660.35 on 2022-01-25\nBuying at 41566.48 on 2022-01-08\nSelling at 57471.35 on 2021-10-12\nBuying at 47674.01 on 2021-08-25\nSelling at 44572.54 on 2021-08-08\nBuying at 40516.28 on 2021-06-15\nSelling at 57351.56 on 2021-03-22\nBuying at 57641.0 on 2021-03-19\nSelling at 56900.74 on 2021-03-17\nBuying at 11318.42 on 2020-08-26\nSelling at 9538.1 on 2020-07-25\nBuying at 9772.44 on 2020-06-10\nSelling at 9315.96 on 2020-05-16\nFinal balance: 14806.674822101442\nFinal balance (buy and hold): 15095.029852800002<\/pre>\n<p>So, you see, in the period between May 2020 and November 2022, trading wouldn&#8217;t have been more profitable than simply buying and holding Bitcoin &#8212; even when ignoring trading fees and higher tax burden. <\/p>\n<p>And ignoring the fact that Bitcoin has had huge up and down volatility, which should be great for trading. That is &#8212; in theory.<\/p>\n<h2>Conclusion<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"711\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-170-1024x711.png\" alt=\"\" class=\"wp-image-1066604\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-170-1024x711.png 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-170-300x208.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-170-768x533.png 768w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2023\/01\/image-170.png 1113w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<div style=\"height:45px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<p>Buy and HODL!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>5\/5 &#8211; (1 vote) I&#8217;ve always wondered if a slow and high-level trading strategy focusing on long-term trends could outperform a buy-and-hold strategy. To answer this question, I created a Python script that would utilize a momentum-based strategy to tell me when to buy and when to sell Bitcoin. Despite my busy life and doubts [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[857],"tags":[73,468,528],"class_list":["post-131257","post","type-post","status-publish","format-standard","hentry","category-python-tut","tag-programming","tag-python","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/131257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=131257"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/131257\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=131257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=131257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=131257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}