Markers

Markers are small annotations (circles, squares, or arrows) attached to a series at specific points in time. Use them to flag individual events (a fill, a signal, a regime change) directly on the chart without disrupting the underlying price curve.

There are three ways to put markers on a chart. Use tvl.marker() for static, code-defined markers; tvl.markers_from_table() when each row of a Deephaven table should become one marker (and tick live as the table updates); and tvl.up_down_markers() as a convenience for the common “buys are up arrows, sells are down arrows” pattern.

What are markers useful for?

  • Annotating fills: Mark every executed order on the price line so traders can see where positions changed hands.
  • Highlighting signals: A strategy that generates buy/sell signals can render them as up/down arrows directly on the candlestick.
  • Flagging events: News releases, earnings announcements, or system events can be pinned to their timestamps as labeled circles.
  • Picking out levels: Price-based positions (at_price_top, at_price_middle, at_price_bottom) let a marker float independent of the bar: useful for marking option strikes or support/resistance touches.

Examples

Add a single static marker

tvl.marker() builds one Marker object. Pass a list of them via the markers= keyword on any per-type constructor.

The single marker hovers above the bar for 2024-01-15 with a downward red arrow.

Show every marker shape

MarkerShape has four values: "circle", "square", "arrow_up", "arrow_down". The example below puts one of each on a single chart at staggered times.

The four markers march across the chart, one shape per timestamp.

Show every marker position

MarkerPosition has six values. The three bar-relative positions ("above_bar", "below_bar", "in_bar") anchor to the bar at the given time. The three price-relative positions ("at_price_top", "at_price_bottom", "at_price_middle") float at a specific price regardless of the bar.

All six positions render together. The bar-relative ones move with the candle, the price-relative ones lock to their price.

Drive markers from a Deephaven table

tvl.markers_from_table() builds a MarkerSpec instead of a list. Each row of the table becomes one marker; columns supply per-row values for any property that has a *_column parameter. Because the spec keeps a live reference to the table, markers tick when the table updates.

Pass the spec via the series’ marker_spec= argument. As the source table ticks, new markers appear automatically.

Use fixed defaults with markers_from_table

If every marker shares the same shape and color, omit the per-row column and set the fixed default directly. Mix-and-match is fine. Fixed values fill in for any property without a *_column.

The chart shows one blue circle per event, each labeled with its row’s Note.

Price-driven markers from a table

For at_price_* positions, supply a price_column so each row’s price comes from the data.

The orange squares float at Level, independent of the candle’s High/Low.

Use up_down_markers for buy/sell signals

tvl.up_down_markers() is the shortcut for the most common pattern: a list of up timestamps and a list of down timestamps, rendered as arrows below/above the bar with theme-derived colors.

The helper returns a list[Marker] that drops straight into the series’ markers= argument. The library sorts markers by time, so the order of up_times and down_times doesn’t matter. (Two type-only Literal aliases, MarkerSign and MismatchDirection, are exported for annotations.)

API Reference

Create a single static marker to place on a series.

Returns: Marker A Marker instance with snake_case input values translated to the camelCase JS form expected by the wire protocol.

Raises: ValueError -- If position is a price-anchored variant and price is not supplied.

ParametersTypeDefaultDescription
timeAnyTime anchor for the marker. UTC timestamp, ISO string, or BusinessDay dict.
positionMarkerPosition'above_bar'Anchor position. See MarkerPosition. For "at_price_*" positions you must also supply price.
shapeMarkerShape'circle'Glyph drawn for the marker. See MarkerShape.
colorOptional[Color]NoneCSS color for the glyph fill.
textstr''Optional label text drawn near the marker.
sizeOptional[int]NoneGlyph size multiplier (default 1).
idOptional[str]NoneOptional string identifier.
priceOptional[float]NoneRequired when position is one of the "at_price_*" variants.

timestamp is always a column name. For each other property, you may pass a fixed value (e.g. color="#FF0000") that applies to every marker, or a *_column name (e.g. color_column="Color") to read the value per-row from the table. For price-based positions ("at_price_top" etc.) supply either price (same price for every row) or price_column (different price per row).

Returns: MarkerSpec A MarkerSpec ready to attach to a series via the marker_spec= parameter of any series factory.

Raises: ValueError -- If both price and price_column are supplied, or if a price-anchored position is requested without either.

ParametersTypeDefaultDescription
tableAnyDeephaven table whose rows drive the markers.
timestampstr'Timestamp'Column name supplying each marker's time value.
positionMarkerPosition'above_bar'Default marker position; see MarkerPosition.
shapeMarkerShape'circle'Default marker shape; see MarkerShape.
colorOptional[Color]NoneDefault marker color.
textstr''Default label text.
sizeOptional[int]NoneDefault size multiplier.
priceOptional[float]NoneDefault price for price-anchored positions.
position_columnOptional[str]NoneColumn supplying per-row MarkerPosition values.
shape_columnOptional[str]NoneColumn supplying per-row MarkerShape values.
color_columnOptional[str]NoneColumn supplying per-row CSS color strings.
text_columnOptional[str]NoneColumn supplying per-row text labels.
size_columnOptional[str]NoneColumn supplying per-row size values.
id_columnOptional[str]NoneColumn supplying per-row marker IDs.
price_columnOptional[str]NoneColumn supplying per-row price values for price-anchored positions.

