Bitcoin Trade Automation with Awesome Oscillator in Python

Implementing and backtesting an AO-based powerful trading strategy to make bitcoin trades in python



In recent days, the hype surrounding Bitcoin or cryptocurrency has only increased and has never seen a decline in momentum. While Bitcoin is reaching record-breaking heights, many speculators believe that it is just another bubble and can burst at any time. Also, while analyzing the reason behind the sudden price hikes in Bitcoin, it seems that human mentality and greed play a vital role. After considering these facts, we could say that the Bitcoin market is one of the most volatile and riskier markets to trade-in. Fortunately, with the help of Algorithmic Trading, we could handle this volatile market safely by automating the trades. In this article, we are going to use a powerful technical indicator named Awesome Oscillator (AO) and create a trading strategy based on it to make automated Bitcoin trades with python.


Awesome Oscillator (AO)


Awesome Oscillator (AO) is a leading technical indicator used to identify a market’s trend or to measure a market’s momentum. The Awesome Oscillator is plotted in the form of a histogram which reveals a green bar when the current bar is higher than the previous bar, similarly, a red bar is revealed when the current bar is lower than the previous bar. Being an oscillator, the values of the Awesome Oscillator fluctuates above and below the zero line.


To know how AO is calculated, it is essential to have some knowledge of the Simple Moving Average (SMA). SMA is nothing but the average price of a specified period of time. Awesome Oscillator is calculated by subtracting the 34 periods Simple Moving Average from the 5 periods Simple Moving Average. The SMAs are not calculated from the close prices of the stocks but instead, from the median price. The way to calculate Awesome Oscillator can be represented as follows:



AO = SMA 5 OF MEDIAN PRICE - SMA 34 OF MEDIAN PRICE


Now that we have an understanding of what Awesome Oscillator is. Let’s build some intuitions on our trading strategy.


About our trading strategy: There are many types of AO-based trading strategies which can be implemented but in this article, we are going to explore one the basic strategy called Zero Line Cross. When AO crosses from below to above the zero line, a buy signal is generated by our trading strategy. A sell signal is revealed when AO crosses from above the below the zero line. Ou trading strategy can be represented as follows:



IF PREVIOUS AO < 0 AND CURRENT AO > 0 => BUY SIGNAL
IF PREVIOUS AO > 0 AND CURRENT AO < 0 => SELL SIGNAL 


Now that we have an understanding of what AO means and how can it be used to build a trading strategy. Let’s use Python to implement our own AO-based trading strategy and backtest it to see how well it performs in the real-world market.


Before moving on, a note on disclaimer: This article’s sole purpose is to educate people and must be considered as an information piece but not as investment advice or so.


Python Implementation


The coding part is classified into various steps as follows:



1. Importing Packages
2. Extracting Data from Alpha Vantage
3. Awesome Oscillator Calculation
4. AO Plot
5. Creating the Trading Strategy
6. Plotting the Trading Signals
7. Creating our Position
8. Backtesting


We will be following the order mentioned in the above list and buckle up your seat belts to follow every upcoming coding part.


Step-1: Importing Packages


Importing the required packages into the python environment is a non-skippable step. The primary packages are going to be Pandas to work with data, NumPy to work with arrays and for complex functions, Matplotlib for plotting purposes, and Requests to make API calls. The secondary packages are going to be Math for mathematical functions and Termcolor for font customization (optional).


Python Implementation:



import pandas as pd
import requests
import numpy as np
import matplotlib.pyplot as plt
from math import floor
from termcolor import colored as cl

plt.rcParams['figure.figsize'] = (20, 10)
plt.style.use('fivethirtyeight')


Now that we have imported all the essential packages into our python environment. Let’s proceed with pulling the historical data of Bitcoin with Alpha Vantage’s powerful crypto API.


Step-2: Extracting Data from Alpha Vantage


