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
naColor Issues: If your conditional logic forwickcolorresults inna(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()orbgcolor()to visualize intermediate boolean states during debugging. plotcandle()Parameter Order: Ensure theopen, high, low, closearguments 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
varfor Initialization: For variables that need to maintain state across bars but are only initialized once or under specific conditions, use thevarkeyword to prevent re-initialization on every bar. - Conditional Plotting: If using Method 2 (separate wick plotting), wrap
plotbar()calls inifconditions 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 viasecurity(), 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
isLongUpperWickormomentumBasedWickColorinstead of generic names likec1orwick_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.