Last active
February 4, 2025 10:09
-
-
Save brandonros/a85561837b7428d8416440e08fd6a62a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import WebSocket from 'ws' | |
const parseWsPacket = (str) => { | |
const cleanerRgx = /~h~/g | |
const splitterRgx = /~m~[0-9]{1,}~m~/g | |
return str | |
.replace(cleanerRgx, '') | |
.split(splitterRgx) | |
.map((p) => { | |
if (!p) return false | |
try { | |
return JSON.parse(p) | |
} catch (error) { | |
console.warn('Cant parse', p) | |
return false | |
} | |
}) | |
.filter((p) => p) | |
} | |
const formatWsPacket = (packet) => { | |
const msg = typeof packet === 'object' | |
? JSON.stringify(packet) | |
: packet | |
return `~m~${msg.length}~m~${msg}` | |
} | |
const sendFormattedWsPacket = (socket, packet) => socket.send(formatWsPacket(packet)) | |
const authToken = 'unauthorized_user_token' | |
const stockExchange = 'AMEX' // American Stock Exchange | |
const ticker = 'SPY' // SPDR S&P 500 ETF Trust | |
const quoteSessionId = 'qs_QUOTE_SESSIONID_1234' | |
const qs = new URLSearchParams() | |
qs.append('from', `symbols/${stockExchange}-${ticker}/`) | |
const socket = new WebSocket(`wss://data.tradingview.com/socket.io/websocket?${qs.toString()}`, { | |
origin: 'https://s.tradingview.com' | |
}) | |
socket.on('open', () => { | |
console.log('opened') | |
// set auth | |
sendFormattedWsPacket(socket, { m: 'set_auth_token', p: [authToken] }) | |
// quote session | |
sendFormattedWsPacket(socket, { m: 'quote_create_session', p: [quoteSessionId] }) | |
sendFormattedWsPacket(socket, { m: 'quote_add_symbols', p: [quoteSessionId, `${stockExchange}:${ticker}`] }) // extended: ={"session":"extended","symbol":"AMEX:SPY"} | |
}) | |
socket.on('error', (err) => { | |
console.log('error') | |
console.error(err) | |
process.exit(1) | |
}) | |
socket.on('close', () => { | |
console.log('closed') | |
process.exit(1) | |
}) | |
socket.on('message', (event) => { | |
const parsedPackets = parseWsPacket(event.toString()) | |
for (let i = 0; i < parsedPackets.length; ++i) { | |
const parsedPacket = parsedPackets[i] | |
const isPing = typeof parsedPacket === 'number' | |
if (isPing) { | |
sendFormattedWsPacket(socket, `~h~${parsedPacket}`) | |
} else { | |
console.log(JSON.stringify(parsedPacket)) | |
} | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment