How to Change Wick Color in Pine Script: A Comprehensive Guide

Customizing the visual representation of candlesticks in TradingView’s Pine Script can significantly enhance chart analysis. Among these customizations, altering wick colors provides traders with nuanced visual cues about market sentiment and potential price action. This guide delves into various methods and advanced techniques for changing wick colors, tailored for intermediate to senior Pine Script developers.

Understanding Candlestick Components: Body vs. Wick

Before diving into customization, it’s essential to recall the anatomy of a candlestick. A candlestick consists of a body and wicks (also known as shadows or tails).

  • The body represents the range between the opening and closing prices for a given period. Its color typically indicates whether the price closed higher or lower than it opened.
  • The wicks extend from the body to the highest and lowest prices reached during the period. The upper wick shows the high relative to the body, and the lower wick shows the low relative to the body.

Why Customize Wick Colors? Use Cases and Benefits

Default wick colors often match the candle body or a neutral system color. Customizing wick colors offers several analytical advantages:

  • Highlighting Volatility and Rejection: Long wicks often signify price rejection at certain levels. Coloring these wicks differently can draw immediate attention to potential support/resistance zones or areas of supply/demand imbalance.
  • Identifying Specific Candlestick Patterns: Patterns like Dojis, Pin Bars (Hammers/Shooting Stars), or Marubozus can be made more prominent by assigning unique wick colors based on their formation criteria.
  • Signaling Momentum Shifts: Wick colors can be dynamically altered based on underlying momentum indicators (e.g., RSI, MACD) or volume analysis, providing early signals of potential trend changes or continuations.
  • Improving Visual Clarity: Custom wick colors can make charts less cluttered and more intuitive, allowing traders to process information faster, especially when dealing with multiple indicators or complex strategies.

Basic Syntax and Functions for Plotting Candlesticks in Pine Script

The primary function for plotting candlesticks in Pine Script is plotcandle(). Its basic syntax allows for specifying open, high, low, and close prices, along with colors for the body, border, and wicks.

// Pine Script v5
//@version=5
indicator("Basic Candle Plot", overlay=true)

plotcandle(open, high, low, close,
     title="Candles", 
     color = close > open ? color.new(color.green, 20) : color.new(color.red, 20),
     wickcolor = close > open ? color.new(color.green, 0) : color.new(color.red, 0),
     bordercolor = close > open ? color.green : color.red)

The wickcolor argument is key here. It accepts a series color, meaning its value can change dynamically on each bar based on specified conditions.

Methods for Changing Wick Color

Pine Script offers several approaches to modify wick colors, each with its own flexibility and complexity.

Method 1: Using ‘plotcandle’ with Conditional Wick Colors

This is the most straightforward method. The wickcolor argument of the plotcandle() function can be assigned a color based on logical conditions. This color applies to both the upper and lower wicks of a single candle.

// Pine Script v5
//@version=5
indicator("Conditional Wick Color - plotcandle", overlay=true)

// Condition: Wick color yellow if close is in the upper 25% of the candle's range, else default
candle_range = high - low
is_strong_close = candle_range > 0 and (close - low) / candle_range > 0.75

custom_wick_color = if is_strong_close
    color.new(color.yellow, 0)
else
    close > open ? color.new(color.green, 0) : color.new(color.red, 0)

plotcandle(open, high, low, close, 
     title="Conditional Wicks", 
     color=close > open ? color.new(color.green, 20) : color.new(color.red, 20), 
     wickcolor=custom_wick_color, 
     bordercolor=close > open ? color.green : color.red)

This method is efficient and usually sufficient for most common wick coloring needs.

Method 2: Deconstructing Candlesticks and Plotting Wicks Separately

For more granular control, such as applying different colors or conditions to upper and lower wicks independently, you might need to “deconstruct” the candlestick. This involves plotting the candle body and then overlaying the wicks using separate plotting functions like plotbar(). This method gives maximum flexibility but adds complexity.

Here’s how you could plot custom upper and lower wicks with potentially different colors:

// Pine Script v5
//@version=5
indicator("Separate Wick Plotting", overlay=true)

