DocumentationConstants & Helpers

Constants & Helpers

Every value and function on this page is part of the public API exported from openalgo-charts and can be imported directly:

import {
  VERSION, darkTheme, DEFAULT_CANDLE_STYLE,
  clamp, niceTicks, generateBars,
} from 'openalgo-charts';

Part 1 — Constants

VERSION and version()

export const VERSION = '1.0.3';
export function version(): string;

VERSION is the string literal; version() returns the same string. Both are replaced with the published semver at release time.


Themes

The full set of palette keys that make up a ChartTheme:

interface ChartTheme {
  background: string;
  grid: string;
  axisText: string;
  axisLine: string;
  crosshair: string;
  // candle / bar / column
  upColor: string;
  downColor: string;
  wickUpColor: string;
  wickDownColor: string;
  // line / area
  lineColor: string;
  areaTopColor: string;
  areaBottomColor: string;
  // baseline
  baselineTopLine: string;
  baselineTopFill: string;
  baselineBottomLine: string;
  baselineBottomFill: string;
  // last-price tag
  lastPriceUp: string;
  lastPriceDown: string;
  lastPriceText: string;
  // trade layer
  buy: string;
  sell: string;
  profit: string;
  loss: string;
}

darkTheme (the library default, re-exported as DEFAULT_THEME):

export const darkTheme: ChartTheme = {
  background:          '#0d0e12',
  grid:                '#161a26',
  axisText:            '#8b91a7',
  axisLine:            '#2a3046',
  crosshair:           '#6b7280',
  upColor:             '#26a69a',
  downColor:           '#ef5350',
  wickUpColor:         '#26a69a',
  wickDownColor:       '#ef5350',
  lineColor:           '#4f8cff',
  areaTopColor:        'rgba(79,140,255,0.40)',
  areaBottomColor:     'rgba(79,140,255,0.00)',
  baselineTopLine:     '#26a69a',
  baselineTopFill:     'rgba(38,166,154,0.20)',
  baselineBottomLine:  '#ef5350',
  baselineBottomFill:  'rgba(239,83,80,0.20)',
  lastPriceUp:         '#26a69a',
  lastPriceDown:       '#ef5350',
  lastPriceText:       '#0d0e12',
  buy:                 '#26a69a',
  sell:                '#ef5350',
  profit:              '#26a69a',
  loss:                '#ef5350',
};
 
export const DEFAULT_THEME = darkTheme;

lightTheme:

export const lightTheme: ChartTheme = {
  background:          '#ffffff',
  grid:                '#eef1f6',
  axisText:            '#5b6472',
  axisLine:            '#d4dae3',
  crosshair:           '#9aa3b2',
  upColor:             '#089981',
  downColor:           '#e0473e',
  wickUpColor:         '#089981',
  wickDownColor:       '#e0473e',
  lineColor:           '#2962ff',
  areaTopColor:        'rgba(41,98,255,0.30)',
  areaBottomColor:     'rgba(41,98,255,0.00)',
  baselineTopLine:     '#089981',
  baselineTopFill:     'rgba(8,153,129,0.18)',
  baselineBottomLine:  '#e0473e',
  baselineBottomFill:  'rgba(224,71,62,0.18)',
  lastPriceUp:         '#089981',
  lastPriceDown:       '#e0473e',
  lastPriceText:       '#ffffff',
  buy:                 '#089981',
  sell:                '#e0473e',
  profit:              '#089981',
  loss:                '#e0473e',
};

Pass either theme to createChart via the theme option, or build your own object that satisfies ChartTheme. See Themes for a step-by-step guide.


DEFAULT_PRICE_SCALE_OPTIONS

export const DEFAULT_PRICE_SCALE_OPTIONS: PriceScaleOptions = {
  marginTop:    0.1,   // 10 % of pane height kept empty above the highest bar
  marginBottom: 0.1,   // 10 % kept empty below the lowest bar
  minMove:      0,     // 0 = infer precision from the visible range
  mode:         'linear',
  inverted:     false,
};

