← Back to Home
Enhanced Volume Profile Strategy Backtest UNH 29.51% Return With 6.79% Max Drawdown

Enhanced Volume Profile Strategy Backtest UNH 29.51% Return With 6.79% Max Drawdown

Get the full strategy library: This article uses one strategy from the Mega Backtrader Strategy Pack, a package of 500+ Backtrader-ready Python trading strategies with batch backtesting, dashboards, metrics, charts, and documentation.

Download the package here: Mega Backtrader Strategy Pack

If you want to test complete Backtrader strategies without building every idea from scratch, the package gives you strategy code, batch runners, metrics, charts, and publishable reports in one workflow.

Volume profile strategies look at where trading activity happened, not only where price closed. The idea is that high-volume price zones can become important reference areas. Price can reject them, rotate around them, or break away from them.

This article walks through EnhancedVolumeProfileStrategy, one of the strategies included in the Mega Backtrader Strategy Pack. The strategy was tested on UNH daily candles from June 20, 2025 to June 18, 2026, with SPY used as the benchmark.

The result:

Result Value
Strategy return 29.51%
UNH buy-and-hold return 32.76%
SPY benchmark return 25.65%
Excess return vs SPY 3.85%
Sharpe ratio 2.06
Max drawdown 6.79%
Closed trades 8
Open trades 0
Win rate 62.50%

This is a clean example because the run ended with 8 closed trades and no open position. The strategy finished ahead of SPY with a controlled maximum drawdown of 6.79%.

Strategy Idea

EnhancedVolumeProfileStrategy builds a rolling volume profile from recent bars, finds the highest-volume price area, calculates the value area, and then uses those levels as trade context.

The strategy focuses on four market concepts:

  1. VPOC: the volume point of control, or the price level with the most weighted volume.
  2. Value area: the price zone that contains most of the profile's weighted volume.
  3. Breakout and pullback: price breaking beyond value area, then pulling back before confirmation.
  4. Volume confirmation: trades require current volume to exceed recent average volume.

This makes the system different from a simple price-only strategy. It asks where volume concentrated first, then decides whether current price action is interacting with those levels in a tradable way.

Strategy Parameters

The strategy exposes its behavior through Backtrader params:

params = (
    ('profile_period', 30),
    ('signal_period', 7),
    ('value_area_pct', 80),
    ('price_bins', 30),
    ('smooth_bins', 3),
    ('atr_period', 14),
    ('vpoc_atr_mult', 1.0),
    ('va_atr_mult', 0.6),
    ('decay_factor', 0.95),
    ('volume_confirm_mult', 1.2),
    ('trend_period', 30),
    ('pullback_bars', 3),
    ('trail_stop_pct', 0.02),
)

These settings control:

Code Walkthrough

The strategy stores price and volume lines and builds a few core indicators:

self.high = self.data.high
self.low = self.data.low
self.close = self.data.close
self.volume = self.data.volume

self.atr = bt.indicators.ATR(period=self.params.atr_period)
self.trend_ma = bt.indicators.SMA(period=self.params.trend_period)
self.volume_ma = bt.indicators.SMA(self.volume, period=self.params.signal_period)

ATR is used to adapt thresholds. The trend moving average gives directional context. The volume moving average is used to confirm whether current volume is meaningful.

The strategy updates adaptive thresholds from ATR:

if not np.isnan(self.atr[0]) and self.atr[0] > 0:
    self.vpoc_threshold = (self.atr[0] / self.close[0]) * self.params.vpoc_atr_mult
    self.va_threshold = (self.atr[0] / self.close[0]) * self.params.va_atr_mult
else:
    self.vpoc_threshold = 0.005
    self.va_threshold = 0.003

This is important because a fixed price threshold can be too wide in quiet markets and too narrow in volatile markets. ATR makes the level tests scale with current conditions.

The volume profile gives more weight to recent bars through exponential decay:

weight = self.params.decay_factor ** i

Older bars still matter, but recent volume has more influence. That helps the profile adapt as market structure changes.

The profile is built by distributing each bar's weighted volume across its high-low range:

for level in range(num_levels):
    price_level = bar_low + (level * (bar_high - bar_low) / num_levels)
    price_bin = int((price_level - min_price) / price_step)
    binned_price = min_price + price_bin * price_step
    raw_profile[binned_price] += volume_per_level

After the raw profile is created, the strategy smooths nearby bins:

for i in range(0, len(prices), self.params.smooth_bins):
    bin_prices = prices[i:i + self.params.smooth_bins]
    total_volume = sum(profile[p] for p in bin_prices)
    weighted_price = sum(p * profile[p] for p in bin_prices) / total_volume
    smoothed[weighted_price] = total_volume

That reduces noise. Instead of reacting to tiny adjacent volume differences, the strategy groups neighboring price levels into cleaner zones.

The VPOC is the price level with the most volume:

for price, volume in self.volume_profile.items():
    if volume > max_volume:
        max_volume = volume
        vpoc_price = price

