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

Logo

All rights to the people (c) 2023 Symmetry Labs A.G.