// Custom colors for wicks
cond_upper_wick_strong = high - math.max(open, close) > (high - low) * 0.5 // Upper wick is >50% of total range
cond_lower_wick_strong = math.min(open, close) - low > (high - low) * 0.5 // Lower wick is >50% of total range

user_upper_wick_color = cond_upper_wick_strong ? color.new(color.aqua, 0) : color.new(color.gray, 50)
user_lower_wick_color = cond_lower_wick_strong ? color.new(color.fuchsia, 0) : color.new(color.gray, 50)

// Plot candle body (make default wicks transparent or match body edge)
body_color = close > open ? color.new(color.green, 20) : color.new(color.red, 20)
plotcandle(open, high, low, close, 
     title="Body", 
     color=body_color, 
     wickcolor=color.new(body_color, 100), // Transparent wicks for the base candle
     bordercolor=body_color)

// Calculate body boundaries
body_high = math.max(open, close)
body_low = math.min(open, close)

// Plot Upper Wick as a thin bar
if high > body_high // Check if upper wick exists
    plotbar(open=body_high, high=high, low=body_high, close=high, 
         title="Upper Wick", 
         color=user_upper_wick_color)

// Plot Lower Wick as a thin bar
if low < body_low // Check if lower wick exists
    plotbar(open=body_low, high=body_low, low=low, close=low, 
         title="Lower Wick", 
         color=user_lower_wick_color)

In this approach, plotbar() is used to draw vertical lines representing the wicks. The open, high, low, and close arguments for plotbar are set to define a thin vertical segment.

Method 3: Utilizing ‘barcolor’ for Whole Bar Coloring, Including Wicks

The barcolor() function colors the entire bar, including its body and wicks, based on a specified condition. While it doesn’t allow for independent wick coloring distinct from the body, it can be used to emphasize entire candles that meet certain criteria, which inherently affects wick appearance.

// Pine Script v5
//@version=5
indicator("Bar Color Example", overlay=true)

// Condition: Color bar purple if volume is significantly above average
is_high_volume = volume > ta.sma(volume, 20) * 1.5

bar_highlight_color = is_high_volume ? color.new(color.purple, 70) : na

barcolor(bar_highlight_color, title="High Volume Bar Highlight")

// Standard candle plot for context
plotcandle(open, high, low, close, title="Candles", 
     wickcolor = close > open ? color.green : color.red)

This method is useful for highlighting specific bars entirely, where the wicks naturally adopt the applied barcolor.

Advanced Wick Color Customization Techniques

Beyond basic conditional coloring, Pine Script enables sophisticated wick customization.

Dynamic Wick Coloring Based on Volume or Price Action

Wick colors can be tied to real-time market data, such as trading volume or specific price action patterns relative to key levels (e.g., MAs, support/resistance).

  • Volume-Based Wicks: Color wicks differently if they formed on high volume, potentially indicating stronger conviction behind the rejection or absorption.
  • Price Action Context: Change wick color if it touches or pierces a significant moving average or a user-defined price level.
// Pine Script v5
//@version=5
indicator("Volume/PA Based Wicks", overlay=true)

sma20 = ta.sma(close, 20)
vol_avg = ta.sma(volume, 20)

wick_color_condition = na_color
if high > sma20 and low < sma20 // Wick pierces SMA20
    wick_color_condition := color.new(color.orange, 0)
else if volume > vol_avg * 2 // Wick formed on very high volume
    wick_color_condition := color.new(color.blue, 0)
else
    wick_color_condition := close > open ? color.new(color.green, 0) : color.new(color.red, 0)

plotcandle(open, high, low, close, wickcolor=wick_color_condition)

Highlighting Wicks That Meet Specific Criteria (e.g., long wicks)

Identifying and highlighting wicks of a certain proportional length (e.g., relative to body size or total candle range) can visually flag potential reversal signals like pin bars.

// Pine Script v5
//@version=5
indicator("Long Wick Highlighter", overlay=true)

candle_range = high - low
body_size = math.abs(open - close)
body_mid = (open + close) / 2

upper_wick_size = high - math.max(open, close)
lower_wick_size = math.min(open, close) - low

is_long_upper_wick = candle_range > 0 and upper_wick_size / candle_range > 0.6 and body_size / candle_range < 0.3
is_long_lower_wick = candle_range > 0 and lower_wick_size / candle_range > 0.6 and body_size / candle_range < 0.3

