<!-- coverage-seen-elsewhere:
  markers -> markers.md
  price_lines -> price-lines.md
  marker_spec -> markers.md
  on_press -> events.md
  on_double_press -> events.md
  auto_bin -> autobin.md
  bin_width -> autobin.md
  bin_count -> autobin.md
  crosshair_mode -> styling.md
  time_visible -> time-scale.md
  watermark_text -> watermark.md
  visible -> titles-legends.md
  last_value_visible -> titles-legends.md
  price_scale_id -> price-scale.md
  price_format -> price-formats.md
  last_price_line -> price-lines.md
  base_line -> price-scale.md
  price_scale -> price-scale.md
  pane -> multi-pane.md
  by -> multi-series.md
-->

# Candlestick Chart

A candlestick chart shows the open, high, low, and close (OHLC) of a price series as a stack of rectangular bodies with thin “wick” lines, giving a compact view of where price ranged within each interval. Use it when you have time-bucketed OHLC bars and need to read direction and range at a glance.

In a bullish (up) candle the close sits above the open and the body is typically rendered green; in a bearish (down) candle the close sits below the open and the body is typically red. The wick (or “shadow”) extends from the body to the period’s high and low, so wick length communicates intra-bar volatility.

## What are candlestick charts useful for?

- **Reading short-term price action**: Bodies and wicks make direction and intra-bar range readable at a glance, which is why candlesticks are common on technical-analysis screens.
- **Spotting reversal and continuation patterns**: Many classical patterns (engulfings, hammers, dojis) rely on the relative size of body and wicks, and candlesticks are the only chart type that surfaces both.
- **Comparing volatility regimes**: Long wicks with small bodies signal indecision; tall bodies with short wicks signal momentum. Switching between regimes is easy to see.
- **Confirming aggregations**: Because TVL aggregates OHLC server-side when the table is large, a candlestick chart is also a quick check that your binning matches what you expected.

## Examples

### A basic candlestick chart

Hand the chart a Deephaven table that already contains OHLC columns and the rest is automatic. The defaults (`timestamp="Timestamp"`, `open="Open"`, `high="High"`, `low="Low"`, `close="Close"`) match the columns produced by `tvl.data.ohlc()`, so for the demo dataset you only need the table itself.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(data)
```

Each candle covers one row in `data`; green bodies are up days and red bodies are down days. `tvl.candlestick()` doesn’t carry the last-price pulse animation that line / area / baseline series do. See [line](line.md) and [styling](styling.md) for the `LastPriceAnimationMode` examples.

When `up_color` / `down_color` are not provided, the chart adapts to the active theme automatically. Light and dark themes both render correctly without code changes.

### Map non-default OHLC column names

If your table uses different column names, for example lowercase columns coming from a feed or a different timestamp column, pass them explicitly. Every column kwarg is just a string column name.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc().rename_columns(["Ts=Timestamp", "O=Open", "H=High", "L=Low", "C=Close"])

candlestick = tvl.candlestick(
    data,
    timestamp="Ts",
    open="O",
    high="H",
    low="L",
    close="C",
)
```

### Customize up and down colors

Override the default green/red palette with `up_color` and `down_color`. Use this to match a brand palette, build a color-blind-friendly variant, or to dim the candles before overlaying markers and price lines.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(
    data,
    up_color="seafoam-800",
    down_color="magenta-600",
)
```

All color kwargs (`up_color`, `down_color`, `border_*_color`, `wick_*_color`) accept a Deephaven theme color (e.g. `"seafoam-800"`, `"accent-300"`), a hex code (`"#1f8a70"`), a named CSS color (`"crimson"`), or an `rgb()`/`rgba()` string for transparency. Theme colors adapt automatically when the user switches themes; hardcoded values do not. Leaving the up/down colors unset inherits the active theme’s OHLC palette.

### Outline-only candles via border colors

`border_up_color` and `border_down_color` set the outline color of each candle independently of the body fill. Setting a border to `"transparent"` removes that border entirely, leaving only the body fill. Combine this with a neutral body fill and a single visible up border to get a “pavement” two-tone candle.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(
    data,
    up_color="gray-500",
    down_color="gray-500",
    border_up_color="gray-500",
    border_down_color="transparent",
)
```

