In this tutorial, we'll explore how to build a basic trading signals system using Python, leveraging the pandas-datareader
library. This guide will walk you through fetching financial data and developing a simple strategy to identify buy/sell signals. Let's get started.
Prerequisites
To follow along, you'll need a basic understanding of Python and some experience with pandas for data manipulation. Ensure you have pandas-datareader
installed:
pip install pandas-datareader
Fetching Financial Data
pandas-datareader
is a useful tool for accessing online financial datasets. We'll begin by fetching historical stock data. First, import the necessary libraries:
import pandas as pd
import pandas_datareader.data as web
import datetime
Next, define the period for which you want to gather data:
start = datetime.datetime(2020, 1, 1)
end = datetime.datetime(2021, 1, 1)
Fetch the data for a specific stock ticker, say Apple Inc (AAPL):
df = web.DataReader('AAPL', 'yahoo', start, end)
print(df.head())
Calculating Moving Averages
Moving Averages (MA) are a common method to smooth out short-term fluctuations and highlight longer-term trends. We'll calculate the 20-day and 50-day moving averages.
df['20_MA'] = df['Close'].rolling(window=20).mean()
df['50_MA'] = df['Close'].rolling(window=50).mean()
Quickly visualize to ensure your moving averages are computed correctly:
import matplotlib.pyplot as plt
plt.figure(figsize=(12,6))
plt.plot(df['Close'], label='Close Prices')
plt.plot(df['20_MA'], label='20-Day MA')
plt.plot(df['50_MA'], label='50-Day MA')
plt.legend(loc='upper left')
plt.show()
Generating Trading Signals
Our strategy will generate a buy signal when the 20-day MA crosses above the 50-day MA, and a sell signal will be triggered when the opposite happens.
df['Signal'] = 0
# Create signals
df.loc[df['20_MA'] > df['50_MA'], 'Signal'] = 1 # Buy
# When the 20-day goes below the 50-day
df.loc[df['20_MA'] < df['50_MA'], 'Signal'] = -1 # Sell
Let's inspect the generated signals:
print(df[['20_MA', '50_MA', 'Signal']].tail(10))
Backtesting Our Strategy
To evaluate the effectiveness of the strategy, we can backtest it over the historical data. Initiate holdings with a fictitious budget and calculate the portfolio value over time.
df['Position'] = df['Signal'].shift()
df['Daily_Return'] = df['Close'].pct_change()
df['Strategy_Return'] = df['Position'] * df['Daily_Return']
# Assuming the initial capital is $10,000
initial_capital = 10000
# Calculate cumulative returns
df['Total_Return'] = (1 + df['Strategy_Return']).cumprod() * initial_capital
Visualize the portfolio performance:
plt.figure(figsize=(12, 6))
plt.plot(df['Total_Return'], label='Strategy Returns')
plt.title('Strategy Performance over the Period')
plt.xlabel('Date')
plt.ylabel('Portfolio Value ($)')
plt.legend()
plt.show()
So there you have it, a simple model to generate trading signals using moving averages. While this provides a basic understanding, you can explore further by incorporating more sophisticated indicators such as Relative Strength Index (RSI), MACD, or Bollinger Bands to build more robust strategies.