Colors
Built-in color constants and helpers.
Color helpers accept hex strings (#RRGGBB or #RRGGBBAA) or ABGR numeric values. Functions like color.rgb() return hex strings, so they can be used anywhere a color is accepted by plots, fills, or entities.
For gradient helpers, prefer the enum-style aliases color.mode.*, color.space.*, and color.easing.*. Raw strings still work for compatibility.
For full scripts, see the Colors & Gradients examples.
Constants
Available via color.*:
| Constant | Value |
|---|---|
color.up | (default; set by chart theme config) |
color.down | (default; set by chart theme config) |
color.red | |
color.maroon | |
color.brown | |
color.orange | |
color.amber | |
color.yellow | |
color.olive | |
color.green | |
color.emerald | |
color.teal | |
color.cyan | |
color.lightskyblue | |
color.blue | |
color.indigo | |
color.navy | |
color.purple | |
color.magenta | |
color.pink | |
color.white | |
color.silver | |
color.gray | |
color.black | |
color.transparent |
color.up and color.down are based on your terminals theme up and down colors.
Gradient option aliases:
color.mode.clampcolor.mode.wrapcolor.mode.mirrorcolor.space.rgbcolor.space.hslcolor.easing.linearcolor.easing.smoothstepcolor.easing.smootherstep
Functions
color.rgb
color.rgb(r, g, b, a?) -> stringBuilds a color from 8-bit channel values. a is optional and defaults to 255 (fully opaque).
| Param | Type | Description |
|---|---|---|
r | number | Red channel (0–255) |
g | number | Green channel (0–255) |
b | number | Blue channel (0–255) |
a | number | Optional alpha channel (0–255) |
const c = color.rgb(17, 34, 51, 68)
plot("RGB", 1, { color: c })color.r / color.g / color.b / color.t
color.r(color) -> number
color.g(color) -> number
color.b(color) -> number
color.t(color) -> numberExtract 8-bit channel values from a color. color.t() returns the fourth channel value (0–255).
const c = color.rgb(17, 34, 51, 68)
log(color.r(c), color.g(c), color.b(c), color.t(c))color.fromGradient
color.fromGradient(value, bottomValue, topValue, bottomColor, topColor) -> stringInterpolates between two colors across a numeric range.
For more advanced gradient mapping, use color.grade or color.scale
| Param | Type | Description |
|---|---|---|
value | number | Current value to map |
bottomValue | number | Lower bound |
topValue | number | Upper bound |
bottomColor | color | Color used at or below bottomValue |
topColor | color | Color used at or above topValue |
color.fromGradient(barIndex(), 0, 100, color.red, color.green)color.grade
color.grade(value, stops, options?) -> stringInterpolates across multiple color stops for more flexible color grading.
Stops can use any numeric range — they don't need to be 0..100.
| Param | Type | Description |
|---|---|---|
value | number | Current value to map |
stops | array | At least 2 stops, either [value, color], { value, color }, or { at, color } |
options | object | Optional grading controls |
Supported options:
| Option | Type | Default | Description |
|---|---|---|---|
mode | string | color.mode.clamp | Out-of-range handling: color.mode.clamp, color.mode.wrap, or color.mode.mirror |
space | string | color.space.hsl | Interpolation space: color.space.rgb or color.space.hsl |
easing | string | color.easing.linear | Segment easing: color.easing.linear, color.easing.smoothstep, or color.easing.smootherstep |
const rsiValue = ta.rsi(candles.close(), 14)
const heat = typeof rsiValue === "number" ? color.grade(rsiValue, [
[0, color.blue],
[30, color.teal],
[50, color.yellow],
[70, color.orange],
[100, color.red]
], {
space: color.space.hsl,
easing: color.easing.smoothstep
}) : color.transparent
plot("RSI Heat", rsiValue, { color: heat })const regime = color.grade(candles.close(), [
[95000, color.blue],
[100000, color.yellow],
[105000, color.red]
])
plot("Price Regime", candles.close(), { color: regime })Midpoint stays muddy olive because the channels blend directly.
Midpoint passes through bright yellow because hue rotates through the shortest path.
Color changes at a constant rate across the bar.
The ends ease in and out, so the middle transitions faster.
The same shape, but with even softer acceleration at both ends.
color.scale
color.scale(stops, options?) -> { sample(value): string }Creates a reusable color scale object. Use this when you want to define the stops once and then sample multiple values from the same gradient.
color.grade(value, stops, options) is the one-off shorthand. color.scale(stops, options).sample(value) is the reusable form.
See the dynamic and static examples for fuller chart-ready versions.
| Param | Type | Description |
|---|---|---|
stops | array | At least 2 stops, either [value, color], { value, color }, or { at, color } |
options | object | Optional grading controls, see color.grade for details |
Static scale
Use a static scale when you want consistent coloring across history.
//@version=2
indicator("Color Scale Example", true)
const candles = subscribe(data.OHLCV)
const heatScale = color.scale([
[0, color.blue],
[30, color.teal],
[50, color.yellow],
[70, color.orange],
[100, color.red]
], {
space: color.space.hsl,
easing: color.easing.smoothstep
})
function onBar(index) {
const rsiValue = ta.rsi(candles.close(), 14)
plot("RSI Heat", rsiValue, {
color: typeof rsiValue === "number" ? heatScale.sample(rsiValue) : color.transparent
})
}Dynamic scale
Use a dynamic scale when the stops should adapt to the current bar context. This is useful for relative coloring, but it will not stay historically fixed if the stop values keep moving.
//@version=2
indicator("Color Scale Example", true)
const candles = subscribe(data.OHLCV)
function onBar(index) {
const rangeLow = ta.lowest(candles.close(), 200)
const rangeHigh = ta.highest(candles.close(), 200)
if (typeof rangeLow !== "number" || typeof rangeHigh !== "number") return
const sessionScale = color.scale([
[rangeLow, color.blue],
[rangeHigh, color.red]
], {
space: color.space.hsl
})
const emaValue = ta.ema(candles.close(), 20)
plot("Close", candles.close(), { color: sessionScale.sample(candles.close()) })
plot("EMA", emaValue, {
color: typeof emaValue === "number" ? sessionScale.sample(emaValue) : color.transparent
})
}color.transp
color.transp(color, percentage) -> stringApplies transparency to a color. 0 is fully opaque, 100 is fully invisible.
See the lighten, darken, and transparency example for a combined overlay use case.
| Param | Type | Description |
|---|---|---|
color | color | Input color (hex string or ABGR number) |
percentage | number | Transparency level (0–100) |
color.transp(color.blue, 50)
color.transp("#ff0000", 80)color.lighten
color.lighten(color, percent) -> stringLightens a color by increasing RGB channels toward white.
| Param | Type | Description |
|---|---|---|
color | color | Input color |
percent | number | Lightness increase (0–100) |
color.lighten(color.red, 30)color.darken
color.darken(color, percent) -> stringDarkens a color by decreasing RGB channels toward black.
| Param | Type | Description |
|---|---|---|
color | color | Input color |
percent | number | Darkness increase (0–100) |
color.darken(color.green, 40)