Quantcast
Channel: Active questions tagged datafeed - Stack Overflow
Viewing all articles
Browse latest Browse all 48

how should i feed the trading view widget with own socket data (datafeed)

$
0
0

I've created a DataFeed class that establishes a WebSocket connection to stream real-time data for use in a TradingView chart. Here's the code for the class:

export default class DataFeed {  constructor(symbol) {    this.symbol = symbol;    this.socket = new WebSocket("ws://socket");    this.subscribers = {};    this.pingInterval = null;    this.socket.onopen = () => {      console.log("WebSocket connection established");      this.subscribe(this.symbol, "1m"); // Default to '1m' interval      this.startPing(); // Start the ping interval    };    this.socket.onmessage = (event) => this.onMessage(event);    this.socket.onerror = (error) => console.error("WebSocket Error:", error);    this.socket.onclose = () => console.log("WebSocket closed");  }  onMessage(event) {    const message = event?.data;    if (message.includes("welcome") || message.includes("Welcome")) {      return;    }    try {      const receivedData = JSON.parse(message);      this.processData(receivedData);    } catch (error) {      console.error("Failed to parse WebSocket message:", message, error);    }  }  subscribe(symbol, resolution) {    const subscribeMessage = JSON.stringify({      action: "subscribe",      channel: `kline_${resolution}`,      symbol: [`${symbol}_USDT`],    });    this.socket.send(subscribeMessage);  }  startPing() {    if (this.pingInterval) {      clearInterval(this.pingInterval);    }    this.pingInterval = setInterval(() => {      if (this.socket.readyState === WebSocket.OPEN) {        this.socket.send(          JSON.stringify({            action: "ping",            symbol: [],            channel: "heartbeat",          })        );      }    }, 5000);  }  processData(message) {    const { data } = message;    if (!data || !data.startTime || data === "pong") {      return;    }    const bar = {      time: new Date(data.startTime).getTime(),      close: parseFloat(data.closePrice),      open: parseFloat(data.openPrice),      high: parseFloat(data.highPrice),      low: parseFloat(data.lowPrice),      volume: parseFloat(data.volume),    };    console.log("Processed bar data:", bar?.close, bar?.volume);    // Notify all subscribers about the new bar    Object.values(this.subscribers).forEach((sub) =>      sub.forEach((s) => s.callback(bar))    );  }  onReady(callback) {    callback({      supported_resolutions: ["1", "5", "15", "30", "60", "D", "W", "M"],      supports_marks: false,      supports_timescale_marks: false,      supports_time: true,    });  }  resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {    setTimeout(() => {      onSymbolResolvedCallback({        name: symbolName,        description: symbolName,        type: "crypto",        session: "24x7",        timezone: "Etc/UTC",        ticker: symbolName,        minmov: 1,        pricescale: 100,        has_intraday: true,        has_daily: true,        has_weekly_and_monthly: true,        supported_resolutions: ["1","3","5","15","30","60","120","240","D",        ],        data_status: "streaming",      });    }, 0);  }  subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscriberUID, onResetCacheNeededCallback) {    if (!this.subscribers[symbolInfo.ticker]) {      this.subscribers[symbolInfo.ticker] = [];    }    this.subscribers[symbolInfo.ticker].push({ callback: onRealtimeCallback });    this.subscribe(symbolInfo.ticker, resolution);  }  unsubscribeBars(subscriberUID) {    for (let symbol in this.subscribers) {      this.subscribers[symbol] = this.subscribers[symbol].filter(        (sub) => sub.uid !== subscriberUID      );    }  }}

Viewing all articles
Browse latest Browse all 48

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>