Documentation
TickerFlow is a high-performance, professional-grade HTML5 charting library built with TypeScript and optimized for financial applications.
Getting Started
Follow these steps to get TickerFlow running in your application. The process takes less than 5 minutes.
Create Your Account
Sign up for a TickerFlow account to access your dashboard and manage your Professional license.
Get Professional LicenseProfessional License
Obtain your Professional license key ($499/year) which includes unrestricted access to all charting engine features, indicators, and priority support.
- All Technical Indicators
- Real-time Streaming
- Custom Indicators API
- Priority Support
Get Your License Key
After signing up, go to your dashboard and create a license key. This key unlocks features based on your plan.
SP-A1B2C3D4-E5F6G7H8-XY12Get the Library
Choose your preferred method to integrate the TickerFlow engine:
Download the optimized production build (`tickerflow-chart.js`) directly from your dashboard. This allows you to self-host the library on your internal infrastructure for maximum performance and security.
Download from Dashboard1npm install @tickerflow/corePrivate npm registry access is available for Enterprise infrastructure.
Initialize with Your License Key
Add your license key when initializing the chart. Store it in environment variables for security.
Environment variables (.env file):
1# .env.local (Next.js) or .env (Vite/React)
2NEXT_PUBLIC_TICKERFLOW_KEY=SP-A1B2C3D4-E5F6G7H8-XY12
3NEXT_PUBLIC_ALPACA_KEY=your_alpaca_api_key
4NEXT_PUBLIC_ALPACA_SECRET=your_alpaca_secret_keyInitialize the chart:
1const chart = new StockChart.StockChartWidget({
2 ticker: 'XXXX', // Use 'XXXX' for simulated live data
3 apiKey: process.env.NEXT_PUBLIC_ALPACA_KEY,
4 secretKey: process.env.NEXT_PUBLIC_ALPACA_SECRET,
5 licenseKey: process.env.NEXT_PUBLIC_TICKERFLOW_KEY,
6 theme: 'dark',
7 defaultTimeframe: '15m',
8});
9
10chart.mount(document.getElementById('chart-container'));Build Your First Workspace
From an end‑user perspective, the workflow is simple: load a chart, set your market, add indicators, and save your layout or workspace for later use.
- Search a ticker, set timeframe, and theme.
- Add indicators and drawings from the toolbars.
- Save a layout, then create a workspace with multiple charts.
- Switch between saved workspaces anytime.
You're Ready!
Your chart is now live! Continue reading for framework-specific examples and advanced features.
Quick tip: The license key is validated automatically. Features are enabled based on your plan tier.
License Tiers & Features
- All Chart Types (Candlestick, Line, Area)
- All Technical Indicators
- Real-time Streaming
- Custom Indicators API
- Unlimited Data Points
- Unlimited Chart Instances
- White-label (Remove branding)
- Priority Support
Vanilla JavaScript / HTML
Perfect for simple websites, WordPress, or legacy applications.
1<!DOCTYPE html>
2<html>
3<head>
4 <title>My Trading App</title>
5 <script src="https://cdn.tickerflow.dev/v1/tickerflow.min.js"></script>
6</head>
7<body>
8 <div id="chart-container" style="width: 100%; height: 600px;"></div>
9
10 <script>
11 const chart = new StockChart.StockChartWidget({
12 ticker: 'XXXX', // Use 'XXXX' for simulated live data
13 apiKey: 'YOUR_ALPACA_KEY',
14 secretKey: 'YOUR_ALPACA_SECRET',
15 licenseKey: 'YOUR_TICKERFLOW_LICENSE_KEY',
16 theme: 'dark',
17 defaultTimeframe: '15m'
18 });
19
20 chart.mount(document.getElementById('chart-container'));
21 </script>
22</body>
23</html>Next.js / React
We provide custom hooks for seamless React integration with full SSR support.
1// components/TradingChart.tsx
2'use client';
3
4import { useStockChart, ChartCanvas } from 'tickerflow';
5
6export default function TradingChart() {
7 const { chart, bars, isLoading, isLive, setTicker, setTimeframe } = useStockChart({
8 licenseKey: process.env.NEXT_PUBLIC_TICKERFLOW_KEY!,
9 ticker: 'BTC/USDT',
10 instrument: 'crypto',
11 cryptoConnector: 'binance',
12 binance: {
13 // Optional overrides
14 restBaseUrl: 'https://api.binance.com',
15 wsBaseUrl: 'wss://stream.binance.com:9443',
16 defaultQuoteAsset: 'USDT',
17 },
18 theme: 'dark',
19 defaultTimeframe: '15m',
20 width: 800,
21 height: 600,
22 });
23
24 if (!chart) return <div>Loading...</div>;
25
26 return (
27 <div className="h-screen w-full">
28 <ChartCanvas chart={chart} bars={bars} width={800} height={600} />
29 </div>
30 );
31}Vue.js
Use a ref to mount the widget in the onMounted lifecycle hook.
1<template>
2 <div ref="chartContainer" class="chart-container" style="width: 100%; height: 600px;"></div>
3</template>
4
5<script setup>
6import { onMounted, ref, onBeforeUnmount } from 'vue';
7import { StockChartWidget } from 'tickerflow';
8
9const chartContainer = ref(null);
10let widget = null;
11
12onMounted(() => {
13 widget = new StockChartWidget({
14 ticker: 'AAPL',
15 apiKey: import.meta.env.VITE_ALPACA_KEY,
16 secretKey: import.meta.env.VITE_ALPACA_SECRET,
17 licenseKey: import.meta.env.VITE_TICKERFLOW_KEY,
18 connector: 'alpaca', // 'alpaca' | 'massive' | 'yahoo'
19 theme: 'dark',
20 defaultTimeframe: '15m',
21 width: 800,
22 height: 600,
23 });
24 widget.mount(chartContainer.value);
25});
26
27onBeforeUnmount(() => {
28 if (widget) widget.destroy();
29});
30</script>Technical Indicators
TickerFlow includes 20+ professional-grade indicators used by traders worldwide. Indicators are rendered in real-time and automatically update with live data.
Overlay Indicators
Rendered directly on the price chart
- EMAExponential Moving Average
- SMASimple Moving Average
- Bollinger BandsVolatility bands ±2σ
- VWAPVolume Weighted Avg Price
- Ichimoku CloudSupport/resistance zones
- Parabolic SARTrend reversal points
Separate Pane Indicators
Rendered in their own panel below the chart
- RSIRelative Strength Index (0-100)
- MACDMoving Avg Convergence/Divergence
- StochasticMomentum oscillator (%K, %D)
- VolumeBar volume with coloring
- ATRAverage True Range
- OBVOn-Balance Volume
Strategy IndicatorsProfessional
Advanced multi-signal indicators for professional traders
ORB (Opening Range Breakout)
Identifies breakout levels based on the first 15-30 minutes of trading. Shows high/low range with extension targets.
SMC (Smart Money Concepts)
Detects order blocks, fair value gaps (FVG), break of structure (BOS), and liquidity zones.
W-Lines (EMA Cloud Strategy)
Dual EMA (9/21) cloud system with multi-timeframe trend panel. Shows bullish/bearish cloud fills, PDR (Prior Day Range) levels, and reclaim signals when price re-enters the cloud.
Adding Indicators
Use chart.addIndicator(type, options) to add any indicator. Each indicator has sensible defaults, but you can customize colors, lengths, and other parameters.
1// Add a simple EMA with custom color
2chart.addIndicator('ema', { length: 50, color: '#3b82f6' });
3
4// Add RSI with custom overbought/oversold levels
5chart.addIndicator('rsi', {
6 length: 14,
7 overbought: 70,
8 oversold: 30
9});
10
11// Add MACD with custom parameters
12chart.addIndicator('macd', {
13 fast: 12,
14 slow: 26,
15 signal: 9,
16 histogramColors: { positive: '#22c55e', negative: '#ef4444' }
17});
18
19// Add Bollinger Bands
20chart.addIndicator('bollinger', {
21 length: 20,
22 stdDev: 2,
23 color: '#8b5cf6'
24});
25
26// Remove an indicator
27chart.removeIndicator('ema');Note: All indicators including Advanced and Strategy indicators are available with the Professional license.
Custom Indicators
Overview
The Custom Indicator API allows you to extend TickerFlow with your own proprietary algorithms. Unlike other libraries that require you to learn a domain-specific language, TickerFlow lets you write indicators in standard JavaScript or TypeScript.
Your indicators become first-class citizens in the chart:
- They appear in the Indicators Menu.
- They have auto-generated Settings Dialogs based on your config.
- They support Custom Rendering (Canvas API) for advanced visualizations.
1. Configuration
The configuration object defines how your indicator looks and behaves in the UI.
Key Properties
idUnique identifier (e.g., 'my_algo').
placement'overlay' (main chart) or 'separate' (bottom pane).
inputsArray of user-editable fields (numbers, booleans, selects).
outputsDefault styling for lines (color, width).
1const config = {
2 name: "Super Trend",
3 type: "super_trend",
4 placement: "overlay",
5 inputs: [
6 { name: "period", type: "number", default: 10, min: 1 },
7 { name: "multiplier", type: "number", default: 3.0, step: 0.1 }
8 ],
9 outputs: [
10 { name: "up", color: "#00ff00" },
11 { name: "down", color: "#ff0000" }
12 ]
13};2. Calculation (TALib)
The calculate function contains your logic. It receives the full history of bars, the user's current input values, and the TALib helper library — a collection of pre-built technical analysis functions so you don't have to implement them from scratch.
Function Signature
1const calculate = (bars: Bar[], inputs: Record<string, any>, lib: TALib) => IndicatorValue[]barsArray of OHLCV bar objects with timestamp, open, high, low, close, volume
inputsUser-configured values from your config.inputs definition
libTALib helper object with technical analysis functions
TALib Function Reference
Moving Averages
lib.sma(source, length)Returns: number[]Simple Moving Average — The arithmetic mean of the last length values. Commonly used to smooth price data and identify trends.
1const close = bars.map(b => b.close);
2const sma20 = lib.sma(close, 20); // 20-period SMA
3const sma50 = lib.sma(close, 50); // 50-period SMA
4
5// SMA crossover strategy
6const goldenCross = lib.crossover(sma20, sma50); // Fast crosses above slowlib.ema(source, length)Returns: number[]Exponential Moving Average — Weighted moving average that gives more importance to recent prices. Reacts faster to price changes than SMA. Uses multiplier: k = 2 / (length + 1)
1const close = bars.map(b => b.close);
2const ema9 = lib.ema(close, 9); // Fast EMA (scalping)
3const ema21 = lib.ema(close, 21); // Medium EMA (swing)
4const ema200 = lib.ema(close, 200); // Slow EMA (trend)
5
6// EMA ribbon
7const emas = [9, 21, 55, 100, 200].map(len => lib.ema(close, len));Oscillators & Momentum
lib.rsi(source, length)Returns: number[]Relative Strength Index — Momentum oscillator measuring speed and magnitude of price changes. Returns values 0-100. Traditional interpretation: >70 = overbought, <30 = oversold.
1const close = bars.map(b => b.close);
2const rsi = lib.rsi(close, 14); // Standard 14-period RSI
3
4// Detect overbought/oversold
5return bars.map((b, i) => ({
6 timestamp: b.timestamp,
7 value: rsi[i],
8 // Signal when RSI crosses key levels
9 signal: lib.crossunder([rsi[i]], 30)[0] ? 'oversold'
10 : lib.crossover([rsi[i]], 70)[0] ? 'overbought'
11 : null
12}));Volatility
lib.stdev(source, length)Returns: number[]Standard Deviation — Measures price volatility/dispersion from the mean. Used to calculate Bollinger Bands and other volatility-based indicators.
1const close = bars.map(b => b.close);
2const sma20 = lib.sma(close, 20);
3const stdev20 = lib.stdev(close, 20);
4
5// Build Bollinger Bands manually
6const upperBand = sma20.map((sma, i) => sma + (stdev20[i] * 2));
7const lowerBand = sma20.map((sma, i) => sma - (stdev20[i] * 2));
8
9// Bollinger Band Width (volatility measure)
10const bbWidth = upperBand.map((upper, i) => (upper - lowerBand[i]) / sma20[i]);Price Extremes
lib.highest(source, length)Returns: number[]Highest Value — Returns the maximum value over the last length periods. Useful for Donchian Channels, breakout detection, and ATR calculations.
1const high = bars.map(b => b.high);
2const low = bars.map(b => b.low);
3
4// Donchian Channel (20-period)
5const donchianHigh = lib.highest(high, 20);
6const donchianLow = lib.lowest(low, 20);
7const donchianMid = donchianHigh.map((h, i) => (h + donchianLow[i]) / 2);
8
9// Breakout detection
10const breakoutUp = lib.crossover(high, donchianHigh);lib.lowest(source, length)Returns: number[]Lowest Value — Returns the minimum value over the last length periods. Commonly used with highest() for channel-based strategies.
1const close = bars.map(b => b.close);
2const low = bars.map(b => b.low);
3
4// Williams %R (similar to Stochastic)
5const highest14 = lib.highest(close, 14);
6const lowest14 = lib.lowest(low, 14);
7const williamsR = close.map((c, i) =>
8 ((highest14[i] - c) / (highest14[i] - lowest14[i])) * -100
9);Crossover Detection
lib.crossover(a, b)Returns: boolean[]Crossover — Returns true when series a crosses above series b. The second parameter can be an array OR a constant number. Essential for signal generation.
1const close = bars.map(b => b.close);
2const ema9 = lib.ema(close, 9);
3const ema21 = lib.ema(close, 21);
4
5// EMA crossover (array vs array)
6const bullishCross = lib.crossover(ema9, ema21);
7
8// Price crosses above a level (array vs constant)
9const breaksResistance = lib.crossover(close, 150.00);
10
11// RSI exits oversold (crosses above 30)
12const rsi = lib.rsi(close, 14);
13const rsiExitOversold = lib.crossover(rsi, 30);lib.crossunder(a, b)Returns: boolean[]Crossunder — Returns true when series a crosses below series b. Same signature as crossover. Used for sell signals or stop-loss triggers.
1const close = bars.map(b => b.close);
2const ema9 = lib.ema(close, 9);
3const ema21 = lib.ema(close, 21);
4
5// EMA death cross
6const bearishCross = lib.crossunder(ema9, ema21);
7
8// Price breaks support
9const breaksSupport = lib.crossunder(close, 140.00);
10
11// RSI enters overbought territory
12const rsi = lib.rsi(close, 14);
13const rsiEnterOverbought = lib.crossover(rsi, 70); // Use crossover for entering
14const rsiExitOverbought = lib.crossunder(rsi, 70); // Use crossunder for exitingComplete Calculate Example
Here's a full example showing how to build a custom "Dual EMA Crossover" indicator with buy/sell signals:
1const calculate = (bars, inputs, lib) => {
2 // 1. Extract price data from bars
3 const close = bars.map(b => b.close);
4
5 // 2. Get user inputs (defined in config.inputs)
6 const fastLength = inputs.fastLength || 9;
7 const slowLength = inputs.slowLength || 21;
8
9 // 3. Calculate EMAs using TALib
10 const fastEMA = lib.ema(close, fastLength);
11 const slowEMA = lib.ema(close, slowLength);
12
13 // 4. Detect crossovers for signals
14 const bullishCross = lib.crossover(fastEMA, slowEMA);
15 const bearishCross = lib.crossunder(fastEMA, slowEMA);
16
17 // 5. Return indicator values
18 return bars.map((bar, i) => ({
19 timestamp: bar.timestamp,
20
21 // Multiple output values (for multi-line indicators)
22 fast: fastEMA[i],
23 slow: slowEMA[i],
24
25 // Signal data (for custom rendering)
26 signal: bullishCross[i] ? 'buy'
27 : bearishCross[i] ? 'sell'
28 : null,
29 signalPrice: bar.close
30 }));
31};💡 Pro Tips
- • TALib functions return arrays with
NaNfor the firstlength-1bars (warmup period) - • Always use
bars.map(b => b.close)to extract price arrays — don't pass the bars array directly - • Crossover/crossunder return
boolean[]— use them to generate discrete signals - • You can combine multiple TALib functions to build complex indicators (MACD, Stochastic, etc.)
3. Custom Rendering
For standard lines, you don't need this. But if you want to draw shapes, bands, or text (like arrows for buy/sell signals), provide a render function. It gives you direct access to the HTML5 Canvas Context and a lib helper object.
Available Render Helpers (lib)
Example: Drawing Arrows on Crossover
1// 1. Calculate logic with signals
2const calculate = (bars, inputs, lib) => {
3 const close = bars.map(b => b.close);
4 const fast = lib.sma(close, 10);
5 const slow = lib.sma(close, 20);
6 const buySignal = lib.crossover(fast, slow);
7 const sellSignal = lib.crossunder(fast, slow);
8
9 return bars.map((b, i) => ({
10 timestamp: b.timestamp,
11 value: fast[i],
12 // Pass signal data to renderer
13 signal: buySignal[i] ? 'buy' : sellSignal[i] ? 'sell' : null,
14 price: b.close
15 }));
16};
17
18// 2. Render arrows based on signals using helper lib
19const render = (ctx, { bars, scale, values }, lib) => {
20 ctx.save();
21
22 values.forEach(v => {
23 if (!v.signal) return;
24
25 // Find X coordinate (bar index)
26 const barIndex = bars.findIndex(b => b.timestamp === v.timestamp);
27 const x = scale.x(barIndex);
28
29 // Find Y coordinate (price)
30 const y = scale.y(v.price);
31
32 if (v.signal === 'buy') {
33 // Draw Up Arrow (Green) below the bar
34 lib.drawArrowUp(ctx, x, y + 20, '#00ff00');
35 } else if (v.signal === 'sell') {
36 // Draw Down Arrow (Red) above the bar
37 lib.drawArrowDown(ctx, x, y - 20, '#ff0000');
38 }
39 });
40
41 ctx.restore();
42};Putting it all together
Register your indicator once, and it's available forever.
1chart.registerCustomIndicator({
2 config: config,
3 calculate: calculate,
4 render: render // Optional
5});Drawing Tools
Professional charting requires the ability to annotate and analyze. TickerFlow includes a comprehensive suite of drawing tools that persist across sessions and can be exported/imported.
📏 Lines & Rays
- Trendline — Connect two price points to identify trend direction
- Horizontal Line — Mark support/resistance levels
- Vertical Line — Mark important time events
- Ray — Extends infinitely in one direction
- Extended Line — Extends infinitely in both directions
📐 Fibonacci Tools
- Retracement — Find pullback levels (23.6%, 38.2%, 50%, 61.8%)
- Extension — Project price targets beyond the swing
- Fan — Diagonal support/resistance from a pivot
- Time Zones — Vertical lines at Fib intervals
🔷 Shapes
- Rectangle — Highlight price ranges or zones
- Circle — Mark key reversal points
- Triangle — Identify chart patterns
- Parallel Channel — Define trading channels
💬 Annotations
- Text — Add notes anywhere on the chart
- Callout — Text with arrow pointer
- Price Label — Shows exact price at a point
- Arrow — Point to specific bars or patterns
📊 Position ToolsPro+
Visualize and plan trades with built-in Long and Short position calculators. Instantly see your Risk:Reward ratio, potential P&L, and live position tracking.
📈 Long Position
Plan bullish trades with visual entry, target, and stop levels.
- Entry Price — Your planned buy price
- Take Profit (TP) — Target exit for profit (green zone)
- Stop Loss (SL) — Exit level to limit loss (red zone)
- Quantity — Number of shares (default: 100)
- R:R Ratio — Auto-calculated risk-to-reward
📉 Short Position
Plan bearish trades with inverted profit/loss zones.
- Entry Price — Your planned short entry
- Take Profit (TP) — Target below entry (green zone)
- Stop Loss (SL) — Exit above entry (red zone)
- Quantity — Number of shares (default: 100)
- R:R Ratio — Auto-calculated risk-to-reward
Real-Time P&L Display
1// Programmatically add a Long Position
2chart.addDrawing('longPosition', {
3 entryPrice: 150.00,
4 takeProfit: 165.00, // +10% target
5 stopLoss: 142.50, // -5% stop
6 quantity: 200, // 200 shares
7 color: '#26a69a'
8});
9
10// Add a Short Position
11chart.addDrawing('shortPosition', {
12 entryPrice: 150.00,
13 takeProfit: 135.00, // -10% target (profit for short)
14 stopLoss: 157.50, // +5% stop (loss for short)
15 quantity: 100
16});
17
18// Position tools auto-calculate:
19// - Risk:Reward ratio (R:R)
20// - Profit amount: (TP - Entry) × Qty
21// - Loss amount: (Entry - SL) × Qty
22// - Profit/Loss percentages
23// - Current P&L with live price trackingUser Interaction
Drawing tools are accessible via the toolbar on the left side of the chart. Users can:
- Click + Drag to create drawings
- Click to select existing drawings
- Drag handles to resize or reposition
- Right-click to access properties or delete
- Double-click text to edit
Programmatic Control
Save user drawings to your database and restore them on page load:
1// Export all drawings as JSON (save to your backend)
2const savedDrawings = chart.exportDrawings();
3await fetch('/api/save-drawings', {
4 method: 'POST',
5 body: JSON.stringify({ symbol: 'AAPL', drawings: savedDrawings })
6});
7
8// Import drawings (restore from your backend)
9const response = await fetch('/api/drawings?symbol=AAPL');
10const { drawings } = await response.json();
11chart.importDrawings(drawings);
12
13// Clear all drawings
14chart.clearDrawings();
15
16// Programmatically add a horizontal line
17chart.addDrawing('horizontal_line', {
18 price: 150.00,
19 color: '#ef4444',
20 lineWidth: 2,
21 label: 'Stop Loss'
22});Note: Basic drawing tools (lines, rectangles, text) are available on all plans. Advanced tools (Fibonacci, channels, complex shapes) require a Pro license or higher.
Price Alerts
Pro+Never miss a trading opportunity. TickerFlow's built-in alert system notifies you when price reaches your target levels via browser notifications, sound alerts, Telegram, and webhook integrations.
Available Alert Conditions
Crosses Above
Triggers when price moves above your level
Crosses Below
Triggers when price moves below your level
Greater Than
Triggers while price is above level
Less Than
Triggers while price is below level
Percent Change
Triggers on % move from reference price
Price Change
Triggers on absolute $ move
Creating Alerts via UI
Users can create alerts directly from the chart:
- Right-click on any price level on the chart
- Select "Create Alert" from the context menu
- Configure the alert condition and notification preferences
- Click "Save" — the alert line appears on chart
Programmatic Alerts
1import { PriceAlertManager, ALERT_CONDITIONS } from 'tickerflow';
2
3const alerts = PriceAlertManager.getInstance();
4
5// Create a simple price alert
6alerts.createAlert({
7 symbol: 'AAPL',
8 condition: ALERT_CONDITIONS.CROSSES_ABOVE,
9 value: 190.00,
10 repeatMode: 'ONCE', // 'ONCE' | 'EVERY_TIME' | 'ONCE_PER_BAR'
11 message: 'AAPL broke $190!' // Custom notification message
12});
13
14// Create alert with webhook (for Slack, Discord, etc.)
15alerts.createAlert({
16 symbol: 'BTCUSD',
17 condition: ALERT_CONDITIONS.PERCENT_CHANGE,
18 value: 5, // 5% move
19 repeatMode: 'ONCE_PER_BAR',
20 webhookUrl: 'https://hooks.slack.com/services/XXX/YYY/ZZZ',
21 webhookPayload: {
22 text: '🚨 BTC moved 5%! Current price: {{price}}'
23 }
24});
25
26// List all active alerts
27const activeAlerts = alerts.getAlerts();
28
29// Remove an alert
30alerts.removeAlert(alertId);
31
32// Clear all alerts for a symbol
33alerts.clearAlerts('AAPL');📱 Telegram Notifications
Send alerts directly to Telegram using a bot token and chat ID.
- Create a bot with @BotFather and copy the bot token.
- Send your bot a message (e.g. /start), then visit https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates and read message.chat.id as the chat ID.
- Set notificationSettings.telegram when creating the widget.
1const chart = new StockChartWidget({
2 ticker: 'AAPL',
3 notificationSettings: {
4 telegram: {
5 enabled: true,
6 botToken: '123456789:ABCDEF...',
7 chatId: '123456789'
8 }
9 }
10});Security note: storing a bot token in a browser app makes it visible to users. For production, send alerts to your backend via webhooks and have your server send Telegram messages.
🔗 Webhook Integration
Connect alerts to your trading bots, notification systems, or automation workflows. Webhooks send a POST request with alert data when triggered.
1// Webhook payload sent to your endpoint:
2{
3 "alert_id": "abc123",
4 "symbol": "AAPL",
5 "condition": "CROSSES_ABOVE",
6 "trigger_price": 190.00,
7 "current_price": 190.25,
8 "triggered_at": "2025-01-05T14:30:00Z",
9 "custom_payload": { ... } // Your custom data
10}Configuration Options
Customize every aspect of your chart. All options can be passed when creating the widget or updated dynamically at runtime.
Required Options
| Option | Type | Description |
|---|---|---|
| ticker | string | Symbol to display (e.g., "AAPL", "BTC/USDT", "EUR_USD"). Use "XXXX" for simulated demo data. |
| licenseKey | string | Your TickerFlow license key from the dashboard. Features are enabled based on your plan. |
Data Connection
| Option | Type | Default | Description |
|---|---|---|---|
| connector | string | "alpaca" | "alpaca" | "massive" | "yahoo" — stocks/index connector |
| apiKey | string | — | API key for Alpaca/Massive (stocks/index) |
| secretKey | string | — | Secret key (Alpaca only) |
| cryptoConnector | string | "binance" | Crypto connector (currently: "binance") |
| binance | object | — | Binance config: restBaseUrl, wsBaseUrl, defaultQuoteAsset |
| forexConnector | string | "oanda" | Forex connector (currently: "oanda") |
| oanda | object | — | OANDA config: accessToken, accountId, environment. (Optional: falls back to Massive/Yahoo if missing) |
| proxyUrl | string | corsproxy.io | CORS proxy URL for Yahoo connector |
| dataProvider | DataProvider | — | Custom data provider object (overrides connector) |
Display & Appearance
| Option | Type | Default | Description |
|---|---|---|---|
| theme | string | "dark" | "dark" | "light" — color scheme |
| defaultTimeframe | string | "15m" | "1m" | "5m" | "15m" | "1h" | "4h" | "1d" | "1w" |
| width | number | auto | Chart width in pixels (auto-fills container if not set) |
| height | number | auto | Chart height in pixels (auto-fills container if not set) |
| tickerWatermarkOpacity | number | 0.03 | Controls ticker watermark opacity in the chart background (0–0.2) |
| debug | boolean | false | Enable verbose console logging |
Callbacks & AI
| Option | Type | Description |
|---|---|---|
| onPriceUpdate | (price, symbol) => void | Called when the latest price updates |
| onTickerChange | (ticker, name?) => void | Called when the user selects a new ticker |
| notificationSettings | Partial<PriceAlertSettings> | Default alert preferences (sound, channels, etc.) |
| openAIApiKey | string | API key for on‑chart AI analysis |
| openAIModel | string | Model name for AI analysis |
| openAIEndpoint | string | Custom AI endpoint (server proxy) |
| onAiAnalysis | (args) => Promise<ChartAnalysisJson> | Handle AI analysis requests yourself |
Complete Example
1const chart = new StockChartWidget({
2 // Required
3 ticker: 'AAPL',
4 licenseKey: process.env.TICKERFLOW_KEY,
5
6 // Stocks / index
7 connector: 'alpaca',
8 apiKey: process.env.ALPACA_KEY,
9 secretKey: process.env.ALPACA_SECRET,
10
11 // Crypto (Binance)
12 // cryptoConnector: 'binance',
13 // binance: { defaultQuoteAsset: 'USDT' },
14
15 // Forex (OANDA)
16 // forexConnector: 'oanda',
17 // oanda: { accessToken: process.env.OANDA_TOKEN, accountId: process.env.OANDA_ACCOUNT_ID, environment: 'practice' },
18
19 // Display
20 theme: 'dark',
21 defaultTimeframe: '15m',
22 width: 1200,
23 height: 800,
24 tickerWatermarkOpacity: 0.03,
25 debug: false,
26});
27
28chart.mount(document.getElementById('chart'));Workspaces & Multi‑Chart Layouts
A workspace lets end users organize multiple charts into a single view. Each workspace can contain different tickers, timeframes, and chart types, and can be saved and recalled from the Workspaces menu.
Create a workspace
- Open the Workspaces menu in the chart header.
- Choose a grid layout (2‑chart, 3‑chart, 4‑chart, etc.).
- Set each chart’s ticker and timeframe.
- Save the workspace with a name.
Manage workspaces
- Load saved workspaces from the same menu.
- Update a workspace after changing layouts or indicators.
- Delete unused workspaces to keep things tidy.
Data Connectors
TickerFlow supports multiple data sources out of the box. Each connector handles authentication, data fetching, and real-time streaming automatically. Stocks/index use connector, while crypto/forex use dedicated connector props.
Quick Comparison
| Feature | Alpaca | Massive | Yahoo | Binance | OANDA |
|---|---|---|---|---|---|
| Real-time Streaming | ✓ WebSocket | ✓ WebSocket | — | ✓ WebSocket | ✓ Streaming HTTP |
| API Key Required | Yes | Yes | No | No | Yes |
| Stocks | ✓ | ✓ | ✓ | — | — |
| Crypto | — | — | — | ✓ | — |
| Forex | — | — | — | — | ✓ |
| Best For | US Stocks, Real-time | Global markets | Quick demos, EOD | Crypto bars + streaming | Forex candles + quotes |
AlpacaDefaultRecommended
Direct connection to Alpaca Markets API. Best choice for US stocks with real-time WebSocket streaming. Supports both IEX and full SIP data feeds.
Alpaca Data Plans
- IEX (Basic)
IEX exchange data, 200 API calls/min, 30 streaming symbols
- Algo Trader Plus
Full SIP (all US exchanges), unlimited calls, unlimited streaming
1const chart = new StockChartWidget({
2 ticker: 'AAPL',
3 connector: 'alpaca', // Default, can be omitted
4 apiKey: 'YOUR_ALPACA_KEY',
5 secretKey: 'YOUR_ALPACA_SECRET',
6 licenseKey: 'YOUR_TICKERFLOW_KEY'
7});Massive Data
Global market data provider with extensive historical data. Good choice for international stocks and when you need 10+ years of history.
Massive Data Plans
- Basic (Free): 5 calls/min, 2y history, EOD data
- Starter ($29/mo): Unlimited calls, 5y history, 15m delayed
- Developer ($79/mo): Unlimited calls, 10y history, 15m delayed
- Advanced ($199/mo): Unlimited calls, 20y+ history, Real-time
1const chart = new StockChartWidget({
2 ticker: 'AAPL',
3 connector: 'massive',
4 apiKey: 'YOUR_MASSIVE_KEY',
5 // No secretKey needed for Massive
6 licenseKey: 'YOUR_TICKERFLOW_KEY'
7});Yahoo FinanceNo API Key
Uses Yahoo Finance data via a CORS proxy. Perfect for quick demos, development, or when you don't need real-time data. No API key required.
Note: Yahoo connector doesn't support real-time streaming. Data is fetched on load and on timeframe change. For live charts, use Alpaca or Massive.
1const chart = new StockChartWidget({
2 ticker: 'AAPL',
3 connector: 'yahoo',
4 // No API key needed!
5 // Optional: Use your own proxy for better reliability
6 // proxyUrl: 'https://your-cors-proxy.com/?url=',
7 licenseKey: 'YOUR_TICKERFLOW_KEY'
8});BinanceCrypto
Crypto historical data + live bars via Binance. No API key required.
1const chart = new StockChartWidget({
2 ticker: 'BTC/USDT',
3 cryptoConnector: 'binance',
4 binance: {
5 // Optional overrides
6 restBaseUrl: 'https://api.binance.com',
7 wsBaseUrl: 'wss://stream.binance.com:9443',
8 defaultQuoteAsset: 'USDT',
9 },
10 licenseKey: 'YOUR_TICKERFLOW_KEY'
11});OANDAForex
High-fidelity Forex candles + live quotes via OANDA. Requires an access token and account id. If these are not provided, the library will automatically attempt to fetch Forex data via Massive, Yahoo Finance, or Alpaca.
1const chart = new StockChartWidget({
2 ticker: 'EUR_USD',
3 forexConnector: 'oanda',
4 oanda: {
5 accessToken: 'YOUR_OANDA_ACCESS_TOKEN',
6 accountId: 'YOUR_OANDA_ACCOUNT_ID',
7 environment: 'practice', // or 'live'
8 },
9 licenseKey: 'YOUR_TICKERFLOW_KEY'
10});Custom Data ProviderAdvanced
Implement your own data provider for full control. Connect to your own backend, proprietary data feeds, or any third-party API.
DataProvider Interface
Your provider must implement these methods:
getBars(symbol, timeframe, from, to)— Fetch historical OHLCV datasubscribe(symbol, timeframe, onBar)— Start real-time updatesunsubscribe()— Cleanup streaming connection
1// Custom data provider implementation
2const myDataProvider = {
3 // Fetch historical bars
4 getBars: async (symbol, timeframe, from, to) => {
5 const response = await fetch(
6 `/api/bars?symbol=${symbol}&tf=${timeframe}&from=${from}&to=${to}`
7 );
8 const data = await response.json();
9
10 // Return array of Bar objects
11 return data.map(bar => ({
12 timestamp: new Date(bar.time).getTime(),
13 open: bar.o,
14 high: bar.h,
15 low: bar.l,
16 close: bar.c,
17 volume: bar.v
18 }));
19 },
20
21 // Subscribe to real-time updates
22 subscribe: (symbol, timeframe, onBar) => {
23 const ws = new WebSocket(`wss://your-api.com/stream?symbol=${symbol}`);
24
25 ws.onmessage = (event) => {
26 const bar = JSON.parse(event.data);
27 onBar({
28 timestamp: bar.timestamp,
29 open: bar.open,
30 high: bar.high,
31 low: bar.low,
32 close: bar.close,
33 volume: bar.volume
34 });
35 };
36
37 // Store reference for cleanup
38 this._ws = ws;
39 },
40
41 // Cleanup
42 unsubscribe: () => {
43 if (this._ws) {
44 this._ws.close();
45 this._ws = null;
46 }
47 }
48};
49
50// Use your custom provider
51const chart = new StockChartWidget({
52 ticker: 'CUSTOM_SYMBOL',
53 dataProvider: myDataProvider,
54 licenseKey: 'YOUR_TICKERFLOW_KEY'
55});