Pine Script Ulcer Index

Master this unique risk measure in TradingView's Pine Script that quantifies the depth and duration of price drawdowns, helping you assess the 'pain' of an investment.

Subscribe now @ $99/month

What is the Ulcer Index?

The Ulcer Index (UI) is a risk measure developed by Peter Martin in 1987. Unlike traditional volatility measures like standard deviation, the Ulcer Index focuses specifically on downside volatility and the depth and duration of drawdowns. It quantifies the "pain" an investor experiences from price declines. A higher Ulcer Index indicates greater and longer-lasting drawdowns, implying higher risk or discomfort. A lower Ulcer Index suggests more stable performance with less significant or persistent declines.

The Ulcer Index is particularly valuable in portfolio management and for assessing risk-adjusted returns, as it provides a clearer picture of the downside risk faced by a trader or investor. It helps identify assets that might offer good returns but at the cost of severe or prolonged drawdowns.

Components and Calculation

The calculation of the Ulcer Index involves a few steps:

  1. Percentage Drawdown (PD): For each period, calculate the percentage that the current price is below the highest price reached in the lookback period (the "peak").
    `PD = ((Current Close - Highest Close in 'length' period) / Highest Close in 'length' period) * 100`
    Note: PD is always negative or zero.
  2. Squared Percentage Drawdown: Square the PD values. This emphasizes larger drawdowns.
    `Squared PD = PD * PD`
  3. Average of Squared PD: Calculate the average of these squared PD values over the specified `length` (e.g., 14 periods).
    `Avg_Squared_PD = SMA(Squared PD, length)`
  4. Ulcer Index Formula: Take the square root of the `Avg_Squared_PD`.
    `Ulcer Index = math.sqrt(Avg_Squared_PD)`

A common `length` for the Ulcer Index is 14 periods, but it can be adjusted to suit different analysis timeframes.

Basic Ulcer Index (UI) Implementation in Pine Script

Pine Script v5 provides a convenient built-in function `ta.ui()` for calculating the Ulcer Index.


//@version=5
indicator("My Ulcer Index", overlay=false) // overlay=false to plot in a separate pane

// Input for Ulcer Index length
length = input.int(14, title="UI Length", minval=1)

// Calculate Ulcer Index using the built-in function
// ta.ui implicitly uses 'close' as source and the provided length
ulcerIndexValue = ta.ui(length)

// Plot the Ulcer Index line
plot(ulcerIndexValue, title="Ulcer Index", color=color.orange, linewidth=2)

// Optional: Add reference levels for visual clarity
// These levels are subjective and depend on asset/risk tolerance.
// Lower values are generally better (less "ulcer-inducing" risk).
hline(2.0, "High Risk Ref", color=color.red, linestyle=hline.style_dashed)
hline(0.5, "Low Risk Ref", color=color.green, linestyle=hline.style_dashed)

Focus on Drawdown: The Ulcer Index is unique because it quantifies risk based specifically on the depth and persistence of drawdowns, giving a tangible measure of investment pain.

Practical Ulcer Index Trading Strategies

1. Portfolio Risk Assessment and Asset Comparison

The primary use of the Ulcer Index is for comparing the drawdown risk of different assets or strategies, and for assessing the overall risk of a portfolio.


//@version=5
indicator("Ulcer Index for Risk Comparison", overlay=false)

length = input.int(14, title="UI Length", minval=1)
ulcerIndexValue = ta.ui(length)

plot(ulcerIndexValue, "Ulcer Index", color=color.orange, linewidth=2)

// Example: Display current Ulcer Index on chart
if barstate.islast
    label.new(bar_index, ulcerIndexValue, "UI: " + str.tostring(ulcerIndexValue, "#.##"), 
     style=label.style_label_down, color=color.blue, textcolor=color.white)

// You'd typically use this for comparative analysis across different symbols or strategy runs
// rather than direct buy/sell signals on a single chart.
// Consider combining this with a custom screener or a script that plots multiple UIs.

2. Risk-Adjusted Entry/Exit Signals (Contextual)

While not a direct buy/sell signal generator, the Ulcer Index can provide context for trading decisions. For example, some traders might prefer to enter trades when the Ulcer Index is relatively low, suggesting less recent downside risk.


//@version=5
strategy("Ulcer Index Risk-Adjusted Strategy", overlay=true)

