Rajandran R Creator of OpenAlgo Sketchmaker, RagZ. Building GenAI Applications. 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. Now the recent curiosity on building Trading AI Agents.

Halftrend Indicator – Python Code

2 min read

Halftrend is a Trend trend-following indicator that could manage the sideways market better. In this tutorial, we will be building Halftrend using pandas_ta and the Plotly Python library. Halftrend which is considered a better than Supertrend indicator to manage sideways markets with fewer whipsaws

Halftrend comes with an upline (buymode) and a downline (sellmode) and trend (+1 – long direction and -1 is short direction and ATR bands (upper and lower).

Importing the Libraries

import yfinance as yf
import pandas as pd
import pandas_ta as ta
import plotly.graph_objects as go
import numpy as np

Halftrend Function

def halftrend(data, amplitude=2, channel_deviation=4):
    
    data['ATR'] = ta.atr(data['High'], data['Low'], data['Close'], length=50)

    atr = data['ATR'] / 2
    atr /= 2

    dev = channel_deviation * atr

    current_high = data['High'].mask(data['High'].shift(-amplitude) > data['High'].rolling(window=amplitude, min_periods=1).max(), np.nan)
    current_low = data['Low'].mask(data['Low'].shift(-amplitude) < data['Low'].rolling(window=amplitude, min_periods=1).min(), np.nan)

    upper_band = data['High'].rolling(window=amplitude, min_periods=1).mean()
    lower_band = data['Low'].rolling(window=amplitude, min_periods=1).mean()

    main = pd.Series(index=data.index, dtype='float64')
    trend = pd.Series(index=data.index, dtype='float64')
    up_line = pd.Series(index=data.index, dtype='float64')
    down_line = pd.Series(index=data.index, dtype='float64')
    atr_high = pd.Series(index=data.index, dtype='float64')
    atr_low = pd.Series(index=data.index, dtype='float64')

    for i in range(1, len(data)):
        if trend[i-1] > 0:
            main[i] = max(main[i-1], current_low[i])
            if upper_band[i] < main[i] and data['Close'][i] < data['Low'][i-1]:
                trend[i] = -1
                main[i] = min(main[i-1], current_high[i])
            else:
                trend[i] = trend[i-1] + 1
        elif trend[i-1] < 0:
            main[i] = min(main[i-1], current_high[i])
            if lower_band[i] > main[i] and data['Close'][i] > data['High'][i-1]:
                trend[i] = 1
                main[i] = max(main[i-1], current_low[i])
            else:
                trend[i] = trend[i-1] - 1
        else:
            if data['Close'][i] > data['Close'][i-1]:
                trend[i] = 1
                main[i] = current_low[i]
            else:
                trend[i] = -1
                main[i] = current_high[i]

        if trend[i] > 0:
            up_line[i] = main[i]
            down_line[i] = None
            atr_high[i] = up_line[i] + dev[i]
            atr_low[i] = up_line[i] - dev[i]
        else:
            up_line[i] = None
            down_line[i] = main[i]
            atr_high[i] = down_line[i] + dev[i]
            atr_low[i] = down_line[i] - dev[i]

    return trend, up_line, down_line, atr_high, atr_low

Download the Data and Compute Halftrend

# Download historical data
ticker = 'RELIANCE.NS'
start_date = '2023-01-01'
end_date = '2024-01-01'
data = yf.download(ticker, start=start_date, end=end_date)

# Compute Halftrend
trend, up_line, down_line, atr_high, atr_low = halftrend(data,amplitude=2,channel_deviation=4)

Plot Candlestick Along with Halftrend Indicator

# Plotting with Plotly
fig = go.Figure(data=[go.Candlestick(x=data.index,
                open=data['Open'],
                high=data['High'],
                low=data['Low'],
                close=data['Close'],
                name='Candlesticks'),
                go.Scatter(x=data.index, y=up_line, mode='lines', name='Up Line', line=dict(color='green')),
                go.Scatter(x=data.index, y=down_line, mode='lines', name='Down Line', line=dict(color='red')),
                go.Scatter(x=data.index, y=atr_high, mode='lines', name='ATR High', line=dict(color='green', dash='dash')),
                go.Scatter(x=data.index, y=atr_low, mode='lines', name='ATR Low', line=dict(color='red', dash='dash'))])

fig.update_layout(title=f'{ticker} Chart with Halftrend',
                  template='plotly_dark',
                  xaxis_title='Date',
                  yaxis_title='Price',
                  xaxis=dict(type='category', showgrid=False, tickmode='array',
                              tickvals=data.index[::len(data)//5],  # Adjust the frequency of ticks as needed
                              ticktext=data.index[::len(data)//5].strftime('%b %Y')),  # Format ticks as 'Jan 2022'
                  xaxis_rangeslider_visible=False,
                  yaxis=dict(showgrid=False))

fig.show()

Output

Rajandran R Creator of OpenAlgo Sketchmaker, RagZ. Building GenAI Applications. 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. Now the recent curiosity on building Trading AI Agents.

Leave a Reply

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