wick_highlight_color = if is_long_upper_wick or is_long_lower_wick
    color.new(color.yellow, 0)
else
    close > open ? color.new(color.green, 50) : color.new(color.red, 50)

plotcandle(open, high, low, close, wickcolor=wick_highlight_color)

Creating Wick Color Alerts and Visual Signals

Beyond just coloring, changes in wick characteristics can trigger alerts or plot distinct visual signals (shapes, arrows) on the chart.

// Pine Script v5
//@version=5
indicator("Wick Alerts & Signals", overlay=true)

// Using is_long_upper_wick, is_long_lower_wick from previous example
candle_range = high - low
body_size = math.abs(open - close)
upper_wick_size = high - math.max(open, close)
lower_wick_size = math.min(open, close) - low

is_long_upper_wick_criteria = candle_range > 0 and upper_wick_size / candle_range > 0.6 and body_size / candle_range < 0.3
is_long_lower_wick_criteria = candle_range > 0 and lower_wick_size / candle_range > 0.6 and body_size / candle_range < 0.3

wick_color = color.new(color.gray, 0)
if is_long_upper_wick_criteria
    wick_color := color.new(color.red, 0)
    plotshape(true, title="Long Upper Wick Signal", location=location.abovebar, color=color.red, style=shape.arrowdown, size=size.tiny)
    alertcondition(is_long_upper_wick_criteria, title="Long Upper Wick Alert", message="Long upper wick detected on {{ticker}} at {{close}}")
else if is_long_lower_wick_criteria
    wick_color := color.new(color.green, 0)
    plotshape(true, title="Long Lower Wick Signal", location=location.belowbar, color=color.green, style=shape.arrowup, size=size.tiny)
    alertcondition(is_long_lower_wick_criteria, title="Long Lower Wick Alert", message="Long lower wick detected on {{ticker}} at {{close}}")

plotcandle(open, high, low, close, wickcolor=wick_color)

Practical Examples and Code Snippets

Let’s consolidate these concepts with a few practical examples.

Example 1: Coloring Wicks Based on Bullish or Bearish Momentum

Wicks can be colored to reflect the closing price’s position within the candle’s total range, indicating intraday momentum.

// Pine Script v5
//@version=5
indicator("Momentum Wicks", overlay=true)

wick_mom_color = color.new(color.gray, 30) // Default
candle_range = high - low

if candle_range > 0
    close_position_in_range = (close - low) / candle_range
    if close_position_in_range > 0.66 // Close in upper third: bullish momentum
        wick_mom_color := color.new(color.teal, 0)
    else if close_position_in_range < 0.33 // Close in lower third: bearish momentum
        wick_mom_color := color.new(color.maroon, 0)

plotcandle(open, high, low, close, 
     title="Momentum Wicks",
     color = close > open ? color.new(color.green, 30) : color.new(color.red, 30),
     wickcolor=wick_mom_color,
     bordercolor= close > open ? color.green : color.red)

Example 2: Highlighting Doji Candlesticks by Wick Color

Doji candles signify indecision. Their wicks can be distinctively colored to make them stand out.

// Pine Script v5
//@version=5
indicator("Doji Wick Highlighter", overlay=true)

candle_range = high - low
body_abs = math.abs(open - close)

// Doji condition: Body is less than 10% of the total candle range
is_doji = candle_range > 0 and (body_abs / candle_range < 0.1)

doji_wick_color = is_doji ? color.new(color.blue, 0) : (close > open ? color.new(color.green,0) : color.new(color.red,0))

plotcandle(open, high, low, close, 
     title="Doji Wicks",
     color = is_doji ? color.new(color.silver, 30) : (close > open ? color.new(color.green, 30) : color.new(color.red, 30)),
     wickcolor = doji_wick_color,
     bordercolor = is_doji ? color.blue : (close > open ? color.green : color.red))

Example 3: Wick Color Changes Based on User-Defined Conditions

Provide flexibility by allowing users to input conditions and colors. This example focuses on a single external condition for simplicity.

// Pine Script v5
//@version=5
indicator("User Defined Wick Color", overlay=true)

