Monitoring Price for Execution

You can directly listen to the Binance API for monitoring the price of a pair. In this simple trading bot example, we're placing a LONG/SHORT order depending on whether the price we receive from Binance is above or below a certain threshold. In practice, you could use technical indicators to decide how to place orders, or automatically place orders to hedge against LP positions.

async function startPriceMonitoring(subAccount) {
  let binanceWs; 
  try {
      const { markets } = await fetchMarketSymbolId(config.HEDGER_URL, userConfig.SYMBOL);
      if (markets.length === 0) {
          console.error("No markets found for the specified symbol.");
          return;
      }
      const binanceId = markets[0].name;
      console.log("Market Name:", binanceId);
      const marketId = markets[0].id;
      console.log("Market ID:", marketId);
      binanceWs = new WebSocket('wss://fstream.binance.com/stream?streams=' + binanceId.toLowerCase() + '@ticker');
      binanceWs.on('open', function open() {
      console.log('Connected to Binance WebSocket');
      });
      binanceWs.on('message', (message) => {
          handleMessage(message, subAccount, marketId, binanceWs); // Pass WebSocket instance for handling
      });
  } catch (error) {
      console.error("Error setting up price monitoring:", error);
      closeAndExit(binanceWs, error); 
  }
}

Function Overview

  • Fetches a market filtered by the userConfig.SYMBOL using the fetchMarketSymbolId function.

  • Validates the presence of the market in the returned data.

  • Opens a WebSocket connection to Binance's streaming endpoint for the specified market symbol's ticker data.

  • Sets up event listeners for the WebSocket connection to handle open and message events.

Handling the Message

In this example, we're taking an action if the price goes out of a certain range. If the price is greater than userConfig.UPPER_THRESHOLD_PRICE, we'll open a SHORT position, and if it's lower than the userConfig.LOWER_THRESHOLD_PRICE, we'll open a LONG position. The actionTaken flag prevents the bot from executing many orders in a short duration, but ideally a debouncer or cooldown should be implemented.

let actionTaken = false;
async function handleMessage(message, botAddress, marketId, binanceWs) {
  if (actionTaken) return; 
  
  //Getting Price
  const data = JSON.parse(message);
  const price = parseFloat(data.data.c);
  console.log(`Current Price of ${userConfig.SYMBOL}: `, price, "Lower:", userConfig.LOWER_THRESHOLD_PRICE, "Upper:", userConfig.UPPER_THRESHOLD_PRICE);
    
  //Shorting if over
  if (price > userConfig.UPPER_THRESHOLD_PRICE && accountSetup) {
      console.log(`Price over threshold: ${price}`);
      try {
          console.log("Shorting...");
          await executeSendQuoteMarket(botAddress, 1, userConfig.QUANTITY, "auto");
          actionTaken = true; // Prevent further actions
          closeAndExit(binanceWs);
      } catch (error) {
          closeAndExit(binanceWs, error);
      }
       //Longing if under
  } else if (price < userConfig.LOWER_THRESHOLD_PRICE && accountSetup) {
      console.log(`Price under threshold: ${price}`);
      try {
          console.log("Longing...");
          await executeSendQuoteMarket(subAccount, 0, userConfig.QUANTITY, "auto"); 
          actionTaken = true; 
          closeAndExit(binanceWs);
      } catch (error) {
          closeAndExit(binanceWs, error);
      }
  }
}

In this implementation, we're only using the market price, but frontends typically use the Bid/Ask prices to guarantee order execution. These are also streamed from Binance's API. The documentation for querying these can be found here under "Individual Symbol Book Ticker Streams".

Last updated