Introduction
Algorithmic trading is a widely adopted trading strategy that has revolutionized the way people trade stocks. More and more people are making money by investing in stocks and automating their trading strategies. This tutorial will teach you how to create stock trading algorithms using primitive technical indicators like MACD, SMA, EMA, etc., and select the best strategies based on their actual performance/profitability, completely using Python.
Learning objectives
- Learn what algorithmic trading is.
- Create simple stock trading algorithms in Python, using technical indicators to generate buy and sell signals.
- Learn how to implement trading strategies and automate them in Python.
- Learn how to compare and select the best trading strategy based on your average returns.
This article was published as part of the Data Science Blogathon.
Disclaimer: This is not financial adviceand all work done in this project is for educational purposes only.
What is algorithmic trading?
Algorithmic trading is a method of trading financial assets that uses automated computer programs to execute orders based on predefined rules and strategies. It involves the use of various trading strategies, including statistical arbitrage, trend following, and mean reversion, to name a few.
There are many different types of algorithmic trading. One of them is high-frequency trading, which involves executing trades at high speeds with almost no latency to take advantage of small price movements. Another is news-based trading, which involves placing trades based on news and other market events.
In this article, we will use Python to perform stock trading based on technical indicators and candle pattern detection.
How to use Python algorithms for stock trading analysis?
We can analyze the stock market, discover trends, develop trading strategies, and set up signals to automate stock trading, all using Python! The algorithmic trading process using Python involves a few steps such as selecting the database, installing certain libraries, and extracting historical data. Let’s now delve into each of these steps and learn how to create simple stock trading algorithms.
Select the data set
There are thousands of stocks listed on the stock market and we can consider any set of stocks to build the algorithm. However, it is always a good option to consider similar types of stocks, as their fundamentals and technicals will be comparable.
In this article, we will consider the Nifty 50 stocks. The Nifty 50 index consists of 50 of India’s top companies chosen based on various factors such as market capitalization, liquidity, sector representation and financial performance. The index is also widely used as a benchmark to measure the performance of the Indian stock market and as a result, there is a lower amount of risk in investing in these companies compared to investing in small or mid-cap companies. I will consider WIPRO for carrying out the analysis of this article. The analysis approach discussed in this article can be performed on any set of similar actions by calling functions for each action in a for loop.
Installing the necessary libraries
We will use the default libraries like pandas, numpy, matplotlib along with yfinance and pandas_ta. He finance The library will be used to extract historical stock prices. He panda_ta The library will be used to implement the SMA and MACD indicator and build the trading algorithm. These modules can be installed directly using pip like any other Python library. Let’s import the modules after installing them.
!pip install yfinance
!pip install pandas-ta
import yfinance as yf
import pandas as pd
import pandas_ta as ta
import numpy as np
from datetime import datetime as dt
import matplotlib.pyplot as plt
from datetime import timedelta as delta
import numpy as np
import os
import seaborn as sb
Now that we have installed and imported all the necessary libraries, let’s get our hands dirty and start developing the strategies.
We will use the “discharge()”yfinance module function to extract the historical price of a stock, which accepts the stock picker, start date and end date. For the sake of simplicity, we will take “2000-01-01” as the start date and the current date as the end date. We will write a simple function that extracts historical stock prices and returns them as a data frame for further processing while saving them as a CSV file on our disk.
def get_stock_info(stock, save_to_disk=False):
start_date="2000-01-01"
end_date = (dt.now() + delta(1)).strftime('%Y-%m-%d')
df = yf.download(f"{stock}.NS", period='1d', start=start_date, end=end_date, progress=False)
if(save_to_disk == True):
path="./csv"
try: os.mkdir(path)
except OSError as error: pass
df.to_csv(f'{path}/{stock}.csv')
return df
df = get_stock_info('WIPRO', save_to_disk = True)
Creating stock trading algorithms using technical indicators
There are numerous indicators available for trading stocks, but we will use one of the two simplest but extremely popular indicators, namely SMA and MACD. SMA means simple moving average while MACD means Moving Average Convergence Divergence. In case you are not familiar with these terms, you can learn more about them in this article. In short, we will try to find SMA Crossover and MACD Crossover as trading signals and try to find the best combination of the lot to maximize returns.
For the SMA crossover, we will take into account the 10, 30, 50 and 200 day moving averages. For the MACD crossover, we will take into account the 12, 26 and 9 day exponential moving averages. Let’s calculate these values using the pandas_ta library.
To calculate the SMA, we will use the “sma()” It works by passing the adjusted closing price of the stock along with the number of days. To calculate the MACD, we will use the “macd()” It works by passing the adjusted closing price of the stock and setting the fast, slow and signal parameters to 12, 26 and 9 respectively. The SMA and MACD values do not make much sense as such. So let’s code them to understand if there are crossovers.
In the case of SMA, we will take 3 conditions:
- The 10-day SMA should be above the 30-day SMA.
- The 10-day and 30-day SMA should be above the 50-day SMA.
- The 10, 30 and 50 day time frames should be above the 200 day SMA.
In the case of the MACD, we will have 2 conditions:
- The MACD must be above the MACD signal.
- The MACD must be greater than 0.
The Python code given below creates a function to implement the conditions mentioned above.
def add_signal_indicators(df):
df('SMA_10') = ta.sma(df('Adj Close'),length=10)
df('SMA_30') = ta.sma(df('Adj Close'),length=30)
df('SMA_50') = ta.sma(df('Adj Close'),length=50)
df('SMA_200') = ta.sma(df('Adj Close'),length=200)
macd = ta.macd(df('Adj Close'), fast=12, slow=26, signal=9)
df('MACD') = macd('MACD_12_26_9')
df('MACD_signal') = macd('MACDs_12_26_9')
df('MACD_hist') = macd('MACDh_12_26_9')
df('10_cross_30') = np.where(df('SMA_10') > df('SMA_30'), 1, 0)
df('MACD_Signal_MACD') = np.where(df('MACD_signal') < df('MACD'), 1, 0)
df('MACD_lim') = np.where(df('MACD')>0, 1, 0)
df('abv_50') = np.where((df('SMA_30')>df('SMA_50'))
&(df('SMA_10')>df('SMA_50')), 1, 0)
df('abv_200') = np.where((df('SMA_30')>df('SMA_200'))
&(df('SMA_10')>df('SMA_200'))&(df('SMA_50')>df('SMA_200')), 1, 0)
return df
df = add_signal_indicators(df)
Now that we have all the signals added to our data, it’s time to calculate the returns. The returns will be the most important aspect to select the best trading strategy among all. We will calculate the 5 and 10 day stock returns. We will also code the returns as 0 and 1, where 0 indicates negative returns and 1 indicates positive returns. Let’s go ahead and create the function that implements the same.
def calculate_returns(df):
df('5D_returns') = (df('Adj Close').shift(-5)-df('Adj Close'))/df('Close')*100
df('10D_returns') = (df('Adj Close').shift(-10)-df('Adj Close'))/df('Close')*100
df('5D_positive') = np.where(df('5D_returns')>0, 1, 0)
df('10D_positive') = np.where(df('10D_returns')>0, 1, 0)
return df.dropna()
df = calculate_returns(df)
Understand signal performance
We can take all the conditions mentioned above and perform a simple aggregation to calculate the average and median returns we can expect when trading based on these signals. We can also extract the minimum and maximum returns that each signal has generated in the past. This will not only give us a rough idea of how good the signals are, but also an idea of how many returns can be expected when trading these signals. Let’s write a simple code to do the same using Python.
def get_eda_and_deepdive(df):
eda = df.dropna().groupby(('10_cross_30', 'MACD_Signal_MACD',
'MACD_lim', 'abv_50', 'abv_200'))(('5D_returns', '10D_returns'))\
.agg(('count', 'mean','median', 'min', 'max'))
deepdive = df.dropna().groupby(('10_cross_30', 'MACD_Signal_MACD',
'MACD_lim', 'abv_50', 'abv_200','5D_positive', '10D_positive'))(('5D_returns', '10D_returns'))\
.agg(('count', 'mean','median', 'min', 'max'))
return eda, deepdive
eda, deepdive = get_eda_and_deepdive(df)
Let’s visualize the box whisker plot for the top 10 signal combinations sorted by 5-day and 10-day returns.
x = df.copy()
def _fun(x):
code=""
for i in x.keys(): code += str(x(i))
return code
x('signal') = x(('10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200',
'5D_positive', '10D_positive')).apply(_fun, axis=1)
x = x.dropna()
lim = x.groupby(('10_cross_30', 'MACD_Signal_MACD', 'MACD_lim',
'abv_50', 'abv_200', '5D_positive', '10D_positive'))('5D_returns').agg(('mean')).reset_index()
lim = lim.sort_values(by='mean', ascending=False).head(10)
x = x.merge(lim, on=('10_cross_30', 'MACD_Signal_MACD', 'MACD_lim',
'abv_50', 'abv_200', '5D_positive', '10D_positive'), how='inner')
ax = sb.boxplot(x='signal', y='5D_returns', data=x)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
plt.show()
ax = sb.boxplot(x='signal', y='10D_returns', data=x)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
plt.show()
Taking only the 5 and 10 day returns to select the best signals is not the best approach because we will never know how many times the signal has given positive returns versus negative returns. This approach could be taken into account when selecting the best strategies, which could potentially improve the performance of the strategies. I won’t take this approach to keep this article simple and beginner-friendly.
Conclusion
The concept of algorithmic trading can be extremely tempting to many as it can be very lucrative, but at the same time it tends to be an extremely complex and tedious task to create stock trading algorithms from scratch. It is very important to understand the fact that all algorithms can fail, which could lead to huge financial losses when implemented in a real business environment. The goal of this article was to explore how simple trading algorithms can be created and validated using Python. To continue in this project, you can consider other technical indicators and candlestick patterns and use them interchangeably to create more complex algorithms and strategies.
Key takeaways
- In this article, we learned how to extract historical stock prices using yfinance.
- We learned how to calculate MACD and SMA values based on stock price and build Python algorithms to create signals/strategies using these values.
- We also learned how to calculate and visualize 5- and 10-day returns for stock strategies.
Note: This is not financial advice, and all work done on this project is for educational purposes only. That’s all for this article. I hope you enjoyed reading this article and learned something new. Thanks for reading and happy learning!
Frequent questions
Answer. No, all stock trading strategies are doomed to fail and can lead to capital losses. The strategies used in this article are for educational purposes only. Do not use them to make financial investments.
Answer. Yes, these signals can be considered feature-designed variables and can be used to perform machine learning or deep learning.
Answer. It is important to select similar stocks as their fundamentals and other parameters such as alpha/beta will be comparable. The alpha and beta values of a large-cap company and a small-cap company can be in different ranges. Therefore, it may not be correct to mix them randomly when performing this analysis.
Answer. There are hundreds of indicators available and widely used for trading, such as RSI, MACD and SMA. There are numerous candlestick technical indicators available, as well as HARAMICROSS, MORNINGSTAR and HAMMER, which can help generate the signals.
Answer. This analysis can be performed for commodities with a large amount of historical data. But in the case of cryptocurrencies, it depends on how much historical data is actually available. The analysis could fail or give an erroneous conclusion if the signals occur too many times in all the historical data.
The media shown in this article is not the property of Analytics Vidhya and is used at the author’s discretion.