In this step, we are going to pull the historical data of Bitcoin using an API endpoint provided by Alpha Vantage. Before that, a note on Alpha Vantage: Alpha Vantage provides free stock APIs through which users can access a wide range of data like real-time updates, and historical data on equities, currencies, and cryptocurrencies. Make sure that you have an account on Alpha Vantage, only then, you will be able to access your secret API key (a crucial element for pulling data using an API).


Python Implementation:



def get_crypto_price(symbol, exchange, start_date = None):
    api_key = open(r'api_key.txt')
    api_url = f'https://www.alphavantage.co/query?function=DIGITAL_CURRENCY_DAILY&symbol={symbol}&market={exchange}&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['Time Series (Digital Currency Daily)']).T
    df = df.rename(columns = {'1a. open (USD)': 'Open', '2a. high (USD)': 'High', '3a. low (USD)': 'Low', '4a. close (USD)': 'Close', '5. volume': 'Volume'})
    for i in df.columns:
        df[i] = df[i].astype(float)
    df.index = pd.to_datetime(df.index)
    df = df.iloc[::-1].drop(['1b. open (USD)', '2b. high (USD)', '3b. low (USD)', '4b. close (USD)', '6. market cap (USD)'], axis = 1)
    if start_date:
        df = df[df.index >= start_date]
    return df

btc = get_crypto_price(symbol = 'BTC', exchange = 'USD', start_date = '2020-01-01')
btc


Output:



Code Explanation: The first thing we did is to define a function named ‘get_historical_data’ that takes the crypto’s symbol (‘symbol’), crypto exchange (‘exchange’) as required parameters, and the starting date of the historical data (‘start_date’) as an optional parameter. Inside the function, we are defining the API key and the URL and stored them into their respective variable. Next, we are extracting the historical data in JSON format using the ‘get’ function and stored it into the ‘raw_df’ variable. After doing some processes to clean and format the raw JSON data, we are returning it in the form of a clean Pandas dataframe. Finally, we are calling the created function to pull the historical data of Bitcoin with US Dollar as an exchange from the starting of 2020 and stored it into the ‘btc’ variable.


Step-3: Awesome Oscillator Calculation


In this step, we are going to calculate the values of the Awesome Oscillator by following the formula we discussed before.


Python Implementation:



def sma(price, period):
    sma = price.rolling(period).mean()
    return sma

def ao(price, period1, period2):
    median = price.rolling(2).median()
    short = sma(median, period1)
    long = sma(median, period2)
    ao = short - long
    ao_df = pd.DataFrame(ao).rename(columns = {'Close':'ao'})
    return ao_df

btc['ao'] = ao(btc['Close'], 5, 34)
btc = btc.dropna()
btc.tail()


Output:



Code Explanation: This code can be classified into two sections: SMA calculation and AO calculation. In the first section, we are defining a function named ‘sma’ that takes the crypto prices (‘price’), and the number of periods (‘period’) as the parameters. Inside the function, we are using the ‘rolling’ function provided by the Pandas package to calculate the SMA for the given number of periods. We are storing the calculated values into the ‘sma’ variable and returned it.


In the second section, we are defining another function named ‘ao’ that takes the crypto prices (‘price’), short length SMA (‘period1’), and long length SMA (‘period2’) as parameters. Inside the function, we are first calculating the median values for the given crypto prices using the ‘rolling’ and ‘median’ function provided by the Pandas package. Next, we are defining two variables named ‘short’ and ‘long’ to store the short length and long length SMA calculated using the function we created before. To calculate the values of the Awesome Oscillator, we are subtracting the long length SMA from the short length SMA and stored it into the ‘ao’ variable. Then we are converting the ‘ao’ variable to a dataframe and returned it. Finally, we are calling the function to store the AO values of Bitcoin.


Step-4: Awesome Oscillator Plot


In this step, we are going to plot the calculated Awesome Oscillator values of Bitcoin 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 Awesome Oscillator.


Python Implementation:



