This Python script is designed to track and analyze Exponential Moving Average (EMA) crossovers for a set of specified stock tickers within a certain time frame. It utilizes the yfinance
library to fetch 5-minute interval stock data, pandas
for data manipulation, and pandas_ta
to calculate the 10 and 20-period EMAs. The script defines a set of tickers in lists and sets the trading window from 9:30 AM to 3:00 PM. The scanning history output will scan for crossover only between 9.30a.m – 3.00p.m
Timeframe Used for Scanning: 5minute data
Data Source: YFinance
Portfolio Tickers: HDFCBANK.NS, TATASTEEL.NS, ICICIBANK.NS, RELIANCE.NS
Data Download Period: Last 3 Trading Days
Installing the Library
pip install pandas
pip install pandas_ta
pip install yfinance
pip install tabulate
Simple EMA Crossover Intraday Scanner – Python Code
from tabulate import tabulate
import yfinance as yf
import pandas as pd
import pandas_ta as ta
import datetime
# Define the tickers and time range
tickers = ["HDFCBANK.NS", "TATASTEEL.NS", "WIPRO.NS", "ICICIBANK.NS", "RELIANCE.NS"]
start_time = datetime.time(9, 30) # 09:30 AM
end_time = datetime.time(15, 0) # 03:00 PM
def fetch_and_calculate_ema(ticker):
# Fetching 5min interval data for the current day, suppress progress bar
data = yf.download(ticker, interval='5m', period='3d', progress=False)
# Calculating 10 and 20 EMA
data['EMA10'] = ta.ema(data['Close'], length=10)
data['EMA20'] = ta.ema(data['Close'], length=20)
return data
def check_crossover(data, ticker):
crossover_events = pd.DataFrame()
for i in range(1, len(data)):
current_time = data.index[i].time()
if start_time <= current_time <= end_time:
# Check for positive crossover
if (data['EMA10'][i] > data['EMA20'][i]) and (data['EMA10'][i-1] < data['EMA20'][i-1]):
event = pd.DataFrame([{
"DateTime": data.index[i],
"Ticker": ticker,
"Crossover Type": "Positive EMA Crossover",
"Close": data['Close'][i],
"EMA10": data['EMA10'][i],
"EMA20": data['EMA20'][i]
}])
crossover_events = pd.concat([crossover_events, event])
# Check for negative crossover
elif (data['EMA10'][i] < data['EMA20'][i]) and (data['EMA10'][i-1] > data['EMA20'][i-1]):
event = pd.DataFrame([{
"DateTime": data.index[i],
"Ticker": ticker,
"Crossover Type": "Negative EMA Crossover",
"Close": data['Close'][i],
"EMA10": data['EMA10'][i],
"EMA20": data['EMA20'][i]
}])
crossover_events = pd.concat([crossover_events, event])
return crossover_events
# ANSI color codes
RED = '\033[31m'
GREEN = '\033[32m'
RESET = '\033[0m'
def scan_tickers():
all_crossovers = pd.DataFrame()
for ticker in tickers:
data = fetch_and_calculate_ema(ticker)
crossover_events = check_crossover(data, ticker)
all_crossovers = pd.concat([all_crossovers, crossover_events])
if not all_crossovers.empty:
# Convert 'DateTime' to a datetime object if it's not already
all_crossovers['DateTime'] = pd.to_datetime(all_crossovers['DateTime'])
# Round off the values to two decimal places
all_crossovers['Close'] = all_crossovers['Close'].round(2)
all_crossovers['EMA10'] = all_crossovers['EMA10'].round(2)
all_crossovers['EMA20'] = all_crossovers['EMA20'].round(2)
# Sort by DateTime
all_crossovers.sort_values(by='DateTime', inplace=True)
# Apply color coding to the 'Crossover Type'
all_crossovers['Crossover Type'] = all_crossovers['Crossover Type'].apply(
lambda x: f"{GREEN}{x}{RESET}" if "Positive" in x else f"{RED}{x}{RESET}"
)
# Tabulate and print
tabulated_data = tabulate(all_crossovers, headers='keys', tablefmt='fancy_grid', showindex=False)
print(tabulated_data)
return True
# Run the scan
scan_tickers()
Output
Defines the Summary of What the Python Code Does
Define Tickers and Time Range: Set up the stocks you’re interested in and the time range for the trading day.
Fetch and Calculate EMA: Downloads historical stock data for each ticker and calculates the 10 and 20-period EMAs.
Check Crossover: Checks for points where the 10-period EMA crosses above (positive crossover) or below (negative crossover) the 20-period EMA within the trading hours.
Scan Tickers: Iterates over each ticker, gathers the crossover events, and then compiles them into one DataFrame. It then sorts this DataFrame by the DateTime
column to ensure the events are in chronological order.
Tabulate and Print: Converts the sorted DataFrame into a nicely formatted table using tabulate
and prints it out.
Finally, the script is designed to be run once for demonstration, but in practical applications, it’s intended to be scheduled to run periodically throughout the trading day. It provides a structured output of significant EMA crossovers, valuable for traders monitoring multiple stocks for potential trading signals based on EMA strategies.