Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

Designing Simple EMA Crossover Intraday Scanner using Python

2 min read

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.

Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

[Live Coding Webinar] Build Your First Trading Bridge for…

In this course, you will be learning to build your own trading bridge using Python. This 60-minute session is perfect for traders, Python enthusiasts,...
Rajandran R
1 min read

How to Place Orders Concurrently using ThreadPoolExecutor – Python…

Creating concurrent orders is essential for active traders, especially those handling large funds, as it allows for executing multiple trade orders simultaneously, thereby maximizing...
Rajandran R
2 min read

Host your Python Flask Web Application using pyngrok and…

Ngrok offers several significant advantages for developers, especially when it comes to testing applications or hosting machine learning models. Ngrok allows you to expose...
Rajandran R
1 min read

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More