Up candles use a neutral grey throughout; down candles drop their border so only the grey body remains.

### Recolor the wicks

`wick_up_color` and `wick_down_color` set the wick color separately from the body. Use this to dim the wicks while keeping bright bodies (for marker visibility), or to brighten the wicks on a dark background.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(
    data,
    wick_up_color="gray-500",
    wick_down_color="gray-500",
)
```

Both wicks are now grey; the bodies keep their defaults.

### Set the chart title

`title` is the legend label for the series. It appears on hover and in the chart toolbar. Use it whenever you have more than one series on a chart, or when the chart will be embedded somewhere a column name (`Open`/`Close`) is too generic.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(data, title="AAPL daily OHLC")
```

The legend now reads “AAPL daily OHLC” instead of the default series name.

### Server-side autobinning

Hand the chart a large OHLC table and TVL automatically aggregates it server-side into a viewport-friendly number of buckets, picking a “nice” bin width and computing `first(Open)` / `max(High)` / `min(Low)` / `last(Close)` per bin. Override the bucket count or width via `bin_count` / `bin_width`, or set `auto_bin=False` to bypass it entirely for small tables.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(data, auto_bin=True, bin_width="P7D")
```

See [autobin](autobin.md) for the full autobin surface: ISO-8601 duration grammar, when each `auto_bin` value is the right pick, and how the path interacts with the downsampler.

### Single border / wick colors and toggles

`border_color` and `wick_color` set one color for both up and down candles, shorthand for setting the `*_up_color` / `*_down_color` pair to the same value. `border_visible` and `wick_visible` toggle the outline and wick rendering entirely.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(
    data,
    border_visible=True,
    border_color="gray-500",
    wick_visible=True,
    wick_color="gray-500",
)
```

### Time-proportional layout with `continuous`