The returned list can be passed directly to the markers= parameter of any series factory. The library sorts markers by time, so Python ordering does not matter.

Returns: list[Marker] Flat list of Marker objects — up events followed by down events.

ParametersTypeDefaultDescription
up_timeslist[Any]Time values for bullish / up events.
down_timeslist[Any]Time values for bearish / down events.
up_colorLiteral['gray-50', 'gray-75', 'gray-100', 'gray-200', 'gray-300', 'gray-400', 'gray-500', 'gray-600', 'gray-700', 'gray-800', 'gray-900', 'red-100', 'red-200', 'red-300', 'red-400', 'red-500', 'red-600', 'red-700', 'red-800', 'red-900', 'red-1000', 'red-1100', 'red-1200', 'red-1300', 'red-1400', 'orange-100', 'orange-200', 'orange-300', 'orange-400', 'orange-500', 'orange-600', 'orange-700', 'orange-800', 'orange-900', 'orange-1000', 'orange-1100', 'orange-1200', 'orange-1300', 'orange-1400', 'yellow-100', 'yellow-200', 'yellow-300', 'yellow-400', 'yellow-500', 'yellow-600', 'yellow-700', 'yellow-800', 'yellow-900', 'yellow-1000', 'yellow-1100', 'yellow-1200', 'yellow-1300', 'yellow-1400', 'chartreuse-100', 'chartreuse-200', 'chartreuse-300', 'chartreuse-400', 'chartreuse-500', 'chartreuse-600', 'chartreuse-700', 'chartreuse-800', 'chartreuse-900', 'chartreuse-1000', 'chartreuse-1100', 'chartreuse-1200', 'chartreuse-1300', 'chartreuse-1400', 'celery-100', 'celery-200', 'celery-300', 'celery-400', 'celery-500', 'celery-600', 'celery-700', 'celery-800', 'celery-900', 'celery-1000', 'celery-1100', 'celery-1200', 'celery-1300', 'celery-1400', 'green-100', 'green-200', 'green-300', 'green-400', 'green-500', 'green-600', 'green-700', 'green-800', 'green-900', 'green-1000', 'green-1100', 'green-1200', 'green-1300', 'green-1400', 'seafoam-100', 'seafoam-200', 'seafoam-300', 'seafoam-400', 'seafoam-500', 'seafoam-600', 'seafoam-700', 'seafoam-800', 'seafoam-900', 'seafoam-1000', 'seafoam-1100', 'seafoam-1200', 'seafoam-1300', 'seafoam-1400', 'cyan-100', 'cyan-200', 'cyan-300', 'cyan-400', 'cyan-500', 'cyan-600', 'cyan-700', 'cyan-800', 'cyan-900', 'cyan-1000', 'cyan-1100', 'cyan-1200', 'cyan-1300', 'cyan-1400', 'blue-100', 'blue-200', 'blue-300', 'blue-400', 'blue-500', 'blue-600', 'blue-700', 'blue-800', 'blue-900', 'blue-1000', 'blue-1100', 'blue-1200', 'blue-1300', 'blue-1400', 'indigo-100', 'indigo-200', 'indigo-300', 'indigo-400', 'indigo-500', 'indigo-600', 'indigo-700', 'indigo-800', 'indigo-900', 'indigo-1000', 'indigo-1100', 'indigo-1200', 'indigo-1300', 'indigo-1400', 'purple-100', 'purple-200', 'purple-300', 'purple-400', 'purple-500', 'purple-600', 'purple-700', 'purple-800', 'purple-900', 'purple-1000', 'purple-1100', 'purple-1200', 'purple-1300', 'purple-1400', 'fuchsia-100', 'fuchsia-200', 'fuchsia-300', 'fuchsia-400', 'fuchsia-500', 'fuchsia-600', 'fuchsia-700', 'fuchsia-800', 'fuchsia-900', 'fuchsia-1000', 'fuchsia-1100', 'fuchsia-1200', 'fuchsia-1300', 'fuchsia-1400', 'magenta-100', 'magenta-200', 'magenta-300', 'magenta-400', 'magenta-500', 'magenta-600', 'magenta-700', 'magenta-800', 'magenta-900', 'magenta-1000', 'magenta-1100', 'magenta-1200', 'magenta-1300', 'magenta-1400', 'negative', 'notice', 'positive', 'info', 'accent', 'accent-100', 'accent-200', 'accent-300', 'accent-400', 'accent-500', 'accent-600', 'accent-700', 'accent-800', 'accent-900', 'accent-1000', 'accent-1100', 'accent-1200', 'accent-1300', 'accent-1400', 'bg', 'content-bg', 'subdued-content-bg', 'surface-bg', 'fg'] |
str |
None
NoneFill color for up-markers. Default: theme OHLC increase color.
down_colorLiteral['gray-50', 'gray-75', 'gray-100', 'gray-200', 'gray-300', 'gray-400', 'gray-500', 'gray-600', 'gray-700', 'gray-800', 'gray-900', 'red-100', 'red-200', 'red-300', 'red-400', 'red-500', 'red-600', 'red-700', 'red-800', 'red-900', 'red-1000', 'red-1100', 'red-1200', 'red-1300', 'red-1400', 'orange-100', 'orange-200', 'orange-300', 'orange-400', 'orange-500', 'orange-600', 'orange-700', 'orange-800', 'orange-900', 'orange-1000', 'orange-1100', 'orange-1200', 'orange-1300', 'orange-1400', 'yellow-100', 'yellow-200', 'yellow-300', 'yellow-400', 'yellow-500', 'yellow-600', 'yellow-700', 'yellow-800', 'yellow-900', 'yellow-1000', 'yellow-1100', 'yellow-1200', 'yellow-1300', 'yellow-1400', 'chartreuse-100', 'chartreuse-200', 'chartreuse-300', 'chartreuse-400', 'chartreuse-500', 'chartreuse-600', 'chartreuse-700', 'chartreuse-800', 'chartreuse-900', 'chartreuse-1000', 'chartreuse-1100', 'chartreuse-1200', 'chartreuse-1300', 'chartreuse-1400', 'celery-100', 'celery-200', 'celery-300', 'celery-400', 'celery-500', 'celery-600', 'celery-700', 'celery-800', 'celery-900', 'celery-1000', 'celery-1100', 'celery-1200', 'celery-1300', 'celery-1400', 'green-100', 'green-200', 'green-300', 'green-400', 'green-500', 'green-600', 'green-700', 'green-800', 'green-900', 'green-1000', 'green-1100', 'green-1200', 'green-1300', 'green-1400', 'seafoam-100', 'seafoam-200', 'seafoam-300', 'seafoam-400', 'seafoam-500', 'seafoam-600', 'seafoam-700', 'seafoam-800', 'seafoam-900', 'seafoam-1000', 'seafoam-1100', 'seafoam-1200', 'seafoam-1300', 'seafoam-1400', 'cyan-100', 'cyan-200', 'cyan-300', 'cyan-400', 'cyan-500', 'cyan-600', 'cyan-700', 'cyan-800', 'cyan-900', 'cyan-1000', 'cyan-1100', 'cyan-1200', 'cyan-1300', 'cyan-1400', 'blue-100', 'blue-200', 'blue-300', 'blue-400', 'blue-500', 'blue-600', 'blue-700', 'blue-800', 'blue-900', 'blue-1000', 'blue-1100', 'blue-1200', 'blue-1300', 'blue-1400', 'indigo-100', 'indigo-200', 'indigo-300', 'indigo-400', 'indigo-500', 'indigo-600', 'indigo-700', 'indigo-800', 'indigo-900', 'indigo-1000', 'indigo-1100', 'indigo-1200', 'indigo-1300', 'indigo-1400', 'purple-100', 'purple-200', 'purple-300', 'purple-400', 'purple-500', 'purple-600', 'purple-700', 'purple-800', 'purple-900', 'purple-1000', 'purple-1100', 'purple-1200', 'purple-1300', 'purple-1400', 'fuchsia-100', 'fuchsia-200', 'fuchsia-300', 'fuchsia-400', 'fuchsia-500', 'fuchsia-600', 'fuchsia-700', 'fuchsia-800', 'fuchsia-900', 'fuchsia-1000', 'fuchsia-1100', 'fuchsia-1200', 'fuchsia-1300', 'fuchsia-1400', 'magenta-100', 'magenta-200', 'magenta-300', 'magenta-400', 'magenta-500', 'magenta-600', 'magenta-700', 'magenta-800', 'magenta-900', 'magenta-1000', 'magenta-1100', 'magenta-1200', 'magenta-1300', 'magenta-1400', 'negative', 'notice', 'positive', 'info', 'accent', 'accent-100', 'accent-200', 'accent-300', 'accent-400', 'accent-500', 'accent-600', 'accent-700', 'accent-800', 'accent-900', 'accent-1000', 'accent-1100', 'accent-1200', 'accent-1300', 'accent-1400', 'bg', 'content-bg', 'subdued-content-bg', 'surface-bg', 'fg'] |
str |
None
NoneFill color for down-markers. Default: theme OHLC decrease color.
up_textstr''Label text for up-markers. Default: "" (no label).
down_textstr''Label text for down-markers. Default: "" (no label).
up_sizeint |
None
NoneSize multiplier for up-markers. Default: library default (1).
down_sizeint |
None
NoneSize multiplier for down-markers. Default: library default (1).