mode accepts 'linear' or 'logarithmic'. minMove is the instrument tick size (e.g. 0.05 for NSE equity options); when nonzero the axis labels snap to that step.


DEFAULT_TIME_SCALE_OPTIONS

export const DEFAULT_TIME_SCALE_OPTIONS: TimeScaleOptions = {
  barSpacing:    8,   // CSS px per bar at the default zoom level
  minBarSpacing: 1,   // zoom-out floor
  maxBarSpacing: 80,  // zoom-in ceiling
  rightOffset:   4,   // empty bar slots to the right of the latest bar
};

DEFAULT_CANDLE_STYLE

export const DEFAULT_CANDLE_STYLE: CandleStyle = {
  upColor:        '#26a69a',
  downColor:      '#ef5350',
  borderUpColor:  '#26a69a',
  borderDownColor:'#ef5350',
  wickUpColor:    '#26a69a',
  wickDownColor:  '#ef5350',
  borderVisible:  true,
  wickVisible:    true,
};

CandleStyle also accepts optional hollow?: boolean (draw up-candle bodies as outlines) and widthScale?: (bar: Bar) -> number (per-bar body-width multiplier used by the volume-candle type).


DEFAULT_HISTOGRAM_STYLE

export const DEFAULT_HISTOGRAM_STYLE: HistogramStyle = {
  color: '#3a4666',
  base:  0,          // baseline value; bars extend from base to bar.close
};

DEFAULT_CANDLE_BUILDER_OPTIONS

export const DEFAULT_CANDLE_BUILDER_OPTIONS: CandleBuilderOptions = {
  intervalSec:      60,              // one-minute bars
  volumeMode:       'ltq-sum',       // accumulate last-traded-qty per tick
  lateTickPolicy:   'foldIntoBar',   // merge late ticks into the current bar
  sessionAnchorSec: 0,               // align buckets to epoch (override with session open)
};

volumeMode: 'day-delta' diffs the cumulative day-volume instead. Use CandleBuilder directly to aggregate live WebSocket ticks into interval bars.


DEFAULT_TRADING_COLORS

export const DEFAULT_TRADING_COLORS: TradingColors = {
  long:  '#2f6df6',
  short: '#ef5350',
  order: '#3b82f6',
  tp:    '#26a69a',
  sl:    '#ef5350',
  buy:   '#26a69a',
  sell:  '#ef5350',
};

Override any key via TradingController.setSettings({ longColor: '...', ... }).


DEFAULT_KEYMAP, ALT_PRESET, BUILTIN_COMMANDS

The built-in keyboard commands and their default combo bindings. Combos are expressed as physical key codes (layout-independent). See Keyboard Shortcuts for rebinding and custom commands.

CommandLabelDefault combos
panLeftPan leftArrowLeft
panRightPan rightArrowRight
panLeftFastPan left (fast)Mod+ArrowLeft
panRightFastPan right (fast)Mod+ArrowRight
panUpPan upArrowUp
panDownPan downArrowDown
zoomInZoom inEqual, Shift+Equal, NumpadAdd
zoomOutZoom outMinus, NumpadSubtract
resetScaleReset scaleHome, Digit0
fitContentFit contentAlt+KeyF
screenshotScreenshot (PNG)Alt+Shift+KeyS
toggleGridVertToggle vertical gridAlt+KeyV
toggleGridHorzToggle horizontal gridAlt+KeyH
toggleCrosshairMagnetToggle crosshair magnetAlt+KeyM

ALT_PRESET overrides a subset of the above when ShortcutManager is constructed with { preset: 'alt' }:

export const ALT_PRESET: Record<string, string[]> = {
  panLeftFast:  ['Alt+ArrowLeft'],
  panRightFast: ['Alt+ArrowRight'],
  screenshot:   ['Mod+Shift+KeyS'],
};

