Vercel Composition Patterns
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
A skill your agent uses when building, configuring, extending or debugging openalgo-charts in a consumer app or the source repository, including chart navigation, drawing tools, indicators…
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install marketcalls/openalgo-charts openalgo-charts --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/openalgo-charts .claude/skills/openalgo-charts && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .claude/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-chartsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install marketcalls/openalgo-charts openalgo-charts --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.github/skills/openalgo-charts .agents/skills/openalgo-charts && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .agents/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install marketcalls/openalgo-charts openalgo-charts --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.github/skills/openalgo-charts .cursor/skills/openalgo-charts && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .cursor/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/marketcalls/openalgo-charts.git --path .github/skills/openalgo-charts--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install marketcalls/openalgo-charts openalgo-charts --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.github/skills/openalgo-charts .gemini/skills/openalgo-charts && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .gemini/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install marketcalls/openalgo-charts openalgo-chartsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .github/skills && cp -r skills-src/.github/skills/openalgo-charts .github/skills/openalgo-charts && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .github/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install marketcalls/openalgo-charts openalgo-charts --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/marketcalls/openalgo-charts.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.github/skills/openalgo-charts .opencode/skills/openalgo-charts && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "openalgo-charts" agent skill from https://github.com/marketcalls/openalgo-charts/tree/master/.github/skills/openalgo-charts into .opencode/skills/openalgo-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "openalgo-charts", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
openalgo-chartsA skill your agent uses when building, configuring, extending or debugging openalgo-charts in a consumer app or the source repository, including chart navigation, drawing tools, indicators…
Openalgo Charts is an agent skill from marketcalls/openalgo-charts. Use when building, configuring, extending or debugging openalgo-charts in a consumer app or the source repository, including chart navigation, drawing tools, indicators, profiles, live feeds, replay, widgets and framework hosts.
Its SKILL.md is about 7.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 27 other files, including reference files (for example `references/alerts.md`, `references/bundling-and-tiers.md` and `references/chart-linking.md`).
It sits in Development. The repository describes itself as: Production-grade charts built for brokers, exchanges, trading platforms, and financial portals. Bring your own market data, plug it in, and deliver a complete charting experience… The licence is Apache-2.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 8b4cffe. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
rgnpmnodeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Openalgo Charts loads about 7.6k tokens when it runs, and up to ~275k if it reads all its reference files. Until then it costs about 61 tokens; SKILL.md has 3,030 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from marketcalls/openalgo-charts at commit 8b4cffe, republished under its Apache-2.0 licence (© marketcalls). 3,030 words, ~7,560 tokens.
.claude/skills/openalgo-charts/SKILL.md (or your agent's skills folder). This skill also uses 26 other files; get the full folder from GitHub.openalgo-charts is a from-scratch, dependency-free HTML5-canvas charting engine: a canvas rendering pipeline with vector export, no DOM per bar, nine bundle entry points, zero runtime dependencies.
Works the same whether the project is a downstream npm consumer app or an upstream openalgo-charts source checkout. Detect which one you are in and resolve every API name from whatever typings are locally available.
Do not assume you are inside the upstream source repository.
node_modules/openalgo-charts/package.json for the actual version.node_modules/openalgo-charts/dist/index.d.ts for the base API surface, and dist/{trade,draw,indicators,transform,profile,webgl,widget,workspace}/index.d.ts for each tier.dist/index.d.ts first, then src/ if generated output is unavailable.ARCHITECTURE.md and website/pages/docs/*.mdx are supporting evidence, but local typings win when they disagree.Verify before answering (copy-paste):
node -p "require('./node_modules/openalgo-charts/package.json').version"
rg -n "createChart|addSeries|addIndicator|DrawingController|OrderEngine" node_modules/openalgo-charts/dist/index.d.ts
# upstream checkout instead of a consumer app:
rg -n "createChart|addSeries|addIndicator" dist/index.d.ts src/index.ts
# which tiers does this project actually load?
rg -n "from 'openalgo-charts" src appIf the relevant file is unavailable, say what could not be verified. Do not invent option names, methods, exports, event names, or indicator ids.
Eight layers, in dependency order. Most bugs come from confusing one for another.
createChart(container, options) returns a Chart. One chart per container element. It owns everything below.0..N-1. This is the load-bearing idea; see rule 2 below.chart.timeScale maps logical index to x; each pane's PriceScale maps price to y. Panes autoscale independently.'right', 'left', '' overlay).chart.addSeries(type, options) returns a SeriesApi. The type names an entry in the chart-type registry; the core never switches on type.indicators, draw, transform, profile, trade, webgl are separate bundles that register what they add on import (the draw tier into its own tool registry, the others into the base engine's registries); widget sits above them all and is the one tier that builds DOM.npm install openalgo-chartsImport only what you use. Each tier is a separate entry point, so a feature you do not load costs zero bytes. The workspace tier is pure configuration and persistence; it registers nothing.
| Import | Contents | Brotli limit |
|---|---|---|
openalgo-charts | Engine, 13 chart types, panes and scales, primitives, registries, chart state and settings schema, market replay, symbol comparison, chart linking with appearance adapters, grouped timeline events, shared loading controller, request pool, warm-load bar cache, interval registry, chart timezone, trading visualization, OpenAlgo feeds, EMA/RSI/ATR/Supertrend calculators, vector SVG export, the render backend port | 95.50 kB |
openalgo-charts/indicators | 112 built-in indicators + the Tier-2 external-data contract | 30 kB |
openalgo-charts/draw | 87 drawing tools, including Anchored VWAP and fixed-range Volume Profile, opt-in drawing links and a headless DrawingController with multi-select, z-order, a per-tool settings schema, the 1.9.x migration, the clipboard and the icon builders | 41 kB |
openalgo-charts/transform | Heikin Ashi, Renko, Range bars, Line Break, Point and Figure, Kagi | 6 kB |
openalgo-charts/profile | Volume Profile, Market Profile (TPO), Footprint, order flow | 15 kB |
openalgo-charts/trade | Order engine, state machine, order/position/bracket lines, DOM ladder | 103.50 kB with base |
openalgo-charts/webgl | The WebGL2 series backend behind renderer: 'auto' | 'webgl2'; composites into the pane's canvas, falls back to 2D for the session on context loss | 7 kB |
openalgo-charts/widget | createWidget: the chart with a top bar, drawing rail, responsive mobile controls, status line, settings and indicator dialogs, drawing properties, event details, right-click menu, keymap and optional persistence. The only tier that ships DOM; imports the draw tier itself | 51.50 kB |
openalgo-charts/workspace | Portable workspace/template documents, asynchronous catalog repository and atomic IndexedDB adapter; no UI or market data | 6 kB |
Limits are the CI-enforced budgets in .size-limit.json. This reference targets 2.6.0; a
section marked (unreleased) is on the main branch only and is not in that release.
In a source checkout, run npm run size before quoting byte counts. In a consumer app,
check the installed version and measure its actual imports with the app's bundler.
Reference measurements and every budget row live in bundling-and-tiers.
The clipboard lives in the draw tier, not the base one, because it needs the drawing-tool registry. DrawingClipboard and friends come from openalgo-charts/draw.
import { createChart } from 'openalgo-charts';
const chart = createChart(document.getElementById('chart')!);
const series = chart.addSeries('candlestick');
series.setData([
{ time: 1705286700, open: 100, high: 101, low: 99.5, close: 100.6, volume: 1200 },
{ time: 1705286760, open: 100.6, high: 101.4, low: 100.2, close: 101.1, volume: 900 },
]);
chart.fitContent();time is UTC seconds. The container must have a non-zero size before the chart can lay out.
Math.floor(Date.now() / 1000), not Date.now(). Feed adapters convert broker formats at the edge. Which wall clock those seconds are labelled in is ChartOptions.timezone, an IANA name defaulting to Asia/Kolkata; never offset the timestamps themselves to fake a zone, or every session anchor and gap moves with them.logicalIndex * barSpacing, so weekends, holidays and session breaks have no index and collapse to nothing. Never compute an x from a timestamp difference; use chart.timeToCoordinate(t) or chart.timeScale.indexToTimeFloat and time back to index on the receiver with timeToIndex / timeToIndexFloat, against that chart's own DataLayer. createLinkGroup, followerIndex and followerRange do this; a hand-rolled b.setVisibleLogicalRange(a.getVisibleLogicalRange()) does not, and it looks correct until the two charts hold different bars. An instant outside the receiver's first or last bar is an absence: draw nothing rather than clamping to an edge bar. See chart-linking.withBarCache drops trailing unclosed bars for this reason. A fast wrong price is a worse failure than a slow right one on a chart that draws Buy and Sell buttons.import { X } from 'openalgo-charts' or a published tier specifier only. A deep path into dist/ internals inlines a second copy of the registry Map, and createChart will never see what your tier registered. See rollup.config.js.chart.addIndicator('macd') needs import 'openalgo-charts/indicators'; addSeries('kagi') needs import 'openalgo-charts/transform' and throws a specific tier-naming error without it.1 - marginTop - marginBottom of the pane.{ time, price }, never pixels. Pixel anchors slide the moment a gap collapses or the user zooms.dpr in any custom primitive, or it blurs and misaligns on HiDPI.chart.trading renders trade state; it does not place orders. The host pushes exchange state in and turns the emitted trading:* events into broker calls. The transactional path is openalgo-charts/trade.openalgo-charts/widget is the one tier that does. The base and the seven non-widget optional tiers have no toolbar, no dialogs, no settings forms, no command palette. Drawing tools, indicator settings, replay transports and order menus are the host's UI, driven by descriptors and events. A host that does not want to write that chrome imports the widget tier and calls createWidget (see widget); a host that does gets the description of that UI: chartSettingsSchema(chart) for a settings dialog, the contextmenu event for a right-click menu, and chart.priceAxisState(...) for a menu raised on a price axis. Chrome you write is held to the UI standard in themes-and-styling: styled scrollbars, small square swatches, paired up/down colours on one row, themed form controls, and no control with nothing behind it.PriceLevels.available(kind) and PriceAxisState.active / scaled / movable exist to be read for exactly this. Hiding it loses the information that the state is off.Detailed reference for each topic is in references/. Read the one that matches the task before writing code.
| Reference | Topic |
|---|---|
| core-api | createChart, ChartOptions, SeriesApi, lifecycle, coordinate conversion, the render/invalidation model |
| chart-types | All 13 base series types, their styles and autoscale rules, runtime type switching |
| scales-and-panes | Price/time scale options, log and inverted modes, left/right/overlay scales, per-axis state and moves, axis chrome (corner clock, bar countdown, tick priority), pane weights and layout |
| themes-and-styling | ChartTheme keys, dark/light, gradients, SeriesStyle precedence, price formatting, and the UI standard for host chrome |
| data-and-time | Bar shape, UTC seconds, the chart timezone and the time helpers, setData/update/prependData, the logical-index model, history paging, tick and volume bars |
| feeds-and-live | DataFeed contract, OpenAlgo REST/WS/live feeds, CandleBuilder, the interval registry, withBarCache warm loading, writing a custom feed |
| events-and-state | The full event catalogue with payloads, getState/restoreState, saved layouts |
| alerts | Headless trader alerts, confirmed versus intrabar timing, lifecycle, expiry and host delivery |
| indicators | The 112 built-ins with exact ids, placements and input defaults, the settings model, levels/ranges/fills, signal markers, registerIndicator, the Tier-2 external-data contract |
| transforms | Heikin Ashi, Renko, Range, Line Break, Point and Figure, Kagi |
| drawing-tools | The 87 tools, DrawingController, anchors, magnet, undo, copy/cut/paste and the clipboard payload, persistence, shortcuts, custom tools |
| primitives-and-plugins | IPrimitive, z-order, hit-testing, the dpr contract, built-in primitives including the PriceLevels reference-level family, registerChartType |
| replay-and-compare | ReplayController and its transport events, addComparison, the overlay-scale mechanism, timestamp alignment |
| chart-linking | createLinkGroup, the sync-by-instant rule, followerIndex / followerRange, the linked crosshair, host-driven symbol, interval and chart type sync, appearance adapters, the drawings channel over DrawingLinkGroup, and saved link groups (WorkspaceSync) |
| settings-and-menus | chartSettingsSchema and its round trip, the five tabs, the colorPair row, the timezone control, canvas options (grid, crosshair, scales, margins), status-line switches, the contextmenu event and the price-axis menu |
| trading | The data-driven on-chart trading layer, trading:* events, order/position/bracket lines |
| trade-tier | OrderEngine, order state machine, validation, analyzer mode, DOM ladder, broker adapters |
| profiles-and-orderflow | Volume Profile, Market Profile (TPO), Footprint, cumulative delta, the trade-data dependency |
| react-integration | React and Next.js lifecycle, keeping orchestration out of React, SSR, resize |
| vue-integration | Vue 3 composable and component, keeping the chart out of ref()/reactive(), props to data, KeepAlive, Nuxt |
| bundling-and-tiers | Entry points, registry identity, tree-shaking, script/ESM/import-map loading, size budget |
| widget | createWidget and the widget tier: options, the handle, events, the context every dialog is handed, the keymap scopes, the tokens, every exported mount and helper, packaging |
| workspaces | Portable multi-chart workspaces, indicator templates, async catalog transactions, account namespaces and atomic browser storage |
| interactions | Two-axis panning, optional horizontal mouse/pen pan, axis drag, navigator reset, default visible bars, keyboard and accessibility |
| host-integration | Hidden-tab startup, paging/replay isolation, stale async work, registration readiness, and upstream browser validation |
| pitfalls | The verified foot-gun list. Read this when something behaves unexpectedly |
| User asks about | First check | Answer with | Avoid |
|---|---|---|---|
| First chart / blank chart | container size, dist present | createChart + addSeries + setData; hidden charts fit on their first measurable layout | assuming data needs to be fetched again when a tab opens |
| Upgrade a 1.9.x drawing host | drawing model | DrawingText, FibLevel[], versioned drawings, multi-selection and schema controls | writing text into DrawingStyle or treating toJSON() as an array |
| Recent-bar default / chart drifts vertically | navigation | navigation.defaultVisibleBars, horizontal mousePan, resetScale() | trimming history or overriding the preference with fitContent() |
| Trackpad zoom or price jumps during navigation | interactions | normalized proportional wheel input, price-axis scaling and animAutoscale | mapping every wheel event to the same zoom step or replacing a manual price range |
| Touch controls or a narrow dashboard chart | widget | mobile: 'auto', 'always' or 'never'; shared drawing state and tool allowlist | assuming the headless engine supplies widget chrome |
| Compact TPO or demo palettes | profiles | per-session split, markers, explicit palette options | inventing a library theme preset |
| Replay changes during recovery / late symbol response | host integration | generation and request-owner guards around every writer | assuming replay owns the host feed or timers |
| Bars in the wrong place | units of time | UTC seconds | Date.now() milliseconds |
| Axis shows the wrong hours | chart.timezone() | timezone: 'America/New_York' on createChart, or setTimezone | shifting bar timestamps, or a timeFormatter that only relabels |
| Gaps for weekends | the gapless-axis rule | it is intended; whitespace points if you want a gap | shifting timestamps |
| Realtime ticks | last-bar vs full replace | series.update(bar) | setData on every tick |
| Loading older history | setHistoryLoader | prependData + historyLoadComplete | rebuilding and re-fitting |
| Indicator not found | is the tier imported | import 'openalgo-charts/indicators' | registering it by hand |
| Which indicator id to use | the catalogue in indicators | the exact id from the 112-row table, guarded with hasIndicator(id) | guessing an id from the display name |
| Indicator settings UI | descriptor inputs + generated style keys | build the form from the descriptor, apply with setSettings; or openalgo-charts/widget (mountIndicatorSettings, or the whole terminal via createWidget) for a host that does not want to write chrome | expecting the engine itself to have a dialog |
| Drawing tools | DrawingController | headless controller + host toolbar; or createWidget from openalgo-charts/widget, which ships the rail | expecting the engine itself to have a toolbar |
| Volume in its own pane | paneIndex and priceScaleId | addSeries('histogram', { paneIndex: 1 }) | a second chart |
| Volume inside the price pane | overlay scale | priceScaleId: '' plus scale margins | manual y math |
| Placing real orders | which layer | openalgo-charts/trade OrderEngine | chart.trading (visualization only) |
| Order lines on the chart | which layer | chart.trading sync + trading:* events | drawing your own price lines |
| Custom overlay | primitive vs chart type | IPrimitive + addPrimitive | a custom chart type for decoration |
| Bar-by-bar replay | ReplayController | headless controller + host transport bar; indicators rebuild from the prefix | a second chart, or slicing data by hand |
| Two symbols on one chart | addComparison | hidden overlay scale + a rebasing pane mode | a second series on the same price axis |
| A grid of charts moving together | createLinkGroup | independent cursor, viewport, symbol, interval, chart type, appearance and drawings channels (drawings moved by the draw tier's DrawingLinkGroup); everything syncs by time, never by logical index | copying getVisibleLogicalRange() between charts |
| Linked crosshair shows the wrong bar | the index-to-time conversion | followerIndex(target.dataLayer, time, whenMissing) | assuming index N is the same instant on both charts |
| Port a study that reads a higher timeframe, draws ahead of the last bar, or compares against another symbol | coverage additions (2.4.0) | securitySeries, plot.offset, ctx.requestBars with chart.setBarsProvider, IndicatorInputError | folding bars by hand, emitting future times into the axis, or fetching a benchmark from inside calc |
| Slaving the symbol across charts | who owns the instrument | the host emits 'symbol' / calls setSymbol, each member gets an onSymbol loader | expecting the engine to know what a symbol is |
| Copy and paste a drawing | draw.copy() / cut() / paste() | await them; the host owns the key chords | a synchronous call, or throwing on foreign clipboard text |
| Refetching the same bars on every switch | withBarCache(feed, opts) | wrap the feed; key is symbol/exchange/interval, range is sliced | caching the forming bar, or keying on the range |
| A monthly / tick / volume timeframe | registerInterval | a Bucketing rule (calendar, ticks, volume), then bucketStartOf | intervalToSeconds on a code that has no fixed length |
| Unknown interval code | isKnownInterval(code) | validate the picker; resolveInterval throws UnknownIntervalError | catching the throw and defaulting to 60 seconds |
| Percent / rebased axis | priceScale.mode | 'percentage' or 'indexed-to-100' plus a baseline | recomputing the data into percentages |
| Settings dialog | chartSettingsSchema(chart) | render the tabs, round-trip with read/applyChartSettings; or mountSettingsDialog / createWidget from openalgo-charts/widget | hardcoding a control list |
| Right-click menu | contextmenu event | preventDefault() + target.kind | hit-testing the pointer yourself |
| Menu on a price axis | target.side / target.scaleId | chart.priceAxisState(pane, scaleId), acted on by the setPriceAxis* calls | assuming pane 0's right scale |
| Previous close, session high/low, bid/ask lines | PriceLevels | one primitive, one options group per level, line and label together | a PriceLine per level with its own tag bookkeeping |
| A level or axis row with no data | available(kind), state.active | render it disabled with its state visible | hiding the control |
| Corner clock, bar-close countdown | ChartOptions.axisChrome | { sessionClock: true, barCountdown: true }, plus a clock for a delayed feed | a DOM overlay positioned over the axis |
| Named multi-chart layouts and templates | workspaces | WorkspaceRepository plus a storage adapter; each pane carries getState() | treating a single chart snapshot as the whole host workspace |
| Watchlists with live prices, or symbol news | widget, workspaces | WatchlistRepository plus a QuoteFeed and a NewsFeed, as the widget's watchlist and news options | pricing a row from the last candle, or rendering provider text as HTML |
| React lifecycle | where the chart instance lives | create in an effect, hold in a ref, chart.destroy() on cleanup | chart instance in state |
| Vue lifecycle, or replay and picks misbehaving in a Vue app | is the chart in ref() or reactive() | shallowRef or markRaw, create in onMounted, destroy() in onBeforeUnmount; see vue-integration | ref(chart), which hands back a proxy the library does not recognise as its chart |
| Bundle size | which tiers are imported | drop the unused tier import | code-splitting the base |
Verified names. Get these wrong and nothing works.
// chart
const chart = createChart(el, options);
chart.addSeries(type, { paneIndex, style, priceScaleId, priceFormat });
chart.addIndicator(id, settings, { paneIndex }); // needs the indicators tier
chart.addPriceLine(opts, paneIndex);
chart.addPrimitive(primitive, paneIndex);
chart.fitContent(); // explicitly fit all loaded history
chart.resetScale(); // preferred default view + all price scales
chart.setNavigationOptions({ mousePan: 'both', defaultVisibleBars: 120 });
chart.navigationOptions();
chart.applyOptions({ theme, grid, canvas, statusLine, priceScale, priceFormatter, timeFormatter, timezone, crosshairMode });
chart.setTheme(theme);
chart.setTimezone('America/New_York') / chart.timezone(); // IANA name, default 'Asia/Kolkata'
chart.panes(); // readonly Pane[]
chart.primarySeries() / chart.primarySeriesInfo();
chart.setCanvasOptions(opts) / chart.setStatusLineOptions(opts) / chart.setPriceScaleOptions(opts);
chart.setAxisChromeOptions({ sessionClock: true, barCountdown: true }) / chart.axisChromeOptions();
// one price axis at a time (what a menu on an axis strip acts on)
chart.priceAxisState(paneIndex, scaleId); // PriceAxisState | null
chart.setPriceAxisOptions(paneIndex, scaleId, patch);
chart.setPriceAxisAutoFit(paneIndex, scaleId, on);
chart.setPriceAxisLockRatio(paneIndex, scaleId, on); // boolean
chart.movePriceAxis(paneIndex, 'right', 'left'); // boolean
PRICE_SCALE_MODES; // ['linear','logarithmic','percentage','indexed-to-100']
chart.getState() / chart.restoreState(state);
chart.on(event, cb); // returns an unsubscribe function
chart.subscribeCrosshairMove(cb);
chart.timeToCoordinate(t) / chart.coordinateToTime(x);
chart.priceToCoordinate(p, paneIndex) / chart.coordinateToPrice(y, paneIndex);
chart.destroy(); // idempotent; emits 'destroy', then drops every listener
chart.isDestroyed; // getter, not a method
// getters, not methods
chart.timeScale; // TimeScale
chart.dataLayer; // DataLayer
chart.trading; // TradingController, created on first access
chart.shortcuts; // ShortcutManager | null
// series handle
series.setData(items);
series.update(item);
series.prependData(items);
series.getData();
series.applyOptions({ visible: false }); // not setStyle
series.priceScale();
series.createMarkers();
series.remove();
// headless controllers, base bundle, no tier import
new ReplayController(chart, { bars, startIndex, barMs }); // seek/step/play/pause/stop/state
addComparison(chart, { symbol, bars }); // setBars/remove/list/alignment
chartSettingsSchema(chart) / readChartSettings(chart) / applyChartSettings(chart, patch);
// linked chart grid (base bundle). Syncs by INSTANT, never by logical index.
const group = createLinkGroup({ crosshair: true, viewport: true, symbol: false, whenMissing: 'nearest' });
group.add(chart, { symbol: 'RELIANCE', onSymbol: (s, c) => loadBars(s, c) });
group.remove(chart) / group.setOptions(patch) / group.setSymbol(chart, s) / group.destroy();
group.members() / group.has(chart) / group.symbol() / group.crosshairIndex(chart);
followerIndex(followerDataLayer, timeSec, 'nearest' | 'hide'); // number | null
followerRange(leaderDataLayer, followerDataLayer, range); // LogicalRange | null
// warm-load bar cache: wraps ANY DataFeed (base bundle)
const feed = withBarCache(sourceFeed, { ttlMs, max, maxBars, storage, now, barCloses });
feed.getBars({ symbol, exchange, interval, from, to, noCache: true });
feed.invalidate({ symbol, exchange, interval }) / feed.clear() / feed.stats() / feed.source;
// interval registry (base bundle): a bucketing rule, not a duration
registerInterval({ code: '1MO', bucketing: { mode: 'calendar', unit: 'month', count: 1 } });
resolveInterval(code) // throws UnknownIntervalError
tryResolveInterval(code) / isKnownInterval(code) / registeredIntervals() / unregisterInterval(code);
bucketStartOf(bucketing, timeSec, zone?) / nextBucketStart(...) / isTimeBucketed(bucketing);
// drawing clipboard (draw tier) - all async
await draw.copy(target?) / await draw.cut(target?) / await draw.paste();
draw.clipboard().lastError();
// reference levels (a primitive: previous close, session high/low, bid/ask, ...)
const levels = new PriceLevels({ levels: { previousClose: { line: true, label: true } } });
chart.addPrimitive(levels); // the price pane, wherever it sits
levels.setLevel(kind, patch) / levels.setQuote(q) / levels.values() / levels.available(kind);
computePriceLevels({ bars, anchorTime }); // the same numbers, pure, no canvaschart.fitContent() takes no arguments; chart.timeScale.fitContent(barCount) does.
shallowRef; a vanilla user wants neither; a no-bundler user gets <script type="module"> from dist/ or a CDN, or the script-tag files when the page cannot load modules.When answering an openalgo-charts question:
© marketcalls, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 26 other files (references) in .github/skills/openalgo-charts of marketcalls/openalgo-charts.
Open the folder on GitHubat commit 8b4cffe
Openalgo Charts next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Openalgo Charts this skillmarketcalls/openalgo-charts | 146 | — | ~7.6k | Automated safety check: Pass | Apache-2.0 | |
| Vercel Composition Patternssupabase/supabase | 111k | 58 repos | ~726 | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 297k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Typescript Advanced Typesrolling-scopes/rsschool-app | 10k | 25 repos | ~4.2k | Automated safety check: Pass | MPL-2.0 | |
| PR Babysitteropeninterpreter/openinterpreter | 69k | 3 repos | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 4 repos | ~1.1k | Automated safety check: Pass | MIT |
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
rolling-scopes/rsschool-app
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications.
openinterpreter/openinterpreter
Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
onyx-dot-app/onyx
Iteratively improves a PR (GitHub), MR (GitLab), or shelved changelist (Perforce) until Greptile gives it a 5/5 confidence score with zero unresolved comments.
marketcalls/openalgo-charts
Diagnose an openalgo-charts problem - blank or invisible chart, bars in the wrong place, unknown series type or indicator errors, misaligned indicators, drawings that drift, a chart that will not…
marketcalls/openalgo-charts
Add a built-in openalgo-charts indicator, restyle it, build a settings UI from its descriptor, or author a custom indicator with registerIndicator or the Tier-2 external-data contract.
marketcalls/openalgo-charts
Extend openalgo-charts with a custom primitive, drawing tool, chart type, or indicator descriptor.
marketcalls/openalgo-charts
Scaffold a working openalgo-charts chart in an existing project - detects the host (React, Next.js, Vue, vanilla bundler, or plain script tag), installs the right tiers, and writes a chart that…
marketcalls/openalgo-charts
Build a full trading terminal on openalgo-charts - symbol search, interval switcher, chart-type picker, indicator menu, drawing rail with clipboard, live OpenAlgo REST plus WebSocket data behind a…
Categories
A skill your agent uses when building, configuring, extending or debugging openalgo-charts in a consumer app or the source repository, including chart navigation, drawing tools, indicators…. Openalgo Charts is an agent skill from marketcalls/openalgo-charts. Use when building, configuring, extending or debugging openalgo-charts in a consumer app or the source repository, including chart navigation, drawing tools, indicators, profiles, live feeds, replay, widgets and framework hosts.
Openalgo Charts fits situations like: debugging openalgo-charts in a consumer app; the source repository; including chart navigation; widgets and framework hosts.
Run `npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a claude-code`. Or copy the skill folder (.github/skills/openalgo-charts in marketcalls/openalgo-charts) into .claude/skills/openalgo-charts in your project. Claude Code loads it when a task matches its description.
Run `npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a codex`. Or copy the skill folder (.github/skills/openalgo-charts in marketcalls/openalgo-charts) into .agents/skills/openalgo-charts in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add marketcalls/openalgo-charts --skill openalgo-charts -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/openalgo-charts, .gemini/skills/openalgo-charts, .github/skills/openalgo-charts and .opencode/skills/openalgo-charts in your project.
Going by SKILL.md and its folder, Openalgo Charts needs the command-line tools its instructions call (rg, npm and node). Our summary lists: Node.js.
SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Openalgo Charts is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.6k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 267k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Openalgo Charts: Vercel Composition Patterns (supabase/supabase, 111k stars), Finishing a Development Branch (obra/superpowers, 297k stars), Typescript Advanced Types (rolling-scopes/rsschool-app, 10k stars) and PR Babysitter (openinterpreter/openinterpreter, 69k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
marketcalls (a GitHub user) maintains it in marketcalls/openalgo-charts, which has 146 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 1, 2026.
Source: marketcalls/openalgo-charts on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.