length = input.int(14, title="UI Length", minval=1)
ulcerIndexValue = ta.ui(length)

plot(ulcerIndexValue, "Ulcer Index", color=color.orange, display=display.pane_only)
hline(0.5, "Low UI Threshold", color=color.green, linestyle=hline.style_dashed, display=display.pane_only)
hline(1.5, "High UI Threshold", color=color.red, linestyle=hline.style_dashed, display=display.pane_only)

// Simple trend filter for entries
emaFast = ta.ema(close, 10)
emaSlow = ta.ema(close, 20)
isUptrend = emaFast > emaSlow and emaFast[1] <= emaSlow[1] // Bullish crossover

// Long Entry Condition: Bullish crossover AND UI is relatively low
longCondition = isUptrend and ulcerIndexValue < 0.7 // Example threshold

// Short Exit Condition: UI rises above a certain point, indicating increased drawdown
shortExitCondition = ulcerIndexValue > 1.0 and strategy.position_size > 0 // Exit if UI is high and we are long

if (longCondition)
    strategy.entry("Long (Low UI)", strategy.long)

if (shortExitCondition)
    strategy.close("Long (Low UI)", comment="High UI Exit")

// You would add more sophisticated exit rules (e.g., trend reversal, stop loss)
// and consider short entries when appropriate (e.g., downtrend + high UI)

3. Ulcer Index Divergence (Less Common)

While not its primary function, divergence between price and the Ulcer Index can sometimes offer insights, though interpretation requires care.


//@version=5
indicator("Ulcer Index Divergence", overlay=true)

length = input.int(14, title="UI Length", minval=1)
ulcerIndexValue = ta.ui(length)

plot(ulcerIndexValue, "Ulcer Index", color=color.orange)
hline(0.5, "Low UI Ref", color=color.green, linestyle=hline.style_dashed)
hline(1.5, "High UI Ref", color=color.red, linestyle=hline.style_dashed)

// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This is a simplified example focusing on price vs UI divergence.

// Bullish Divergence (Price lower low, UI lower high / stable)
// Price makes lower low, UI shows less "pain"
bullishDivergence = close < close[1] and close[1] < close[2] and ulcerIndexValue > ulcerIndexValue[1] and ulcerIndexValue[1] > ulcerIndexValue[2]

// Bearish Divergence (Price higher high, UI higher low / increasing "pain")
// Price makes higher high, UI shows more "pain"
bearishDivergence = close > close[1] and close[1] > close[2] and ulcerIndexValue < ulcerIndexValue[1] and ulcerIndexValue[1] < ulcerIndexValue[2]

plotshape(bullishDivergence, title="Bullish UI Divergence", location=location.belowbar, color=color.blue, style=shape.diamond, size=size.small)
plotshape(bearishDivergence, title="Bearish UI Divergence", location=location.abovebar, color=color.fuchsia, style=shape.diamond, size=size.small)

alertcondition(bullishDivergence, "Bullish UI Divergence", "Ulcer Index indicating potential bullish sentiment shift.")
alertcondition(bearishDivergence, "Bearish UI Divergence", "Ulcer Index indicating potential bearish sentiment shift.")

Optimizing Ulcer Index Performance

To get the most from the Ulcer Index in Pine Script:

Beyond Volatility: While traditional volatility measures treat all price fluctuations equally, the Ulcer Index specifically penalizes drawdowns, making it a more intuitive measure of the "pain" associated with an investment.

Common Ulcer Index Pitfalls

Conclusion

The Ulcer Index is a valuable and distinct technical indicator available in Pine Script for TradingView, offering a unique perspective on market risk by quantifying the depth and duration of price drawdowns. Unlike traditional volatility measures, it directly addresses the "pain" associated with investment declines, making it particularly useful for portfolio management and assessing risk tolerance. While not a directional signal generator, its ability to highlight periods of significant downside risk or stability provides crucial context for trading decisions. By understanding its calculation, thoughtfully tuning its parameters, and integrating it strategically with directional indicators and robust risk management practices, you can leverage the Ulcer Index to make more informed and risk-aware trading decisions.

Enhance Your Trading

Get a high-performance Pine Script analysis tool for actionable market insights, designed for traders on the move.

This strategy runs in live mode on TradingView, helping you identify potential opportunities.

Subscribe now @ $99/month