Algorithmic Trading & Indicators Intermediate

Calculate Supertrend Indicator in Python using Pandas (Vectorized)

Copy-paste production-ready Python code to calculate the Supertrend indicator on OHLCV data using Pandas and NumPy. Includes ATR logic and buy/sell signal generation.

#pandas#numpy#yfinance

Problem Statement

Standard libraries like TA-Lib don't include Supertrend out-of-the-box, and naive loops slow down intraday backtesting. This script computes Wilder's RMA-based Supertrend with single-candle flip signals.

Formula / Core Logic

Basic Upper Band = (High + Low) / 2 + (Multiplier x ATR) Basic Lower Band = (High + Low) / 2 - (Multiplier x ATR)

Installation

pip install pandas numpy yfinance
calculate-supertrend-indicator-python-pandas.py
import pandas as pd
import numpy as np

def calculate_supertrend(df, period=10, multiplier=3.0):
    df = df.copy()
    tr1 = df['High'] - df['Low']
    tr2 = (df['High'] - df['Close'].shift(1)).abs()
    tr3 = (df['Low'] - df['Close'].shift(1)).abs()
    df['TR'] = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
    df['ATR'] = df['TR'].ewm(alpha=1/period, adjust=False).mean()
    hl2 = (df['High'] + df['Low']) / 2
    df['Upper'] = hl2 + (multiplier * df['ATR'])
    df['Lower'] = hl2 - (multiplier * df['ATR'])
    df['Trend'] = np.where(df['Close'] > df['Upper'].shift(1), 1, np.where(df['Close'] < df['Lower'].shift(1), -1, np.nan))
    df['Trend'] = df['Trend'].ffill().fillna(1)
    df['Signal'] = np.where((df['Trend'] == 1) & (df['Trend'].shift(1) == -1), 1, np.where((df['Trend'] == -1) & (df['Trend'].shift(1) == 1), -1, 0))
    return df

Get the Complete 100+ Python Quant & Automation Bundle

Instant lifetime access to all production-ready scripts, valuation models, and trading bots ($19).

Buy Full Bundle on Gumroad ($19) →

Frequently Asked Questions

Q: Why use Wilder's RMA for ATR?

Wilder's smoothing (ewm(alpha=1/period)) matches exact Supertrend values on TradingView and broker terminals.