BUILTIN_COMMANDS is a ReadonlySet<string> containing all 14 command ids listed in the table. Use it to check whether a command string is built-in before registering a custom one with the same name.


IST_OFFSET_SECONDS

export const IST_OFFSET_SECONDS = 19800; // 5 * 3600 + 30 * 60  (UTC+5:30)

India observes no DST, so this is a fixed constant. All internal time is UTC seconds; IST conversion happens only at the feed boundary.


Tier name constants

Each opt-in tier exports a string literal constant that identifies it. These constants are useful for logging, feature detection, and avoiding bare string literals when checking which bundles have loaded. They are exported from the tier’s own entry point, not from the base bundle.

ConstantValueEntry point
PROFILE_TIER'profile'openalgo-charts/profile
TRANSFORM_TIER'transform'openalgo-charts/transform
TRADE_TIER'trade'openalgo-charts/trade
import { PROFILE_TIER   } from 'openalgo-charts/profile';
import { TRANSFORM_TIER } from 'openalgo-charts/transform';
import { TRADE_TIER     } from 'openalgo-charts/trade';

Part 2 — Helper Functions

Math helpers

src/helpers/math.ts

function clamp(value: number, min: number, max: number): number

Clamps value into the inclusive range [min, max].

function lerp(a: number, b: number, t: number): number

Linear interpolation between a and b by fraction t (0..1).

function roundToTick(value: number, step: number): number

Rounds value to the nearest multiple of step (the instrument tick size). Returns value unchanged when step <= 0. Used internally to snap dragged order/SL/TP prices to a valid tick.

function compactVolume(value: number): string

Compact number formatting for volume axes: 1.2K / 3.4M / 5.6B (values under 1000 are rounded integers). This is what addSeries(type, { priceFormat: { type: 'volume' } }) installs on the series’ price scale.


Tick generation

src/scale/ticks.ts

function niceTicks(min: number, max: number, maxTicks?: number): number[]

Generates up to maxTicks (default 6) nicely-rounded price axis labels spanning [min, max]. Steps follow the “nice number” sequence: 1, 2, 2.5, 5, 10 x 10^n. Returns a single midpoint for a degenerate (flat) range.

function precisionForStep(step: number): number

Returns the number of decimal places implied by a price step or tick size, capped at 8. Used to format axis labels. precisionForStep(0.05) -> 2.


Rendering helpers

optimalBarWidth

src/render/candles.ts

function optimalBarWidth(barSpacing: number, dpr: number): number

Returns the optimal candle body width in device pixels for a given bar spacing and device pixel ratio. Keeps a 1-px gap between candles, enforces a 1-px minimum, and matches odd/even parity with the wick so the body stays symmetric.

markerSizePx, effectiveMarkerPx, drawShape

src/primitives/markers.ts

function markerSizePx(size: MarkerSize): number

Base glyph size in CSS px for a marker size preset: tiny -> 6, small -> 9, medium -> 12, big -> 16.

function effectiveMarkerPx(size: MarkerSize, barSpacing: number): number

Same as markerSizePx but clamped so the glyph never exceeds the current bar spacing (minimum 4 px).

function drawShape(
  ctx: CanvasRenderingContext2D,
  shape: MarkerShape,
  cx: number,
  cy: number,
  px: number,
  color: string,
): void

Draws one marker glyph onto a canvas context at center (cx, cy) with diameter px. MarkerShape is: 'arrowUp' | 'arrowDown' | 'circle' | 'square' | 'triangleUp' | 'triangleDown' | 'diamond' | 'flag' | 'text'. The 'text' shape is a no-op; the caller renders the label separately.


Price scale

src/scale/price-scale.ts

function autoscaleRange(
  low: number,
  high: number,
  marginTop: number,
  marginBottom: number,
): PriceRange

Pure function: pads [low, high] by marginBottom below and marginTop above (both as fractions of the span), then returns a PriceRange { min, max }. Widens a degenerate (flat) range to ensure it is drawable.