By default (`continuous=True`) candles are laid out proportionally in time. Unlike the [histogram](histogram.md#continuous-bars), candle bodies are **not** drawn end-to-end — they keep the classic proportions, with a small gap between adjacent candles — but sections of data separated by a time hole (a market close, a halted feed, missing rows) are separated by a proportional open gap. On data with no holes, `continuous=True` and `continuous=False` look the same. Set `continuous=False` to restore the plain ordinal layout, which collapses any time hole to a single candle-width step.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc()

candlestick = tvl.candlestick(data, continuous=False)
```

### Per-bar colors from a column

Drive each candle’s color from a table column with `color_column` (body), `border_color_column` (outline), and `wick_color_column` (wick). Each names a column holding a CSS/theme color string per row. Here we color each bar by whether it closed up or down.

```python order=candlestick,data
import deephaven.plot.tradingview_lightweight as tvl
data = tvl.data.ohlc().update_view(
    ["BarColor = Close >= Open ? `#26a69a` : `#ef5350`"]
)

candlestick = tvl.candlestick(
    data,
    color_column="BarColor",
    border_color_column="BarColor",
    wick_color_column="BarColor",
)
```

## API Reference

A candlestick series renders four channels (open, high, low,
close) per time bucket as a filled body with wicks.  When the
source table is large, auto-binning aggregates OHLC values
server-side before the data is shipped to the browser.

**Returns:** `TvlChart` A chart wrapping a single candlestick series.
chart().

<ParamTable param={{"module_name": "deephaven.plot.tradingview_lightweight.", "name": "candlestick", "parameters": [{"name": "table", "type": "Any", "description": "The Deephaven table containing OHLC data."}, {"name": "timestamp", "type": "str", "description": "Column name for the time axis.", "default": "'Timestamp'"}, {"name": "open", "type": "str", "description": "Column name for the opening price.", "default": "'Open'"}, {"name": "high", "type": "str", "description": "Column name for the bar high.", "default": "'High'"}, {"name": "low", "type": "str", "description": "Column name for the bar low.", "default": "'Low'"}, {"name": "close", "type": "str", "description": "Column name for the closing price.", "default": "'Close'"}, {"name": "up_color", "type": "Optional[Color]", "description": "Body color for up-bars.", "default": "None"}, {"name": "down_color", "type": "Optional[Color]", "description": "Body color for down-bars.", "default": "None"}, {"name": "border_visible", "type": "Optional[bool]", "description": "Show the body border.", "default": "None"}, {"name": "border_color", "type": "Optional[Color]", "description": "Border color for both directions.", "default": "None"}, {"name": "border_up_color", "type": "Optional[Color]", "description": "Border color for up-bars (overrides border_color for up).", "default": "None"}, {"name": "border_down_color", "type": "Optional[Color]", "description": "Border color for down-bars.", "default": "None"}, {"name": "wick_visible", "type": "Optional[bool]", "description": "Show wicks.", "default": "None"}, {"name": "wick_color", "type": "Optional[Color]", "description": "Wick color for both directions.", "default": "None"}, {"name": "wick_up_color", "type": "Optional[Color]", "description": "Wick color for up-bars.", "default": "None"}, {"name": "wick_down_color", "type": "Optional[Color]", "description": "Wick color for down-bars.", "default": "None"}, {"name": "title", "type": "Optional[str]", "description": "Title shown in the series tooltip / legend.", "default": "None"}, {"name": "visible", "type": "Optional[bool]", "description": "Whether the series is visible.", "default": "None"}, {"name": "last_value_visible", "type": "Optional[bool]", "description": "Show the last-value badge on the price scale.", "default": "None"}, {"name": "price_scale_id", "type": "Optional[str]", "description": "ID of the price scale this series uses (\"left\", \"right\", or a custom overlay ID).", "default": "None"}, {"name": "price_format", "type": "Optional[PriceFormat]", "description": "Per-series number format; build with price_format().", "default": "None"}, {"name": "last_price_line", "type": "Optional[LastPriceLine]", "description": "Styling for the auto last-price horizontal rule; build with last_price_line().", "default": "None"}, {"name": "base_line", "type": "Optional[BaseLine]", "description": "Styling for the zero/index base line (percentage / indexed_to_100 price modes); build with base_line().", "default": "None"}, {"name": "price_scale", "type": "Optional[PriceScale]", "description": "Options for the price scale this series binds to; build with price_scale().", "default": "None"}, {"name": "color_column", "type": "Optional[str]", "description": "Column name supplying per-row body color (overrides up_color / down_color).", "default": "None"}, {"name": "border_color_column", "type": "Optional[str]", "description": "Column name supplying per-row border color.", "default": "None"}, {"name": "wick_color_column", "type": "Optional[str]", "description": "Column name supplying per-row wick color.", "default": "None"}, {"name": "pane", "type": "Optional[int]", "description": "Pane index (default 0).", "default": "None"}, {"name": "markers", "type": "Optional[list[Marker]]", "description": "Static markers.", "default": "None"}, {"name": "price_lines", "type": "Optional[list[PriceLine]]", "description": "Horizontal price lines.", "default": "None"}, {"name": "marker_spec", "type": "Optional[MarkerSpec]", "description": "Table-driven marker spec.", "default": "None"}, {"name": "auto_bin", "type": "Optional[bool]", "description": "Tri-state.  None (default) auto-bins when the table exceeds the auto-bin threshold (5000 rows); True forces aggregation even for small tables; False ships the raw table.", "default": "None"}, {"name": "bin_width", "type": "Optional[str]", "description": "ISO 8601 duration override (e.g. \"PT1S\", \"PT5M\").", "default": "None"}, {"name": "bin_count", "type": "Optional[int]", "description": "Target number of bins (default 5000).", "default": "None"}, {"name": "continuous", "type": "bool", "description": "True (default) renders candle bodies spanning their full time bin (end-to-end); False uses the built-in fixed pixel-width renderer.", "default": "True"}, {"name": "by", "type": "Optional[str]", "description": "Column name to partition the table by. When set, one runtime series is created per unique value; new partition keys discovered at runtime (ticking tables) add new series automatically.", "default": "None"}, {"name": "on_press", "type": "Optional[PressEventCallable]", "description": "Server-side callback invoked when the user presses (clicks) on the chart. Receives a TvlPressEvent dict, or no argument.", "default": "None"}, {"name": "on_double_press", "type": "Optional[PressEventCallable]", "description": "Server-side callback invoked when the user double-presses on the chart.", "default": "None"}]}} />
