Skip to content

Instantly share code, notes, and snippets.

@PhHitachi
Created December 6, 2021 08:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhHitachi/bac5a7fe5c22c105773ada49efebb6e0 to your computer and use it in GitHub Desktop.
Save PhHitachi/bac5a7fe5c22c105773ada49efebb6e0 to your computer and use it in GitHub Desktop.
Impliment Real-time data without web-socket via BITQUERY GraphQL API
export const QUERY = {
GET_SYMBOL_INFO: `
query(
$network: EthereumNetwork!,
$baseAddress: String!,
$quoteAddress: String!
) {
ethereum(network: $network) {
dexTrades(
baseCurrency: {is: $baseAddress}
quoteCurrency: {is: $quoteAddress}
) {
baseCurrency {
name
symbol
decimals
}
quoteCurrency {
name
symbol
decimals
}
}
}
}
`,
GET_CANDLE_BARS: `
query(
$network: EthereumNetwork!,
$baseAddress: String!,
$quoteAddress: String!,
$from: ISO8601DateTime!,
$to: ISO8601DateTime!,
$interval: Int,
) {
ethereum(network: $network) {
dexTrades(
options: {
asc: "timeInterval.minute"
}
time: {
between: [$from, $to]
}
baseCurrency: { is: $baseAddress }
quoteCurrency: { is: $quoteAddress }
) {
high: quotePrice(calculate: maximum)
low: quotePrice(calculate: minimum)
open: minimum( of: block, get: quote_price)
close: maximum( of: block, get: quote_price)
volume: quoteAmount( in: USD)
timeInterval {
minute(count: $interval)
}
}
}
}
`,
GET_LAST_CANDLE_BAR: `
query(
$network: EthereumNetwork!,
$baseAddress: String!,
$quoteAddress: String!,
$from: ISO8601DateTime!,
$to: ISO8601DateTime!,
$interval: Int,
) {
ethereum(network: $network) {
dexTrades(
options: {
desc: "timeInterval.minute",
limit: 1
}
time: {
between: [$from, $to]
}
baseCurrency: { is: $baseAddress }
quoteCurrency: { is: $quoteAddress }
) {
high: quotePrice(calculate: maximum)
low: quotePrice(calculate: minimum)
open: minimum( of: block, get: quote_price)
close: maximum( of: block, get: quote_price)
volume: quoteAmount( in: USD)
timeInterval {
minute(count: $interval)
}
}
}
}
`,
}
import timestring from 'timestring'
import { getSymbol, getCandleBars, getLastPrice } from './rest'
var lastCandleTime = 0
const intervals = {
'1': '1m',
'5': '5m',
'15': '15m',
'30': '30m',
'60': '1h',
'120': '2h',
'240': '4h',
'1D': '1d',
'1W': '1w',
'1M': 'month'
}
var configurationData = {
supports_marks: true,
supports_timescale_marks: true,
supports_time: true,
supported_resolutions: Object.keys(intervals)
}
var setLastCandleTime = (data = null, time = null) => {
if (data != null && data.length) {
lastCandleTime = data.slice(-1)[0].time;
}
if (time != null) {
lastCandleTime = time;
}
return lastCandleTime;
}
var getLastCandleTime = () => {
return new Date(lastCandleTime).toISOString();
}
Date.prototype.getTimeToseconds = function() {
return this.getTime() / 1000;
}
export default (baseCurrency) => ({
onReady: (callback) => {
setTimeout(() => callback(configurationData));
},
resolveSymbol: async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
try {
getSymbol({
network: 'bsc',
baseAddress: baseCurrency,
quoteAddress: "0xe9e7cea3dedca5984780bafc599bd69add087d56",
}).then((data) => {
if (data) {
const {baseCurrency, quoteCurrency} = data;
return onSymbolResolvedCallback({
ticker: symbolName,
name: `${baseCurrency.name}/${quoteCurrency.symbol}`,
session: '24x7',
timezone: 'Etc/UTC',
minmov: 1,
pricescale: 10000000,
has_intraday: true,
intraday_multipliers: ['1', '5', '15', '30', '60'],
has_empty_bars: true,
has_weekly_and_monthly: false,
supported_resolutions: configurationData.supported_resolutions,
volume_precision: 1,
data_status: 'streaming',
});
}
});
} catch (err) {
console.log({ err })
onResolveErrorCallback(err)
}
},
getBars: async (symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) => {
try {
var { from, to, firstDataRequest } = periodParams;
if (firstDataRequest) setLastCandleTime(null, 0);
getCandleBars({
network: "bsc",
baseAddress: baseCurrency,
quoteAddress: "0xe9e7cea3dedca5984780bafc599bd69add087d56", //BUSD
from: new Date(from * 1000).toISOString(),
to: new Date(to * 1000).toISOString(),
interval: timestring(intervals[resolution], 'm')
}).then((data) => {
const bars = data.dexTrades.map(bar => ({
time: new Date(bar.timeInterval.minute).getTime(),
low: bar.low,
high: bar.high,
open: Number(bar.open),
close: Number(bar.close),
volume: bar.volume
}))
if (bars.length > 1) {
setLastCandleTime(bars)
onHistoryCallback(bars, { noData: false });
} else {
onHistoryCallback([], { noData: true });
}
});
} catch (err) {
console.log({ err })
onErrorCallback(err)
}
},
subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
window.interval = setTimeout(function() {
getLastPrice({
network: "bsc",
baseAddress: baseCurrency,
quoteAddress: "0xe9e7cea3dedca5984780bafc599bd69add087d56", //BUSD
from: getLastCandleTime(), //time from last candle bar data
to: new Date().toISOString(), //current time
interval: timestring(intervals[resolution], 'm')
}).then((data) => {
const bars = data.dexTrades.map(el => ({
time: new Date(el.timeInterval.minute).getTime(),
low: el.low,
high: el.high,
open: Number(el.open),
close: Number(el.close),
volume: el.volume
}))
onRealtimeCallback(bars[0])
});
}, 1000 * 5)
},
unsubscribeBars: (subscriberUID) => {
clearInterval(window.interval)
},
getMarks: (symbolInfo, startDate, endDate, onDataCallback, resolution) => {
},
getTimescaleMarks: (symbolInfo, from, to, onDataCallback, resolution) => {
}
})
import axios from 'axios'
import { QUERY } from './bitquery'
const baseURL = 'https://graphql.bitquery.io';
const X_API_KEY = "SECRET_KEY";
export const getSymbol = ({ network, baseAddress, quoteAddress }) => {
return bitquery('POST', '/', {
data: {
query: QUERY.GET_SYMBOL_INFO,
variables: JSON.stringify({ network, baseAddress, quoteAddress})
}
}).then((data) => data.ethereum.dexTrades[0])
}
export const getCandleBars = ({ network, baseAddress, quoteAddress, from, to, interval }) => {
return bitquery('POST', '/', {
data: {
query: QUERY.GET_CANDLE_BARS,
variables: JSON.stringify({ network, baseAddress, quoteAddress, from, to, interval })
}
}).then((data) => data.ethereum)
}
export const getLastPrice = ({ network, baseAddress, quoteAddress, from, to, interval }) => {
return bitquery('POST', '/', {
data: {
query: QUERY.GET_LAST_CANDLE_BAR,
variables: JSON.stringify({ network, baseAddress, quoteAddress, from, to, interval })
}
}).then((data) => data.ethereum)
}
export const bitquery = (method, url, params) => {
return axios({
url,
baseURL,
method,
mode: 'cors',
headers: {
"Content-Type": "application/json",
"X-API-KEY": X_API_KEY
},
...params
}).then((response) => {
return response.data.data;
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment