Backtesting Stock Trading Strategies Using Python (Environment)
Welcome back to the second part of our series on backtesting stock trading strategies using Python. In this article, we will walk you through the process of creating an environment to backtest any strategy and explain how to use it by creating an example strategy.

To begin with, let’s briefly review what we covered in the first part of this series. In Part 1, we showed you how to use Python to obtain the OIH stock data from the internet, and how to generate files with the data in different timeframes, such as 1-minute, 5-minute, 15-minute, 1-hour, and 1 day. We encourage you to read Part 1 before continuing with this article, as it will provide you with the data we will be using.
Now that we have our data, let’s dive into the code and see how we can use it to backtest a strategy. We will start by importing the necessary libraries:
import numpy as np
import pandas as pd
import pandas_ta as taWe also need to define the timeframes we will be using (we only use the 15-minute, 1-hour, and 1-day timeframes for simplicity and performance):
TIMEFRAMES = ['15T', '1H', '1D']In this example, we will be using the MACD indicator and the Zero-Cross Strategy. The Zero-Cross Strategy is a popular and simple trading strategy that involves buying when the MACD line crosses from below the zero line and selling when the MACD line crosses from above the zero line.
The get_signals method below will obtain the buy and sell signals determined by the selected strategy. The resulting signals are represented as a series of numerical values:
- 1 indicates a buy signal,
- 0 indicates a hold signal, and
- -1 indicates a sell signal.
def get_signals(df):
# Get the MACD values (MACD, Histogram, and Signal) and rename the columns to something meaningful
macd = df.ta.macd().dropna().reset_index(drop=True)
macd.columns = ['macd', 'histogram', 'signal']
# Calculate the buy and sell points using the Zero-Cross Strategy
macd['signal'] = np.where((macd['histogram'] > 0) & (macd['histogram'].shift() <= 0), 1, 0)
macd['signal'] = np.where((macd['histogram'] < 0) & (macd['histogram'].shift() >= 0), -1, macd['signal'])
return macd['signal']The show_stategy_result method below will simulate a long position strategy and visualize the results. Note that it assumes the purchase of one share per transaction and does not account for any fees.
The basic idea of this strategy is that we buy a stock when we receive a buy signal and hold onto it until we receive a sell signal. When we receive a sell signal, we sell the stock and calculate the profit or loss.
Finally, after iterating through all the rows in the DataFrame, the method prints the total profit or loss, the number of winning trades, the number of losing trades, and the win rate calculated as the percentage of wins out of the total number of trades.
def show_stategy_result(timeframe, df):
waiting_for_close = False
open_price = 0
profit = 0.0
wins = 0
losses = 0
for i in range(len(df)):
signal = df.iloc[i]['signal']
if signal == 1 and not waiting_for_close:
waiting_for_close = True
open_price = df.iloc[i]['close']
elif signal == -1 and waiting_for_close:
waiting_for_close = False
close_price = df.iloc[i]['close']
profit += close_price - open_price
wins = wins + (1 if (close_price - open_price) > 0 else 0)
losses = losses + (1 if (close_price - open_price) < 0 else 0)
print(f' Result for timeframe {timeframe} '.center(60, '*'))
print(f'* Profit/Loss: {profit:.2f}')
print(f"* Wins: {wins} - Losses: {losses}")
print(f"* Win Rate: {100 * (wins/(wins + losses)):6.2f}%")Finally, we iterate over each timeframe, apply the strategy, and show the results:
for timeframe in TIMEFRAMES:
# Read the data
df = pd.read_csv(f'OIH_{timeframe}.csv.gz', compression='gzip')
# Add the signals to each row
df['signal'] = get_signals(df)
# Get the result of the strategy
show_strategy_result(timeframe, df)Here, we read the data for each timeframe, add the signals for each row, and show the results using the show_strategy_result function.
If you run this code with the data provided in the first article, you should see something similar to this.
***************** Result for timeframe 5T ****************** * Profit/Loss: -20056.65 * Wins: 7793 - Losses: 9490 * Win Rate: 45.09% ***************** Result for timeframe 15T ***************** * Profit/Loss: -11212.40 * Wins: 2855 - Losses: 3472 * Win Rate: 45.12% ***************** Result for timeframe 1H ****************** * Profit/Loss: -6789.04 * Wins: 937 - Losses: 1106 * Win Rate: 45.86% ***************** Result for timeframe 1D ****************** * Profit/Loss: -2238.89 * Wins: 89 - Losses: 123 * Win Rate: 41.98%
Note that the strategy used here is just an example, and it is not intended to be a profitable strategy. The main purpose is to demonstrate how to create an environment to backtest any strategy using Python.
In conclusion, backtesting stock trading strategies using Python can be a powerful tool for traders and investors. It allows you to test your strategies and evaluate their performance without risking any real money. By following the steps outlined in this article, you can create your own backtesting environment and start testing your own trading strategies.
If there’s a specific strategy you would like me to implement, please leave a comment detailing the strategy, and I will be sure to do it in a future article.
If you enjoy my work, please support me on Medium by becoming a member through my referral link, and consider giving it a clap as a small gesture of motivation. Thank you!
Download the full source code of this article from here
Twitter / X: https://twitter.com/diegodegese LinkedIn: https://www.linkedin.com/in/ddegese Github: https://github.com/crapher
A Message from InsiderFinance

Thanks for being a part of our community! Before you go:
- 👏 Clap for the story and follow the author 👉
- 📰 View more content in the InsiderFinance Wire
- 📚 Take our FREE Masterclass
- 📈 Discover Powerful Trading Tools





