Trading Sessions Provider
TradingSessionsProvider is responsible for getting selected instrument's trading schedule.
DXcharts Reactrequests sessions up to +14 days fromDate.now()for a correct work, so make sure you've provided enough.
There are 4 types of trading sessions supported:
type SessionType = 'NO_TRADING' | 'PRE_MARKET' | 'REGULAR' | 'AFTER_MARKET';
TradingSessions incorporates from and to timestamps, which is a range of time when the session is active, and type of the session.
const tradingSessions: TradingSession[] = [
{
// as you can see here, NO_TRADING session is defined as from 12:00 AM to 8:00 AM on 10 Jul
from: 1720569600000, // GMT: Wednesday, July 10, 2024 12:00:00 AM
to: 1720598400000, // GMT: Wednesday, July 10, 2024 8:00:00 AM
type: 'NO_TRADING',
},
];
What you should do is just to define instrument's trading sessions one by one, one after another, like:
const tradingSessions: TradingSession[] = [
{
// as you can see here, you define NO_TRADING session from 12:00 AM to 8:00 AM on 10 Jul
from: 1720569600000, // GMT: Wednesday, July 10, 2024 12:00:00 AM
to: 1720598400000, // GMT: Wednesday, July 10, 2024 8:00:00 AM
type: 'NO_TRADING',
},
{
// after that obviously PRE_MARKET sessions starts from 8:00 AM to 12:00 PM
from: 1720598400000, // GMT: Wednesday, July 10, 2024 8:00:00 AM
to: 1720612800000, // GMT: Wednesday, July 10, 2024 12:00:00 PM
type: 'PRE_MARKET',
},
{
// then REGULAR session starts from 12:00 PM to 8:00 PM
from: 1720612800000, // GMT: Wednesday, July 10, 2024 12:00:00 PM
to: 1720641600000, // GMT: Wednesday, July 10, 2024 8:00:00 PM
type: 'REGULAR',
},
{
// and AFTER_MARKET then starts from 8:00 PM Jul 10 to 12:00 AM Jul 11
from: 1720641600000, // GMT: Wednesday, July 10, 2024 8:00:00 PM
to: 1720656000000, // GMT: Thursday, July 11, 2024 12:00:00 AM
type: 'AFTER_MARKET',
},
{
// and so on...
from: 1720656000000,
to: 1720684800000,
type: 'NO_TRADING',
},
];
With tradable weekends and holidays the situation is the same - just define
TradingSessionin the same format for them.
How it works
import { generateTradingSessions } from '@dx-private/dxchart5-react/dist/utils/generator/trading-sessions-generator.utils';import {GenerateSessionOptions,TradingSession,TradingSessionsProvider,} from '@dx-private/dxchart5-react/dist/providers/sessions/trading-sessions-provider';const MOCK_TIME_ZONE = 'America/New_York';/*** Creates mock implementation of {@link TradingSessionsProvider}.*/export const createMockTradingSessionsProvider = (): TradingSessionsProvider => {const sessionsCache = new Map<string, Promise<TradingSession[]>>();const timezonesCache = new Map<string, Promise<string>>();// NOTE: chart requests sessions up to +14 days from Date.now() for a correct work,// so make sure you've provided enough sessions.const MOCK_TRADING_SESSIONS = generateTradingSessions();const requestSession = (tradingHours: string) => {const cached = sessionsCache.get(tradingHours);if (cached) {return cached;}const req = new Promise<TradingSession[]>(resolve => setTimeout(() => resolve(MOCK_TRADING_SESSIONS), 1000));sessionsCache.set(tradingHours, req);return req;};const requestTimezone = (tradingHours: string) => {const cached = timezonesCache.get(tradingHours);if (cached) {return cached;}const req = new Promise<string>(resolve => setTimeout(() => resolve(MOCK_TIME_ZONE), 1000));timezonesCache.set(tradingHours, req);return req;};/*** `options.tradingHours` and `options.symbol` properties are taken by `dxcharts-react` from the information* about `Instrument` you've provided via `SymbolSuggestProvider`.** @example* options.tradingHours = "NewYorkUS(rt=0300;0=p04000930r09301600a16002000)";* options.symbol = "AAPL";*/const getTimeZone = (options: GenerateSessionOptions): Promise<string> => {if (options.tradingHours === undefined) {return Promise.resolve('UTC');}const tradingHours = options.tradingHours;return requestTimezone(tradingHours);};const generateSessions = (from: number, to: number, options: GenerateSessionOptions): Promise<TradingSession[]> => {const tradingHours = options.tradingHours;return tradingHours? requestSession(tradingHours).then((sessions: TradingSession[]) => {return sessions.filter(session => session.to >= from && session.from <= to);}): Promise.resolve([]);};return {generateSessions,getTimeZone,};};
Real-world example: dxFeed Schedule Provider
The following example shows a complete implementation of a Trading Sessions Provider that connects to a dxFeed Schedule API. This provider:
- Fetches trading schedules from a dxFeed Schedule endpoint
- Requests appropriate date ranges - 1 year back for historical data, 14 days forward for holidays
- Maps session types from dxFeed format to chart format (NO_TRADING, PRE_MARKET, REGULAR, AFTER_MARKET)
- Extracts timezone information from schedule metadata
- Caches requests per trading hours string to avoid duplicate API calls
- Handles browser compatibility - includes fallback timestamp parsing for older browsers
:::tip Adapting to your API
This is one of the more complex providers. Key points:
- Sessions are REQUIRED for indicators like VWAP, HistoricalVolatility, PivotPoints
- Must provide 14+ days forward from Date.now() (required by DXcharts React)
- Sessions must be continuous - no gaps, each session ends where next begins
- Map your API response to
TradingSession[]format:[{from: number, // Required: start timestamp in millisecondsto: number, // Required: end timestamp in millisecondstype: 'NO_TRADING' | 'PRE_MARKET' | 'REGULAR' | 'AFTER_MARKET'}] - Filter by date range - only return sessions within the requested from/to range
- If you have simple trading hours, see the simplified version in code comments
See comments in the code for a simplified implementation example.
:::
import { addDays, addYears } from 'date-fns';import {GenerateSessionOptions,TradingSession,TradingSessionsProvider,} from '@dx-private/dxchart5-react/dist/providers/sessions/trading-sessions-provider';import { getLocalTimezone } from '@dx-private/dxchart5-react/dist/utils/timezones/timezones';/*** Example: Trading Sessions Provider implementation using dxFeed Schedule API** This provider fetches trading session schedules from a dxFeed Schedule endpoint.* It implements:* - generateSessions: generates trading sessions for a date range and trading hours* - getTimeZone: retrieves timezone for a given trading hours schedule** IMPORTANT FOR YOUR IMPLEMENTATION:* - Trading sessions are REQUIRED for indicators like VWAP, HistoricalVolatility, PivotPoints* - You must provide sessions for at least 14 days forward from Date.now()* - Sessions must be continuous (no gaps) - each session ends where the next begins* - Session types: 'NO_TRADING', 'PRE_MARKET', 'REGULAR', 'AFTER_MARKET'* - If you don't have session data, you can return empty array, but indicators won't work** SIMPLIFIED VERSION (if you have simple trading hours):* ```typescript* export const createSimpleTradingSessionsProvider = (): TradingSessionsProvider => {* const generateSessions = (from: number, to: number, options: GenerateSessionOptions): Promise<TradingSession[]> => {* // Example: Regular trading hours 9:30 AM - 4:00 PM EST, Monday-Friday* const sessions: TradingSession[] = [];* const startDate = new Date(from);* const endDate = new Date(to);** // Generate sessions for each day in range* for (let date = startDate; date <= endDate; date.setDate(date.getDate() + 1)) {* const dayOfWeek = date.getDay();* if (dayOfWeek >= 1 && dayOfWeek <= 5) { // Monday-Friday* const dayStart = new Date(date);* dayStart.setHours(9, 30, 0, 0); // 9:30 AM* const dayEnd = new Date(date);* dayEnd.setHours(16, 0, 0, 0); // 4:00 PM** sessions.push({* from: dayStart.getTime(),* to: dayEnd.getTime(),* type: 'REGULAR'* });* }* }** return Promise.resolve(sessions);* };** return { generateSessions, getTimeZone: () => Promise.resolve('America/New_York') };* };* ```** The provider includes:* - Request caching to avoid duplicate API calls* - Session type mapping (NO_TRADING, PRE_MARKET, REGULAR, AFTER_MARKET)* - Date range filtering (requests 1 year back, 14 days forward)* - Timezone extraction from schedule metadata* - Timestamp parsing with fallback for older browsers*/type DxFeedSessionType = 'NO_TRADING' | 'PRE_MARKET' | 'REGULAR' | 'AFTER_MARKET';// These interfaces represent dxFeed API response - adapt to your API formatinterface DxFeedScheduleSession {readonly startTime: string; // ISO date string or custom formatreadonly endTime: string;readonly type: DxFeedSessionType;}interface DxFeedScheduleDay {readonly id: string;readonly isHoliday: string;readonly isShort: string;readonly sessions: DxFeedScheduleSession[];}interface DxFeedSchedule {readonly schedule: {readonly name: string;readonly timeZone: string;readonly days: DxFeedScheduleDay[];};}type DxFeedScheduleResponse = Record<string, DxFeedSchedule>[];export interface DxFeedScheduleOptions {readonly feedURL: string;}export const DEFAULT_OPTIONS: DxFeedScheduleOptions = {feedURL: 'https://webdev-new.prosp.devexperts.com:8095/schedule-view',};/*** Creates a Trading Sessions Provider that connects to dxFeed Schedule API** ADAPTATION GUIDE FOR YOUR API:** 1. Replace fetch URL with your API endpoint* 2. Adapt request body/query params to your API format* 3. Map your API response to TradingSession[] format:* [* {* from: number, // Required: start timestamp in milliseconds* to: number, // Required: end timestamp in milliseconds* type: 'NO_TRADING' | 'PRE_MARKET' | 'REGULAR' | 'AFTER_MARKET'* }* ]* 4. IMPORTANT: Sessions must be continuous (no gaps) and cover the requested date range* 5. Filter sessions to match the requested from/to range** @param initOptions - Configuration with schedule endpoint URL* @returns TradingSessionsProvider instance with caching*/export const createDxFeedTradingSessionsProvider = (initOptions: DxFeedScheduleOptions = DEFAULT_OPTIONS,): TradingSessionsProvider => {// Cache requests per trading hours string to avoid duplicate API callsconst reqCache = new Map<string, Promise<DxFeedScheduleResponse>>();/*** Create and cache schedule request for a trading hours string** NOTE: This example requests 1 year back and 14 days forward.* DXcharts React requires at least 14 days forward for proper operation.* You can request more if needed, but don't request less.*/const createReq = (tradingHours: string) => {const cached = reqCache.get(tradingHours);if (cached) {return cached;}const req = fetch(`${initOptions.feedURL}/per-calendar-day`, {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({schedules: [tradingHours],// Request 1 year of sessions - enough for historical data which needs sessions// Only candles with aggregation period less than 1 day need trading sessions// Also, dxfeed can't provide history candles for more than a year if aggregation less than a daystart: addYears(Date.now(), -1),// Request sessions up to +14 days from Date.now() to cover holidays// IMPORTANT: DXcharts React requires at least 14 days forwardstop: addDays(Date.now(), 14),tz: 'UTC',}),}).then(res => res.json());reqCache.set(tradingHours, req);return req;};/*** getTimeZone: Returns timezone for a trading hours schedule** Requirements:* - Return Promise<string> with timezone identifier (e.g., 'America/New_York')* - If tradingHours is undefined, return local timezone* - This is used for proper timezone handling in the chart*/const getTimeZone = (options: GenerateSessionOptions): Promise<string> => {if (options.tradingHours === undefined) {return Promise.resolve(getLocalTimezone());}const tradingHours = options.tradingHours;return createReq(options.tradingHours).then((res: DxFeedScheduleResponse) => {const schedule = res[0][tradingHours].schedule;return schedule.timeZone;});};/*** Parse timestamp string with fallback for older browsers** IMPORTANT: Sessions must have timestamps in milliseconds.* If your API returns dates in different formats, adapt this:* - ISO string: new Date(dateString).getTime()* - Unix timestamp (seconds): timestamp * 1000* - Date object: date.getTime()*/const parseSessionTimestamp = (value: string) => {const parsed = Date.parse(value);if (parsed) {return parsed;}// Fallback for old versions of browsers/OS that don't support Date.parse()// You probably don't need this for modern implementationsconst [years, months, days, hours, minutes, seconds, ms] = value.split(/[\-\+ :T]/);const date = new Date();date.setUTCFullYear(Number(years));date.setUTCMonth(Number(Number(months) - 1));date.setUTCDate(Number(days));date.setUTCHours(Number(hours));date.setUTCMinutes(Number(minutes));date.setUTCSeconds(Number(seconds));date.setUTCMilliseconds(Number(ms));return date.getTime();};/*** generateSessions: Called when chart needs trading sessions for a date range** Requirements:* - Return Promise<TradingSession[]> for the requested date range* - Sessions must cover the entire from-to range (no gaps)* - Each session must have: from, to (milliseconds), and type* - Filter sessions to match the requested range* - Return empty array if tradingHours is undefined** IMPORTANT: Sessions must be continuous - each session ends where the next begins.* Example:* - NO_TRADING: 00:00 - 09:30* - REGULAR: 09:30 - 16:00* - AFTER_MARKET: 16:00 - 20:00* - NO_TRADING: 20:00 - 24:00 (next day)*/const generateSessions = (from: number, to: number, options: GenerateSessionOptions): Promise<TradingSession[]> => {const tradingHours = options.tradingHours;return tradingHours? createReq(tradingHours).then((res: DxFeedScheduleResponse) => {const schedule = res[0][tradingHours].schedule;const days = schedule.days;const sessions = days.flatMap(day => day.sessions);// Map API format to chart format and filter by date rangereturn sessions.map(session => ({from: parseSessionTimestamp(`${session.startTime}`),to: parseSessionTimestamp(`${session.endTime}`),type: session.type,})).filter(session => session.to >= from && session.from <= to);}): Promise.resolve([]);};return {generateSessions,getTimeZone,};};
Key features
- Date range optimization: Requests 1 year of historical sessions and 14 days forward (required by DXcharts React)
- Request caching: Caches schedule requests per trading hours string (recommended)
- Timezone extraction: Retrieves timezone from schedule metadata (optional but recommended)
- Browser compatibility: Includes fallback for
Date.parse()in older browsers (probably not needed for modern apps) - Session filtering: Filters sessions to match requested date range (required)
Indicators that require Trading Session Provider
The following indicators require TradingSessionsProvider to work correctly:
VWAP (Volume Weighted Average Price)
Uses Trading Session Provider to calculate cumulative sum within a trading session.
HistoricalVolatility
PivotPoints
Uses Trading Session Provider to get previous aggregation data.
API reference
TradingSessionsProvider
To change the way trading sessions work
- TradingSessionsProvider.generateSessions
- Parameters
- from: number
- timestamp
- to: number
- timestamp
- options: GenerateSessionOptions
- see
- Returns
- Promise<TradingSession[]>
TradingSessionsProvider.generateSessions(from: number, to: number, options: GenerateSessionOptions): Promise<TradingSession[]>
Generates trading sessions
- TradingSessionsProvider.getTimeZone
- Parameters
- options: GenerateSessionOptions
- Returns
- Promise<string>
TradingSessionsProvider.getTimeZone(options: GenerateSessionOptions): Promise<string>
Returns timezone for specified symbol and trading hours