// User Inputs
src_condition = input.source(close, "Condition Source")
cond_level = input.float(100, "Condition Level")
wick_true_color = input.color(color.new(color.orange, 0), "Wick Color if True")
wick_false_color = input.color(color.new(color.gray, 0), "Wick Color if False")

// Condition (example: source is above a certain level)
user_condition_met = src_condition > cond_level

final_wick_color = user_condition_met ? wick_true_color : wick_false_color

plotcandle(open, high, low, close, 
     title="User Wicks",
     wickcolor=final_wick_color)

This demonstrates using input.* functions to create a more configurable indicator.

Troubleshooting and Best Practices

When working with wick coloring, keep these points in mind for robust and efficient scripts.

Common Errors and How to Fix Them

  • na Color Issues: If your conditional logic for wickcolor results in na (not a number/value), Pine Script might revert to a default color or the candle body color. Ensure your conditions cover all cases or provide a default color explicitly.
    pinescript
    // Bad: might result in 'na' if condition is false
    // conditional_color = condition ? color.red : na
    // Better: provide a default
    conditional_color = condition ? color.red : color.gray
  • Logical Flaws in Conditions: Complex conditions can easily harbor bugs. Test each part of your logic separately. Use plotchar() or bgcolor() to visualize intermediate boolean states during debugging.
  • plotcandle() Parameter Order: Ensure the open, high, low, close arguments are in the correct order. Incorrect order will lead to distorted candle shapes.
  • Over-plotting Issues with Method 2: When deconstructing candles and plotting wicks separately, ensure your base plotcandle() call either uses transparent wicks (color.new(..., 100)) or wicks that will be appropriately covered by your custom wick plots. Otherwise, you might see overlapping or conflicting wick colors.

Optimizing Your Code for Performance

  • Minimize Calculations in Series: Avoid redundant calculations that are performed on every bar for every series argument. Calculate values once per bar if possible.
    pinescript
    // Less optimal: RSI calculated twice
    // plotcandle(..., wickcolor = ta.rsi(close,14) > 70 ? color.red : (ta.rsi(close,14) < 30 ? color.green : color.gray))
    // Better:
    rsi_val = ta.rsi(close, 14)
    plotcandle(..., wickcolor = rsi_val > 70 ? color.red : (rsi_val < 30 ? color.green : color.gray))
  • Use var for Initialization: For variables that need to maintain state across bars but are only initialized once or under specific conditions, use the var keyword to prevent re-initialization on every bar.
  • Conditional Plotting: If using Method 2 (separate wick plotting), wrap plotbar() calls in if conditions to avoid plotting invisible or zero-length wicks unnecessarily, which can improve performance slightly on charts with many bars.
  • Avoid Unnecessary security() Calls: If conditions for wick colors involve data from other timeframes via security(), be mindful of its performance implications and potential for repainting if not handled carefully.

Tips for Readable and Maintainable Code

  • Descriptive Variable Names: Use names like isLongUpperWick or momentumBasedWickColor instead of generic names like c1 or wick_col.

  • Functions for Complex Logic: Encapsulate complex conditional logic for determining wick colors into user-defined functions. This improves readability and reusability.

    // Pine Script v5
    getWickHighlightColor(float highVal, float lowVal, float openVal, float closeVal) =>
        candle_range = highVal - lowVal
        body_size = math.abs(openVal - closeVal)
        upper_wick_size = highVal - math.max(openVal, closeVal)
        is_long_upper = candle_range > 0 and upper_wick_size / candle_range > 0.6 and body_size / candle_range < 0.3
        is_long_upper ? color.new(color.yellow, 0) : color.new(color.gray, 50)
    
    // ... in plotcandle ...
    // wickcolor = getWickHighlightColor(high, low, open, close)
    
  • Comments for Clarity: Explain non-obvious parts of your logic, especially for complex conditions or custom calculations.

  • Consistent Formatting: Adhere to Pine Script’s formatting conventions or establish your own team/personal style for indentation and spacing to make code easier to scan.

By mastering these techniques for changing wick colors, you can create more insightful and visually appealing trading indicators and strategies in Pine Script, ultimately aiding in more informed decision-making.


Leave a Reply