Skip to content
ChartDeck ChartScript docs Account Open the terminal

Colors

Theme colors that follow the chart's look, named colors, hex literals, color.new and transparency, rgb, gradients, palettes and per-theme colors.

Every output a script draws has a color: plots, fills, levels, shapes, backgrounds, labels and tables. This page explains the ways to write a color, how transparency works, and how to make a script look right on a dark chart, a light chart and the accessible looks ChartDeck offers.

The short version: prefer the theme colors (color.up, color.down, color.accent, color.muted, color.text, color.grid). They follow the chart's look automatically, so your script never ends up with dark-gray text on a dark background.

#Theme colors

Theme colors are a ChartScript feature. They are not fixed RGB values: each one names a role, and the chart fills in the actual color from its current look (dark, light, high contrast or color-blind friendly).

ConstantRole
color.upRising things: bullish candles, positive values, buy signals
color.downFalling things: bearish candles, negative values, sell signals
color.accentThe main line of an indicator; a highlight
color.mutedSecondary lines, guides, levels
color.textText that must be readable on the chart background
color.gridSubtle structure, the color of the chart's grid
ChartScriptOpen in editor
//@chartscript 1
indicator("Theme-aware MACD", { overlay: false })
const fastLine = ta.ema(close, 12)
const slowLine = ta.ema(close, 26)
const macd = fastLine - slowLine
const signal = ta.ema(macd, 9)
const hist = macd - signal

plot(hist, "Histogram", hist >= 0 ? color.new(color.up, 40) : color.new(color.down, 40), { style: plot.style_columns })
plot(macd, "MACD", color.accent, 2)
plot(signal, "Signal", color.muted)
hline(0, "Zero", color.grid)

Switch the chart between dark and light and every color above adjusts, with no change to the script and no re-run. Someone who uses the color-blind look gets their own up and down colors too. That is why the official scripts use theme colors almost everywhere.

chart.bg_color and chart.fg_color are theme colors as well: the chart's background and its text color.

#Series colors

Four more theme colors are the chart's series colors, the ones ChartDeck's built-in indicators draw with (an EMA in amber, VWAP in cyan, order blocks in cyan and magenta, Fibonacci levels in violet):

ConstantBuilt-in indicators that use it
color.amberMoving averages, pivot points (P), the zigzag, the point of control
color.magentaThe anchored VWAP, bearish order blocks, the New York session
color.cyanVWAP, bullish order blocks, the London session
color.violetThe regression channel's bands, the Fibonacci levels, inverse fair value gaps

Like the role colors, each one follows the chart's look: the light theme and the color-blind look have their own amber, magenta, cyan and violet, chosen to stay apart from each other and from up and down. Use them when a line should look like it belongs with ChartDeck's own indicators:

ChartScriptOpen in editor
//@chartscript 1
indicator("Daily VWAP", { overlay: true })
plot(ta.vwap(hlc3, timeframe.change("1D")), "VWAP", color.cyan, 2)

#Named colors

For a specific hue, use one of the named colors:

color.aquacolor.blackcolor.bluecolor.fuchsia
color.graycolor.greencolor.limecolor.maroon
color.navycolor.olivecolor.orangecolor.purple
color.redcolor.silvercolor.tealcolor.white
color.yellow

Named colors are fixed: color.blue is the same blue on every chart. Use them for lines that need to be told apart (a fast average in aqua, a slow one in orange) and leave meaning ("up", "down", "secondary") to the theme colors. The reference lists the exact hex value of each.

#Hex literals

You can write any color as a hex literal: #RRGGBB, or #RRGGBBAA with an alpha byte at the end. Alpha FF is opaque and 00 is invisible, so #FF990080 is orange at about half strength.

