Charts Query
Retrieve OHLCV (Open, High, Low, Close, Volume) candlestick data for charting and technical analysis.Try It Now
Copy
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"query": "{ chartLogs(first: 5, where: { market: \"0xd99802ee8f16d6ff929e27546de15d03fdcce4bd\", intervalType: \"1h\" }, orderBy: timestamp, orderDirection: desc) { id timestamp open high low close baseVolume } }"}' \
https://api.goldsky.com/api/public/project_cmicv6kkbhyto01u3agb155hg/subgraphs/sera-pro/1.0.9/gn
Schema
Copy
type ChartLog {
id: ID! # market address + "-" + intervalType + "-" + timestamp
market: Market! # Parent market
intervalType: String! # Candle interval (1m, 5m, 15m, 1h, 4h, 1d, 1w)
timestamp: BigInt! # Candle start time (Unix seconds)
open: BigDecimal! # Opening price
high: BigDecimal! # Highest price in interval
low: BigDecimal! # Lowest price in interval
close: BigDecimal! # Closing price
baseVolume: BigDecimal! # Volume in base token
}
Supported Intervals
| Interval | Description |
|---|---|
1m | 1 minute |
3m | 3 minutes |
5m | 5 minutes |
15m | 15 minutes |
30m | 30 minutes |
1h | 1 hour |
2h | 2 hours |
4h | 4 hours |
6h | 6 hours |
1d | 1 day |
1w | 1 week |
Example Queries
Get Recent Candles
Copy
query GetCandles($marketId: String!, $interval: String!, $limit: Int!) {
chartLogs(
where: {
market: $marketId
intervalType: $interval
}
orderBy: timestamp
orderDirection: desc
first: $limit
) {
timestamp
open
high
low
close
baseVolume
}
}
Copy
{
"marketId": "0xd99802ee8f16d6ff929e27546de15d03fdcce4bd",
"interval": "1h",
"limit": 24
}
Get Candles in Time Range
Copy
query GetCandlesInRange(
$marketId: String!
$interval: String!
$startTime: BigInt!
$endTime: BigInt!
) {
chartLogs(
where: {
market: $marketId
intervalType: $interval
timestamp_gte: $startTime
timestamp_lte: $endTime
}
orderBy: timestamp
orderDirection: asc
first: 1000
) {
timestamp
open
high
low
close
baseVolume
}
}
Copy
{
"marketId": "0xd99802ee8f16d6ff929e27546de15d03fdcce4bd",
"interval": "1h",
"startTime": "1701561600",
"endTime": "1701648000"
}
Get Latest Candle
Copy
query GetLatestCandle($marketId: String!, $interval: String!) {
chartLogs(
where: {
market: $marketId
intervalType: $interval
}
orderBy: timestamp
orderDirection: desc
first: 1
) {
timestamp
open
high
low
close
baseVolume
}
}
Get Multi-Timeframe Data
Copy
query MultiTimeframe($marketId: String!) {
hourly: chartLogs(
where: { market: $marketId, intervalType: "1h" }
orderBy: timestamp
orderDirection: desc
first: 24
) {
timestamp
close
baseVolume
}
daily: chartLogs(
where: { market: $marketId, intervalType: "1d" }
orderBy: timestamp
orderDirection: desc
first: 7
) {
timestamp
open
high
low
close
baseVolume
}
}
Response Example
Copy
{
"data": {
"chartLogs": [
{
"timestamp": "1701648000",
"open": "2500.50",
"high": "2525.75",
"low": "2495.25",
"close": "2520.00",
"baseVolume": "1250.5"
},
{
"timestamp": "1701644400",
"open": "2480.25",
"high": "2505.00",
"low": "2478.50",
"close": "2500.50",
"baseVolume": "980.25"
}
]
}
}
Building a Chart
JavaScript Chart Data Formatter
Copy
async function getChartData(marketId, interval, candles = 100) {
const query = `
query ChartData($marketId: String!, $interval: String!, $candles: Int!) {
chartLogs(
where: { market: $marketId, intervalType: $interval }
orderBy: timestamp
orderDirection: desc
first: $candles
) {
timestamp
open
high
low
close
baseVolume
}
}
`;
const data = await querySubgraph(query, { marketId, interval, candles });
// Reverse to chronological order and format for charting libraries
return data.chartLogs
.reverse()
.map(candle => ({
time: Number(candle.timestamp),
open: parseFloat(candle.open),
high: parseFloat(candle.high),
low: parseFloat(candle.low),
close: parseFloat(candle.close),
volume: parseFloat(candle.baseVolume)
}));
}
// Usage with TradingView Lightweight Charts
const chartData = await getChartData(marketId, '1h', 168); // 1 week of hourly
candlestickSeries.setData(chartData);
Calculate Price Change
Copy
async function getPriceChange(marketId, interval, periods = 24) {
const data = await querySubgraph(`
query PriceChange($marketId: String!, $interval: String!, $periods: Int!) {
chartLogs(
where: { market: $marketId, intervalType: $interval }
orderBy: timestamp
orderDirection: desc
first: $periods
) {
close
}
}
`, { marketId, interval, periods });
if (data.chartLogs.length < 2) return null;
const current = parseFloat(data.chartLogs[0].close);
const previous = parseFloat(data.chartLogs[data.chartLogs.length - 1].close);
const change = current - previous;
const changePercent = (change / previous) * 100;
return {
current,
previous,
change,
changePercent: changePercent.toFixed(2)
};
}
Calculate 24h Volume
Copy
async function get24hVolume(marketId) {
const now = Math.floor(Date.now() / 1000);
const dayAgo = now - 86400;
const data = await querySubgraph(`
query Volume($marketId: String!, $since: BigInt!) {
chartLogs(
where: {
market: $marketId
intervalType: "1h"
timestamp_gte: $since
}
) {
baseVolume
}
}
`, { marketId, since: dayAgo.toString() });
return data.chartLogs.reduce(
(sum, candle) => sum + parseFloat(candle.baseVolume),
0
);
}
Calculate High/Low Range
Copy
async function get24hHighLow(marketId) {
const now = Math.floor(Date.now() / 1000);
const dayAgo = now - 86400;
const data = await querySubgraph(`
query HighLow($marketId: String!, $since: BigInt!) {
chartLogs(
where: {
market: $marketId
intervalType: "1h"
timestamp_gte: $since
}
) {
high
low
}
}
`, { marketId, since: dayAgo.toString() });
if (!data.chartLogs.length) return null;
const highs = data.chartLogs.map(c => parseFloat(c.high));
const lows = data.chartLogs.map(c => parseFloat(c.low));
return {
high: Math.max(...highs),
low: Math.min(...lows)
};
}
Notes
Candles are only created when there is trading activity. Gaps in data indicate no trades during that interval.
For real-time chart updates, poll the latest candle every few seconds and update incrementally.