Conflation

src/model/conflation.ts

Conflation merges many sub-pixel bars into one drawn bar, preserving candle shape. Off by default.

function conflationGroupSize(
  barSpacing: number,
  dpr: number,
  minPx?: number,  // default 0.5
  factor?: number, // default 1
): number

Returns 1 (no conflation) while bars are at least minPx wide; otherwise returns the group size needed to bring each drawn bar above that threshold.

function mergeBars(group: readonly Bar[]): Bar

Merges a group of bars into one OHLC-preserving bar: open = first, close = last, high = max, low = min, volume = sum. Uses the first bar’s time.

function conflateBars(bars: readonly Bar[], groupSize: number): Bar[]

Splits bars into consecutive groups of groupSize and merges each via mergeBars. Identity when groupSize <= 1.

function conflateItems<T extends { x: number; bar: Bar }>(
  items: readonly T[],
  groupSize: number,
): { x: number; bar: Bar }[]

Same as conflateBars but operates on already-projected draw items (which carry an x position); x is set to the group center.


Chart-type registry

src/model/chart-type-registry.ts

function registerChartType(type: SeriesType | string, entry: RendererEntry): void

Registers a custom (or replacement) renderer for a series type name. RendererEntry carries defaultStyle, isPriceSeries, a draw function, and an extents function for autoscale. See Primitives and Plugins.

function getChartType(type: SeriesType | string): RendererEntry

Looks up a registered renderer; throws if the type is unknown. Types 'point-figure' and 'kagi' require import 'openalgo-charts/transform' first.

function registeredChartTypes(): string[]

Returns an array of all currently registered type names.


Gradient

src/render/gradient.ts

function verticalGradient(
  ctx: CanvasRenderingContext2D,
  heightPx: number,
  topColor: string,
  bottomColor: string,
): CanvasGradient

Returns a cached vertical CanvasGradient for area/baseline fills. Gradients are cached per context and per (height, topColor, bottomColor) triple so they are not recreated on every frame.


Canvas

src/core/canvas.ts

function bitmapSize(mediaWidth: number, mediaHeight: number, dpr: number): Size

Pure: returns { width: Math.round(mediaWidth * dpr), height: Math.round(mediaHeight * dpr) }. The bitmap (backing buffer) size for a HiDPI canvas.

function snapToDevicePixel(mediaCoord: number, dpr: number): number

Pure: snaps a media-space coordinate to a crisp device-pixel edge. Avoids sub-pixel blurring on retina displays. Math.round(mediaCoord * dpr) / dpr.


Indicators

src/indicators/ema.ts, rsi.ts, atr.ts, supertrend.ts

See Indicators for full usage examples. Signature quick-reference:

// EMA
function ema(values: readonly number[], period: number): number[]
function emaSeries(bars: readonly Bar[], period: number): Bar[]
 
// RSI -- Wilder smoothing; NaN during warmup (first `period` slots)
function rsi(values: readonly number[], period?: number /* default 14 */): number[]
function rsiSeries(bars: readonly Bar[], period?: number /* default 14 */): Bar[]
 
// ATR -- Wilder ATR; first ATR value lands at index period-1, earlier slots NaN
function trueRange(high: readonly number[], low: readonly number[], close: readonly number[]): number[]
function atr(high: readonly number[], low: readonly number[], close: readonly number[], period?: number /* default 14 */): number[]
 
// Supertrend -- direction: -1 = uptrend (support below price), +1 = downtrend
function supertrend(bars: readonly Bar[], period?: number /* default 10 */, multiplier?: number /* default 3 */): SupertrendPoint[]
function supertrendSeries(bars: readonly Bar[], period?: number, multiplier?: number): { up: Bar[]; down: Bar[] }

supertrendSeries returns two separate Bar[] arrays where the inactive direction carries NaN for every bar, so each renders as its own segment that swaps color at trend flips.