ax1 = plt.subplot2grid((10,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((10,1), (6,0), rowspan = 4, colspan = 1)
ax1.plot(btc['Close'])
ax1.set_title('BITCOIN CLOSING PRICE')
for i in range(len(btc)):
    if btc['ao'][i-1] > btc['ao'][i]:
        ax2.bar(btc.index[i], btc['ao'][i], color = '#f44336')
    else:
        ax2.bar(btc.index[i], btc['ao'][i], color = '#26a69a')
ax2.set_title('BITCOIN AWESOME OSCILLATOR 5,34')
plt.show()


Output:



The above chart is divided into two panels: The above panel representing the close prices of Bitcoin and the below panel with the AO values plotted in the form of a histogram. As you can see, whenever the current bar is greater than the previous bar, a bar with green color is plotted on the chart, and, whenever the current bar is lesser than the previous bar, a red-colored bar is plotted on the chart.


Market momentum: The market’s momentum can easily be identified by seeing the length of the histogram bars. You could see in the above panel of the chart that the price movement of Bitcoin was not so great in the first ten months and you could also see the bars of the AO histogram is tiny revealing that the momentum of the market is poor. On the other hand, the last few months were quite great for Bitcoin and you could see the bars of the AO histogram are larger revealing a greater market momentum.


Market trend: Like how the market’s momentum can be identified easily with the histogram of AO, it also helps in knowing the trend of the marker either a down or uptrend. A market is considered to be in an uptrend when the values of the Awesome Oscillator are greater than the zero line and similarly, a downtrend in the market can be identified when the values of the Awesome Oscillator are lesser than the zero line.


Step-5: Creating the trading strategy


In this step, we are going to implement the discussed Awesome Oscillator trading strategy in python.


Python Implementation:



def implement_ao_crossover(price, ao):
    buy_price = []
    sell_price = []
    ao_signal = []
    signal = 0
    
    for i in range(len(ao)):
        if ao[i] > 0 and ao[i-1] < 0:
            if signal != 1:
                buy_price.append(price[i])
                sell_price.append(np.nan)
                signal = 1
                ao_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                ao_signal.append(0)
        elif ao[i] < 0 and ao[i-1] > 0:
            if signal != -1:
                buy_price.append(np.nan)
                sell_price.append(price[i])
                signal = -1
                ao_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                ao_signal.append(0)
        else:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            ao_signal.append(0)
    return buy_price, sell_price, ao_signal

buy_price, sell_price, ao_signal = implement_ao_crossover(btc['Close'], btc['ao'])


Code Explanation: First, we are defining a function named ‘implement_ao_strategy’ which takes the stock prices (‘price), and the AO values (‘ao’) as parameters.


Inside the function, we are creating three empty lists (buy_price, sell_price, and ao_signal) in which the values will be appended while creating the trading strategy.


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 ‘buy_price’ 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 ‘sell_price’ list, and the signal value will be appended as -1 representing to sell the stock.


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’t make any sense unless we plot the values. So, let’s plot the values of the created trading lists.


Step-6: Plotting the Trading Signals


In this step, we are going to plot the created trading lists to make sense out of them.


Python Implementation:



ax1 = plt.subplot2grid((10,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((10,1), (6,0), rowspan = 4, colspan = 1)
ax1.plot(btc['Close'], label = 'BTC', color = 'skyblue')
ax1.plot(btc.index, buy_price, marker = '^', markersize = 12, color = '#26a69a', linewidth = 0, label = 'BUY SIGNAL')
ax1.plot(btc.index, sell_price, marker = 'v', markersize = 12, color = '#f44336', linewidth = 0, label = 'SELL SIGNAL')
ax1.legend()
ax1.set_title('BITCOIN CLOSING PRICE')
for i in range(len(btc)):
    if btc['ao'][i-1] > btc['ao'][i]:
        ax2.bar(btc.index[i], btc['ao'][i], color = '#f44336')
    else:
        ax2.bar(btc.index[i], btc['ao'][i], color = '#26a69a')
ax2.set_title('BITCOIN AWESOME OSCILLATOR 5,34')
plt.show()


Output: