Overview
The CandleClient provides a high-level interface for fetching historical candle data and subscribing to real-time candle updates from the Drift Data API.
If you’re using TradingView, consider using DriftTvFeed instead, which wraps the CandleClient with TradingView-specific functionality.
Key Features
Fetch Historical Candles : Retrieve candles for any timestamp range
Real-time Subscriptions : Subscribe to live candle updates via websocket
Intelligent Caching : Recent candles (last 1000) cached for instant retrieval
Optimized API Requests : Avoids high-cardinality parameters for better cache hits
Multiple Concurrent Subscriptions : Support for multiple markets/resolutions simultaneously
Architecture
Fetching Candles
Maximum 1000 candles per request (see CANDLE_FETCH_LIMIT)
“Recent history” = last 1000 candles
Recent candles fetched without startTs parameter for better caching
In-memory cache stores recent candles to avoid redundant fetches
Subscribing to Candles
Websocket endpoint for each market/resolution combination
Multiple concurrent subscriptions supported
Uses MarketDataFeed internally for websocket management
Constructor
const candleClient = new CandleClient ();
No configuration required - the client is ready to use immediately.
Methods
fetch
Fetch historical candles for a specific time range.
async fetch ( config : CandleFetchConfig ): Promise < JsonCandle [] >
Parameters
config
CandleFetchConfig
required
Configuration for fetching candles Show CandleFetchConfig properties
Environment configuration (mainnet/devnet/staging)
Market identifier (perp or spot)
Candle resolution (‘1’, ‘5’, ‘15’, ‘60’, ‘240’, ‘D’)
Start timestamp in seconds (oldest candle)
End timestamp in seconds (newest candle)
Returns
Promise resolving to array of JsonCandle objects, sorted ascending by time (oldest first).
Example
import { CandleClient } from '@drift-labs/common' ;
import { MarketId } from '@drift-labs/common' ;
const candleClient = new CandleClient ();
const candles = await candleClient . fetch ({
env: { sdkEnv: 'mainnet-beta' , isDevnet: false , isStaging: false , key: 'mainnet' },
marketId: MarketId . createPerpMarketId ( 0 ), // SOL-PERP
resolution: '15' , // 15-minute candles
fromTs: Math . floor ( Date . now () / 1000 ) - 86400 , // Last 24 hours
toTs: Math . floor ( Date . now () / 1000 )
});
console . log ( `Fetched ${ candles . length } candles` );
candles . forEach ( candle => {
console . log ( ` ${ new Date ( candle . ts * 1000 ) } : O= ${ candle . open } H= ${ candle . high } L= ${ candle . low } C= ${ candle . close } ` );
});
subscribe
Subscribe to real-time candle updates for a specific market and resolution.
async subscribe (
config : CandleSubscriptionConfig ,
subscriptionKey : string
): Promise < void >
Parameters
config
CandleSubscriptionConfig
required
Subscription configuration Show CandleSubscriptionConfig properties
Candle resolution to subscribe to
Environment configuration
Unique key to identify this subscription (used for unsubscribing)
If a subscription with the same key already exists, it will be automatically unsubscribed before creating the new one.
Example
import { CandleClient } from '@drift-labs/common' ;
import { MarketId } from '@drift-labs/common' ;
const candleClient = new CandleClient ();
const subscriptionKey = 'sol-perp-15m' ;
// Subscribe to candles
await candleClient . subscribe (
{
env: { sdkEnv: 'mainnet-beta' , isDevnet: false , isStaging: false , key: 'mainnet' },
marketId: MarketId . createPerpMarketId ( 0 ), // SOL-PERP
resolution: '15'
},
subscriptionKey
);
// Listen for candle updates
candleClient . on ( subscriptionKey , 'candle-update' , ( candle ) => {
console . log ( 'New candle:' , candle );
});
Attach an event listener to a subscription.
on (
subscriptionKey : string ,
event : 'candle-update' ,
listener : ( candle : JsonCandle ) => void
): void
Parameters
The subscription key used when calling subscribe()
Event type (currently only ‘candle-update’ is supported)
listener
(candle: JsonCandle) => void
required
Callback function to handle candle updates
unsubscribe
Unsubscribe from a specific subscription.
unsubscribe ( subscriptionKey : string ): void
Parameters
The subscription key to unsubscribe
Example
candleClient . unsubscribe ( 'sol-perp-15m' );
unsubscribeAll
Unsubscribe from all active subscriptions.
Example
candleClient . unsubscribeAll ();
Static Cache Methods
The CandleFetcher internal class provides static cache management methods:
clearWholeCache
Clear the entire candle cache.
CandleFetcher . clearWholeCache (): void
clearCacheForSubscription
Clear cache for a specific market and resolution.
CandleFetcher . clearCacheForSubscription (
marketId : MarketId ,
resolution : CandleResolution
): void
Types
JsonCandle
interface JsonCandle {
ts : number ; // Timestamp in seconds
open : number ; // Opening price
high : number ; // Highest price
low : number ; // Lowest price
close : number ; // Closing price
volume : number ; // Volume
}
CandleResolution
type CandleResolution = '1' | '5' | '15' | '60' | '240' | 'D' ;
// 1 = 1 minute
// 5 = 5 minutes
// 15 = 15 minutes
// 60 = 1 hour
// 240 = 4 hours
// D = 1 day
Caching Strategy
The client implements a two-tier caching approach:
Recent Candles Cache : Stores the last 1000 candles per market/resolution
URL Cache : Caches constructed URLs to avoid repeated string operations
API Request Optimization
Recent history requests (within last 1000 candles): Omits startTs parameter for better CDN caching
Historical requests (beyond 1000 candles): Uses startTs with pagination
// Fetching large date ranges is handled automatically
const candles = await candleClient . fetch ({
env: mainnetEnv ,
marketId: solPerpMarketId ,
resolution: '15' ,
fromTs: thirtyDaysAgo ,
toTs: now
});
// The client automatically:
// 1. Calculates number of candles needed
// 2. Makes multiple paginated requests if needed
// 3. Combines results into a single sorted array
Common Patterns
Multiple Market Subscriptions
const markets = [
{ id: MarketId . createPerpMarketId ( 0 ), name: 'SOL-PERP' },
{ id: MarketId . createPerpMarketId ( 1 ), name: 'BTC-PERP' },
{ id: MarketId . createPerpMarketId ( 2 ), name: 'ETH-PERP' }
];
for ( const market of markets ) {
const key = ` ${ market . name } -15m` ;
await candleClient . subscribe ({
env: mainnetEnv ,
marketId: market . id ,
resolution: '15'
}, key );
candleClient . on ( key , 'candle-update' , ( candle ) => {
console . log ( ` ${ market . name } update:` , candle );
});
}
Cleanup on Component Unmount
// React example
useEffect (() => {
const subscriptionKey = 'sol-perp-15m' ;
candleClient . subscribe ( config , subscriptionKey );
candleClient . on ( subscriptionKey , 'candle-update' , handleUpdate );
return () => {
candleClient . unsubscribe ( subscriptionKey );
};
}, []);
MarketDataFeed Internal websocket manager used by CandleClient
Data API Reference Official Drift Data API documentation