All series helpers return Bar[] (OHLC all set to the indicator value) so you can call series.setData(emaSeries(bars, 20)) directly.


Feed helpers

generateBars

src/feed/fake-feed.ts

function generateBars(startTime: number, count: number, intervalSec: number): Bar[]

Deterministic synthetic bar generator using xorshift32. Produces a reproducible OHLC random walk from a fixed seed; no Math.random or Date.now. Used in demos and snapshot tests.

intervalToSeconds

src/feed/openalgo-live.ts

function intervalToSeconds(interval: string): number

Maps an interval token to seconds: '1m' -> 60, '5m' -> 300, '1h' -> 3600, 'D' -> 86400, 'W' -> 604800. The bare daily/weekly tokens D and W are supported alongside 1d/1w. Unknown tokens fall back to 60. Accepts case-insensitive suffixes s, m, h, d, w.

mapHistoryResponse, rowTimeToUtcSeconds

src/feed/openalgo-rest.ts

function rowTimeToUtcSeconds(value: number | string): number

Coerces a row timestamp to UTC seconds. Accepts epoch seconds (integer), epoch milliseconds (heuristic: value > 1e12), or an IST date/time string (YYYY-MM-DD[ HH:MM[:SS]]).

function mapHistoryResponse(json: { data?: HistoryRow[] }): Bar[]

Maps an OpenAlgo /api/v1/history response envelope to a sorted Bar[]. Handles both timestamp and time field names, and all three timestamp formats via rowTimeToUtcSeconds.


Time helpers

src/feed/time.ts

All internal time is UTC seconds. These functions convert at the feed boundary only.

// Fixed offset in seconds for IST (UTC+5:30, no DST)
const IST_OFFSET_SECONDS = 19800
 
// Epoch milliseconds -> UTC seconds
function epochMsToUtcSeconds(ms: number): number
 
// IST wall-clock string ('YYYY-MM-DD', 'YYYY-MM-DD HH:MM', 'YYYY-MM-DD HH:MM:SS') -> UTC seconds
function istStringToUtcSeconds(input: string): number
 
// UTC seconds -> IST calendar parts { year, month, day, hour, minute, second, weekday }
function utcSecondsToIstParts(utcSeconds: number): IstParts
 
// UTC seconds -> IST date string for OpenAlgo REST requests ('YYYY-MM-DD')
function utcSecondsToIstDateString(utcSeconds: number): string
 
// UTC seconds -> IST 'HH:MM' label
function formatIstTime(utcSeconds: number): string
 
// UTC seconds -> IST 'HH:MM:SS' label (sub-minute / tick timeframes)
function formatIstTimeSeconds(utcSeconds: number): string
 
// UTC seconds -> IST 'DD Mon' label (e.g. '21 May')
function formatIstDate(utcSeconds: number): string
 
// True when two UTC-second instants fall on different IST calendar days
function isNewIstDay(prevUtcSeconds: number, utcSeconds: number): boolean

Quick example

Using generateBars for a demo chart, plus clamp and roundToTick for order price clamping:

import { createChart, generateBars, clamp, roundToTick } from 'openalgo-charts';
 
const chart = createChart(document.getElementById('chart')!);
const series = chart.addSeries('candlestick');
 
// 300 bars of synthetic OHLC starting at a known epoch, 5-minute interval
const bars = generateBars(1_700_000_000, 300, 300);
series.setData(bars);
 
// Snap a user-dragged price to the nearest 0.05 tick, bounded by the visible range
function sanitizeOrderPrice(raw: number, lo: number, hi: number): number {
  return clamp(roundToTick(raw, 0.05), lo, hi);
}

To add a live EMA overlay from real data:

import { emaSeries } from 'openalgo-charts';
 
const emaSeries20 = chart.addSeries('line', { style: { color: '#f59e0b' } });
emaSeries20.setData(emaSeries(bars, 20));