West
West

Reputation: 2570

How to receive data through websockets in python

I'm trying to retrieve data programmatically through websockets and am failing due to my limited knowledge around this. On visiting the site at https://www.tradingview.com/chart/?symbol=ASX:RIO I notice one of the websocket messages being sent out is ~m~60~m~{"m":"quote_fast_symbols","p":["qs_p089dyse9tcu","ASX:RIO"]}

My code is as follows:

from websocket import create_connection
import json 

ws = create_connection("wss://data.tradingview.com/socket.io/websocket?from=chart%2Fg0l68xay%2F&date=2019_05_27-12_19")

ws.send(json.dumps({"m":"quote_fast_symbols","p"["qs_p089dyse9tcu","ASX:RIO"]}))
result =  ws.recv()
print(result)
ws.close()

Result of the print:

~m~302~m~{"session_id":"<0.25981.2547>_nyc2-charts-3-webchart-5@nyc2-compute-3_x","timestamp":1558976872,"release":"registry:5000/tvbs_release/webchart:release_201-106","studies_metadata_hash":"888cd442d24cef23a176f3b4584ebf48285fc1cd","protocol":"json","javastudies":"javastudies-3.44_955","auth_scheme_vsn":2}

I get this result no matter what message I send out, out of the almost multitude of messages that seem to be sent out. I was hoping one of the messages sent back will be the prices info for the low and highs for RIO. Is there other steps I should include to get this data? I understand there might be some form of authorisation needed but I dont know the workflow.

Upvotes: 2

Views: 3508

Answers (1)

Paweł Zalewski
Paweł Zalewski

Reputation: 11

Yes, there is much more to setup and it needs to be done in order. The following example written in Node.js will subscribe to the BINANCE:BTCUSDT real time data and fetch historical 5000 bars on the daily chart.

  1. Ensure you have proper value of the origin field set in header section before connecting. Otherwise your connection request will be rejected by the proxy. I most common ws there is no way to do this. Use faye-websocket instead
const  WebSocket = require('faye-websocket')  

const  ws = new  WebSocket.Client('wss://data.tradingview.com/socket.io/websocket', [], {
  headers: { 'Origin':  'https://data.tradingview.com' }
});
  1. After connecting you need to setup your data stream. I don't know if all of this commands needs to be performed. This probably can be shrink even more but it works. Basically what you need to do is to create new quote and chart sessions and within these sessions request stream of the data of the prior resolved symbol.

ws.on('open', () => {

  const  quote_session = 'qs_' + getRandomToken()
  const  chart_session = 'cs_' + getRandomToken()
  const  symbol = 'BINANCE:BTCUSDT'
  const  timeframe = '1D'
  const  bars = 5000

  sendMsg(ws, "set_auth_token", ["unauthorized_user_token"])
  sendMsg(ws, "chart_create_session", [chart_session, ""])
  sendMsg(ws, "quote_create_session", [quote_session])
  sendMsg(ws, "quote_set_fields", [quote_session,"ch","chp","current_session","description","local_description","language","exchange","fractional","is_tradable","lp","lp_time","minmov","minmove2","original_name","pricescale","pro_name","short_name","type","update_mode","volume","currency_code","rchp","rtc"])
  sendMsg(ws, "quote_add_symbols",[quote_session, symbol, {"flags":['force_permission']}])
  sendMsg(ws, "quote_fast_symbols", [quote_session, symbol])
  sendMsg(ws, "resolve_symbol", [chart_session,"symbol_1","={\"symbol\":\""+symbol+"\",\"adjustment\":\"splits\",\"session\":\"extended\"}"])
  sendMsg(ws, "create_series", [chart_session, "s1", "s1", "symbol_1", timeframe, bars])

});

ws.on('message', (msg) => { console.log(`RX: ${msg.data}`) })
  1. And finally implementation of the helper methods

const  getRandomToken = (stringLength=12) => {
  characters = 'abcdefghijklmnopqrstuvwxyz0123456789'
  const  charactersLength = characters.length;
  let  result = ''
  for ( var  i = 0; i < stringLength; i++ ) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength))
  }
  return  result
}

const  createMsg = (msg_name, paramsList) => {
  const  msg_str = JSON.stringify({ m:  msg_name, p:  paramsList })
  return  `~m~${msg_str.length}~m~${msg_str}`
}

const  sendMsg = (ws, msg_name, paramsList) => {
  const  msg = createMsg(msg_name, paramsList)
  console.log(`TX: ${msg}`)
  ws.send(createMsg(msg_name, paramsList))
}

Upvotes: 1

Related Questions