self.vpoc = vpoc_price

The value area is calculated by sorting levels by volume and accumulating them until the target percentage is reached:

target_volume = self.total_profile_volume * (self.params.value_area_pct / 100)
accumulated_volume = 0
va_levels = []

for price, volume in sorted_levels:
    accumulated_volume += volume
    va_levels.append(price)

    if accumulated_volume >= target_volume:
        break

The highest and lowest selected price levels become the value area high and value area low.

The strategy then classifies current price relative to these profile levels:

if vah_distance <= self.va_threshold:
    return 'vah', vah_distance
elif val_distance <= self.va_threshold:
    return 'val', val_distance

It also identifies whether price is inside, above, or below the value area.

Volume confirmation is required before trades:

return self.volume[0] > self.volume_ma[0] * self.params.volume_confirm_mult

This helps avoid taking signals when the market is interacting with a level but volume is too quiet to confirm participation.

The breakout logic waits for a pullback instead of chasing the first break:

if current_price > self.value_area_high * (1 + self.va_threshold):
    if not self.waiting_for_pullback:
        self.breakout_type = 'above_va'
        self.breakout_bar = len(self.data)
        self.waiting_for_pullback = True
        return None

Only after enough bars have passed and price pulls back toward the breakout area does the strategy confirm the signal:

if len(self.data) - self.breakout_bar >= self.params.pullback_bars:
    self.waiting_for_pullback = False
    return 'confirmed_breakout_above'

Finally, the strategy uses a 2% trailing stop after entry:

new_trail_stop = current_price * (1 - self.params.trail_stop_pct)
if new_trail_stop > self.trail_stop_price:
    self.cancel(self.stop_order)
    self.trail_stop_price = new_trail_stop
    self.stop_order = self.sell(exectype=bt.Order.Stop, price=self.trail_stop_price)

That gives the position room to move while still protecting gains as price advances.

Backtest Setup

The run used the package batch backtester with these settings:

Setting Value
Asset UNH
Benchmark SPY
Period 1y
Data window June 20, 2025 to June 18, 2026
Interval 1d
Starting cash $10,000
Final value $12,950.51
Strategy file EnhancedVolumeProfileStrategy.py
Strategy class EnhancedVolumeProfileStrategy
Execution mode Long-only batch run

The package generated the metrics table, equity curve, benchmark comparison, drawdown chart, rolling return chart, and daily return distribution automatically.

Results

Metric Value
Starting portfolio value $10,000.00
Final portfolio value $12,950.51
Strategy return 29.51%
UNH buy-and-hold return 32.76%
SPY benchmark return 25.65%
Excess return vs SPY 3.85%
Excess return vs UNH buy-hold -3.26%
Sharpe ratio 2.06
Max drawdown 6.79%
Total trades 8
Closed trades 8
Open trades 0
Winning trades 5
Losing trades 3
Win rate 62.50%
Runtime 3.39 seconds

The strategy finished ahead of SPY and kept drawdown below 7%. UNH buy-and-hold finished slightly higher, but the strategy delivered a smoother controlled-risk profile with only 8 completed trades.

Equity Curve vs Benchmark

Enhanced Volume Profile UNH equity curve versus SPY benchmark

The equity curve shows the strategy growing from $10,000 to $12,950.51.

Drawdown vs Benchmark

Enhanced Volume Profile UNH drawdown versus SPY benchmark

The drawdown chart shows maximum strategy drawdown at 6.79%, which is the strongest part of this case study.

Rolling Return vs Benchmark

Enhanced Volume Profile UNH rolling return versus SPY benchmark

The rolling return chart shows how performance developed across the test window rather than relying only on the final return number.

Daily Return Distribution

Enhanced Volume Profile UNH daily returns histogram

The daily return distribution excludes zero-return strategy days. In this run, 192 flat strategy-equity days were removed from the histogram, leaving 58 non-zero strategy return days plotted.

What This Shows

This volume-profile example is useful because it demonstrates a different kind of strategy logic.

Many trading systems start with price momentum. This one starts with market structure:

  1. Where did volume concentrate?
  2. Where is the value area?
  3. Is price near VPOC, value area high, or value area low?
  4. Did price break out and pull back?
  5. Is volume strong enough to confirm the signal?

That makes it a good example of why a broad Backtrader strategy library is useful. The package is not limited to one type of signal. It includes trend, momentum, mean reversion, volatility, volume, machine learning, and hybrid approaches.

Get the Complete Strategy Library

EnhancedVolumeProfileStrategy is one of 500+ Backtrader-ready strategies included in the Mega Backtrader Strategy Pack.

Get the full package here: Mega Backtrader Strategy Pack

The package includes:

If you want to test more strategy ideas faster, this package gives you the code and the research workflow.

Get the Mega Backtrader Strategy Pack

Disclaimer

This article is for research and educational use only. Backtest results are not financial advice, investment advice, or a guarantee of future performance. Always validate strategy logic, data quality, execution assumptions, costs, slippage, and risk before using any trading system.