ChartScriptFragmentOpen in editor
plot(ta.sma(close, 20), "SMA", #FFC857, 2)
plot(ta.sma(close, 50), "SMA 50", #4FC3F780, 2)

#Transparency

Most of the time you want a color you already have, made see-through. color.new does exactly that:

color.new(color, transp)

transp runs from 0 (opaque) to 100 (invisible). It is the opposite of opacity: higher means fainter.

transpTypical use
0Main lines, markers
30 to 60Secondary lines, histogram bars that should not shout
80 to 95Fills and backgrounds behind price
100Invisible (rarely needed: na is clearer)

color.new keeps a theme color a theme color, so color.new(color.up, 80) is a faint "up" that still follows the chart's look.

ChartScriptOpen in editor
//@chartscript 1
indicator("Faded history", { overlay: true })
const len = input.int(50, "Length", { minval: 1 })
const avg = ta.sma(close, len)
// the line is strong on the newest bars and fades for older ones
const age = last_bar_index - bar_index
plot(avg, "Average", color.new(color.accent, math.min(80, age / 3)), 2)

color.t reads a color's transparency back (0 to 100).

#Building colors from numbers

color.rgb makes a color from red, green and blue (each 0 to 255) and an optional transparency:

ChartScriptFragmentOpen in editor
const rsi = ta.rsi(close, 14)
// redder as the RSI rises, greener as it falls
plot(rsi, "RSI", color.rgb(255 * rsi / 100, 255 * (1 - rsi / 100), 80), 2)

color.r, color.g and color.b take a color apart again. On a theme color they return the components of the color the current theme uses.

#Gradients

color.from_gradient picks a color between two others according to where a value sits in a range:

color.from_gradient(value, bottom_value, top_value, bottom_color, top_color)

At or below bottom_value you get bottom_color; at or above top_value, top_color; in between, a smooth blend. This is the easiest way to show strength rather than just direction.

ChartScriptOpen in editor
//@chartscript 1
indicator("RSI heat", { overlay: false })
const rsi = ta.rsi(close, 14)
const heat = color.from_gradient(rsi, 30, 70, color.down, color.up)
plot(rsi, "RSI", heat, 3)
hline(70, "Upper", color.muted, hline.style_dashed)
hline(30, "Lower", color.muted, hline.style_dashed)

To shade the inside of a fill from one color to another vertically, use the gradient form of fill instead; see Fills.

#A color for each theme

Sometimes a theme role does not fit and a single fixed color will not do either: a gold line that must be bright on a dark chart and deeper on a light one. color.theme takes one color per chart theme:

ChartScriptOpen in editor
//@chartscript 1
indicator("Gold line", { overlay: true })
const gold = color.theme({ dark: #FFC857, light: #B7791F, hc: #FFE600 })
plot(ta.ema(close, 100), "EMA 100", gold, 2)

light and hc (high contrast) are optional; when you leave one out, that theme uses the dark color. You can also read the current theme by name from chart.theme, which is "dark", "light" or "hc".

#Palettes

When a script uses a handful of colors together, a palette keeps them in one place and lets the user swap the whole set. palette.new names the colors, input.palette lets the user choose between palettes, and palette.get reads one color back:

ChartScriptOpen in editor
//@chartscript 1
indicator("Palette demo", { overlay: true })
const calm = palette.new("Calm", { bull: #26A69A, bear: #EF5350 })
const neon = palette.new("Neon", { bull: #39FF14, bear: #FF3864 })
const pal = input.palette(calm, "Colours", { palettes: [calm, neon] })

const fastLine = ta.ema(close, 10)
const slowLine = ta.ema(close, 30)
plot(fastLine, "Fast", fastLine > slowLine ? palette.get(pal, "bull") : palette.get(pal, "bear"), 2)
plot(slowLine, "Slow", color.muted)

#na as a color

na means "no color". On an output's main color it hides: a plot, shape, fill or background with an na color on a bar draws nothing on that bar, and a constant color: na hides the output entirely. Leaving the color argument out is different: the output then uses its default theme color.

On secondary colors (textcolor, wickcolor, bordercolor, colorup, colordown) na means "use the default".

#The user always has the last word

Whatever colors you choose, every output appears in the Style and Colors tabs of the script's settings, where the person using it can change color and opacity, or recolor the whole script with a preset (Colorblind-safe, Monochrome, High contrast). Give a color input, a plot, marker, level or fill, or a named style a role ("up", "down", "neutral", "accent") when its name and hue do not tell the presets what it means; see Designing your script's settings. If your color changes from bar to bar and the user picks a color of their own, theirs is used on every bar (bars where your color is na stay hidden). Use input.color when you want a color to be a proper, named setting of your script.

The ChartScript documentation is in English for now; translations will follow.