← Back to list

Automating Fair Value Gaps (FVG) in Python

Automating indicators in Python is simple and straightforward. Once you get the algorithmic idea it’s easy to translate it into a coding…

Ziad Francis, PhD · 2025-08-30 14:39 · 37 claps · 5.8 min read
#algorithmic-trading #trading-strategy #fair-value-gap #smart-money-concept #trading-bot
Open on Medium ↗
Wiki topics: ECO · Economy · General 💻 · Programming

Automating Fair Value Gaps (FVG) in Python

Automating indicators in Python is simple and straightforward. Once you get the algorithmic idea it’s easy to translate it into a coding language, I would say any language. This bot is capable of detecting FVG automatically saving you the hustle of waiting behind screens and taking measurements all the time.

Fair Value Gap areas/zones automatically detected in Python

Fair Value Gap areas/zones automatically detected in Python

Introduction

In modern trading, market inefficiencies are often where the real opportunities lie. One of the most popular price action concepts that highlights these inefficiencies is the Fair Value Gap (FVG). This pattern, derived from institutional order flow theory, occurs when price moves so quickly that it leaves behind an imbalance, essentially a gap that the market may later revisit.

Traders use FVGs as potential areas of support or resistance, often anticipating that price will return to “fill” the gap before resuming its trend. While identifying these gaps manually on charts can be time-consuming, the real power comes when we automate their detection with Python and integrate them directly into our algorithmic trading strategies.

In this article, I’ll walk you through:

  • A quick refresher on what defines a Fair Value Gap and why institutions leave them behind.
  • How to translate this price action concept into Python code, detecting bullish and bearish FVGs automatically.
  • Practical insights on how these detected gaps can be integrated into trading systems for systematic entries, exits, and confluence with other strategies.

By the end, you will understand how FVGs work, but you’ll also have a ready-to-use Python implementation that you can adapt and extend to your own trading strategies.

What Defines a Fair Value Gap…Briefly

A Fair Value Gap (FVG) is a three-candle price pattern that highlights an imbalance in the market. It occurs when price moves so aggressively in one direction that it leaves behind a portion of price action “untraded.”

  • Candle 1 (Initial Move): Establishes the starting high and low.
  • Candle 2 (Momentum Candle): A strong move in one direction, creating a displacement in price.
  • Candle 3 (Reference Candle): Fails to fully retrace into Candle 1’s range, leaving behind a gap.

The gap itself is the zone between Candle 1’s high and Candle 3’s low (for bullish FVGs), or between Candle 1’s low and Candle 3’s high (for bearish FVGs).

So why does this matter? Fair Value Gaps often reflect (or is believed to reflect…) how institutional players; banks, funds, or large liquidity providers, place orders. When price rushes in one direction, not all orders are filled. This leaves “inefficient” areas where the market may later return to collect liquidity and rebalance price action.

Traders interpret these zones as areas of interest because:

  • Price often retraces into the gap before resuming the original move.
  • FVGs can act as dynamic support or resistance levels.
  • They highlight institutional footprints, giving retail traders a way to align with larger market flows.

In other words, FVGs are not just chart patterns, they’re signals of market inefficiency and potential opportunities where price might revisit.

One single function FVG detector !

Now that we understand the concept of Fair Value Gaps, let’s translate it into Python code. Below is a simple function that automatically detects both bullish and bearish FVGs in historical OHLC data.

def detect_fvg(data, lookback_period=10, body_multiplier=1.5):
    """
    Detects Fair Value Gaps (FVGs) in historical price data.

    Parameters:
        data (DataFrame): DataFrame with columns ['open', 'high', 'low', 'close'].
        lookback_period (int): Number of candles to look back for average body size.
        body_multiplier (float): Multiplier to determine significant body size.

    Returns:
        list of tuples: Each tuple contains ('type', start, end, index).
    """
    fvg_list = [None, None]

    for i in range(2, len(data)):
        first_high = data['High'].iloc[i-2]
        first_low = data['Low'].iloc[i-2]
        middle_open = data['Open'].iloc[i-1]
        middle_close = data['Close'].iloc[i-1]
        third_low = data['Low'].iloc[i]
        third_high = data['High'].iloc[i]

        # Calculate the average absolute body size over the lookback period
        prev_bodies = (data['Close'].iloc[max(0, i-1-lookback_period):i-1] - 
                       data['Open'].iloc[max(0, i-1-lookback_period):i-1]).abs()
        avg_body_size = prev_bodies.mean()

        # Ensure avg_body_size is nonzero to avoid false positives
        avg_body_size = avg_body_size if avg_body_size > 0 else 0.001

        middle_body = abs(middle_close - middle_open)

        # Check for Bullish FVG
        if third_low > first_high and middle_body > avg_body_size * body_multiplier:
            fvg_list.append(('bullish', first_high, third_low, i))

        # Check for Bearish FVG
        elif third_high < first_low and middle_body > avg_body_size * body_multiplier:
            fvg_list.append(('bearish', first_low, third_high, i))

        else:
            fvg_list.append(None)

    return fvg_list

This function scans historical OHLC price data and highlights where Fair Value Gaps (FVGs) occur. Here’s how it works step by step:

Inputs:

  • A DataFrame with candlestick data (Open, High, Low, Close).
  • A lookback_period to calculate the average body size of recent candles.
  • A body_multiplier to ensure the middle candle is strong enough to signal real displacement.

The input DataFrame has to have Open, High, Low and Close columns, just like this example:

Example dataframe, hourly timeframe EURUSD data

Example dataframe, hourly timeframe EURUSD data

Then the function will test for Three-Candle Structure following these conditions:

  • Candle 1 (i-2): Provides the reference high and low.
  • Candle 2 (i-1): The momentum candle , its body size is compared against the average to confirm a strong move.
  • Candle 3 (i): The reference candle, checks if it leaves a gap relative to Candle 1.

Then we also test for the Gap following these rules:

  • Bullish FVG: If Candle 3’s low stays above Candle 1’s high, and Candle 2 had a strong bullish body.
  • Bearish FVG: If Candle 3’s high stays below Candle 1’s low, and Candle 2 had a strong bearish body.

The function returns a list where each element is either:

  • None (no gap found), or
  • A tuple like ('bullish', start_level, end_level, index) describing the gap.

The results can actually be saved in a new column added to the DataFrame, for example clalling the function:

df['FVG'] = detect_fvg(df)
df.head(20)

The updated DataFrame now includes an additional column that flags potential gaps. For each candle (row), whenever a Fair Value Gap is detected, the stored tuple specifies:

  • whether the gap is bullish or bearish,
  • the price levels that define the gap, and
  • the index of the candle where it occurred.

This structured information makes it easy to later visualize the gaps directly on a chart or integrate them into backtesting and strategy logic.

The output DataFrame now looks like the following:

DataFrame with the FVG computed signal

DataFrame with the FVG computed signal

In short, the function automates the manual chart pattern definition: it looks for three consecutive candles forming an imbalance, and it filters out weak setups by requiring a momentum candle larger than average.

Visualizing FVG on the price chart

Once the gaps are detected, the next step is to plot them directly on the chart so we can see how they align with price action. Using Plotly’s interactive candlestick charts makes this very straightforward:

We first select a slice of data (dfpl) to keep the chart clean and focused.

The candlestick trace shows the normal OHLC price movement.

Then, for every row that contains an FVG tuple, we draw a rectangle (zone):

  • Green for bullish gaps (areas where price may revisit on the way up).
  • Red for bearish gaps (areas where price may revisit on the way down).

Each rectangle extends from the gap boundaries (start to end) and projects forward in time so we can see how future candles interact with the zone.

The result is an interactive chart where institutional imbalances are highlighted as colored zones , making it easy to visually confirm where price revisits these areas.

Conclusion

And this is it! you don’t have to wait in front of the screen and take measurments to detect FVG gaps, a simple bot using parts of this code can save you the waiting time. Now whether this indicator is worth it for trading, there only one way to find out, and that’s through a full backtest.

Of course, no signal is perfect. While price often revisits these gap zones, it can either bounce from them or break straight through. At that stage, there’s no reliable way to predict direction solely from the FVG itself, which is why relying only on these levels isn’t a practical trading approach.

Enjoy coding!

If you’d like a more detailed walkthrough with backtests and live coding, you can check out the full video explanation , along with the code download link, on my YouTube channel. Feel free to drop by anytime!

[embed]


메타데이터
post_id
0768d3f382e6
slug
automating-fair-value-gaps-fvg-in-python-0768d3f382e6
url
https://medium.com/@ziad.francis/automating-fair-value-gaps-fvg-in-python-0768d3f382e6
canonical_url
https://medium.com/@ziad.francis/automating-fair-value-gaps-fvg-in-python-0768d3f382e6
author_url
https://medium.com/@ziad.francis
status
ok
fetched_at
2026-06-21 07:44:09