Search code examples
javascriptnode.jsbinance

TypeError: callback.call is not a function


config.json:

{
  "exchangeSettings": {
    "name": "Binance",
    "api": {
      "apiKey": "********************",
      "secret": "********************"
    },
    "testMode": true
  },
  "strategy": {
    "shortSMA": 7,
    "longSMA": 25,
    "interval": 3600000,
    "tradeSymbol": "BNBUSDT",
    "tradeQuantity": 0.1,
    "maxTradeQuantity": 1,
    "stopLossPercentage": 5,
    "takeProfitPercentage": 10,
    "maxDrawdownPercentage": 20,
    "riskRewardRatio": 2
  },
  "notificationSettings": {
    "enableEmail": true,
    "email": "*******@yahoo.com",
    "smtpSettings": {
      "host": "smtp.mail.yahoo.com",
      "port": 465,
  "username": "*******@yahoo.com",
  "password": "**********",
      "secure": true
    }
  },
  "logging": {
    "logLevel": "INFO",
    "logToFile": true,
    "filePath": "/Users/olugbengaoyeneye/GinBot/log"
  }
}

Bot.js:

// bot.js

// Import necessary libraries
const fs = require('fs');
const Binance = require('node-binance-api');

// Load configuration
const configPath = './config.json';
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

// Initialize the Binance bot
const binance = new Binance().options({
  APIKEY: config.exchangeSettings.api.apiKey,
  APISECRET: config.exchangeSettings.api.secret,
  useServerTime: true,
  test: config.exchangeSettings.testMode // Set to true for testing
});

// Function to calculate Simple Moving Average
function calculateSMA(data, period) {
    let sum = 0;
    for (let i = 0; i < period; i++) {
        sum += parseFloat(data[i]);
    }
    return sum / period;
}

// Function to fetch and display account balance
const displayBalance = async () => {
  try {
    const balanceData = await binance.balance();
    console.log("Account balances:", balanceData);
  } catch (error) {
    console.error("Error fetching balance:", error);
  }
};

// Function to execute the trading strategy
const executeStrategy = async () => {
  try {
    console.log("Executing trading strategy...");

    // Fetch historical candlestick data
    let candles = await binance.candlesticks(config.strategy.tradeSymbol, '1h', {limit: 50});
    let closingPrices = candles.map(candle => candle[4]); // 4th element is the closing price

    // Calculate short-term and long-term SMAs
    let shortSMA = calculateSMA(closingPrices, config.strategy.shortSMA);
    let longSMA = calculateSMA(closingPrices, config.strategy.longSMA);

    console.log(`Short SMA: ${shortSMA}, Long SMA: ${longSMA}`);

    // Implement the SMA crossover strategy
    if (shortSMA > longSMA) {
        console.log("Short SMA is above Long SMA. Consider buying.");
        // Add buy logic here
    } else if (shortSMA < longSMA) {
        console.log("Short SMA is below Long SMA. Consider selling.");
        // Add sell logic here
    } else {
        console.log("No clear trend. Hold.");
    }

    // Add more trading logic as needed
  } catch (error) {
    console.error("Error executing strategy:", error);
  }
};

// Function to start the trading bot
const startTradingBot = () => {
  console.log("Starting Trading Bot...");

  // Display account balance
  displayBalance();

  // Execute the strategy at the interval specified in the config
  setInterval(executeStrategy, config.strategy.interval);
};

// Start the bot
startTradingBot();

Output including the error message:

olugbengaoyeneye@Olugbengas-MBP GinBot % node bot.js           
Starting Trading Bot...
(node:37772) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Account balances: {
  BTC: { available: '0.00000000', onOrder: '0.00000000' },
  LTC: { available: '0.00000000', onOrder: '0.00000000' },
  ETH: { available: '0.00003672', onOrder: '0.00000000' },

. . .


  MEME: { available: '0.00000000', onOrder: '0.00000000' },
  TIA: { available: '0.00000000', onOrder: '0.00000000' }
}

Executing trading strategy...
Error executing strategy: TypeError: Cannot read properties of undefined (reading 'map')
    at Timeout.executeStrategy [as _onTimeout] (/Users/olugbengaoyeneye/GinBot/bot.js:45:33)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
/Users/olugbengaoyeneye/GinBot/node_modules/node-binance-api/node-binance-api.js:3847
                    return callback.call( this, error, data, symbol );
                                    ^

TypeError: callback.call is not a function
    at /Users/olugbengaoyeneye/GinBot/node_modules/node-binance-api/node-binance-api.js:3847:37
    at Request._callback (/Users/olugbengaoyeneye/GinBot/node_modules/node-binance-api/node-binance-api.js:188:16)
    at self.callback (/Users/olugbengaoyeneye/GinBot/node_modules/request/request.js:185:22)
    at Request.emit (node:events:515:28)
    at Request.<anonymous> (/Users/olugbengaoyeneye/GinBot/node_modules/request/request.js:1154:10)
    at Request.emit (node:events:515:28)
    at IncomingMessage.<anonymous> (/Users/olugbengaoyeneye/GinBot/node_modules/request/request.js:1076:12)
    at Object.onceWrapper (node:events:629:28)
    at IncomingMessage.emit (node:events:527:35)
    at endReadableNT (node:internal/streams/readable:1589:12)

Node.js v21.1.0
olugbengaoyeneye@Olugbengas-MBP GinBot % 

Error message:

/Users/olugbengaoyeneye/GinBot/node_modules/node-binance-api/node-binance-api.js:3847
                    return callback.call( this, error, data, symbol );
                                    ^

TypeError: callback.call is not a function

I have ran: 'npm update'

I keep getting the error: 'callback.call is not a function'

I have tried everything I could.


Solution

  • Try changing the arguments passed to the candlesticks method: add false as an argument to the method call after the interval parameter:

    let candles = await binance.candlesticks(config.strategy.tradeSymbol, '1h', false, {limit: 50});
    

    If you check the source code, in place of callback parameter, you're actually passing options object, which causes the error (it's trying to invoke .call, but instead of a function, it got an object..).

    src code:

        * @return {promise or undefined} - omitting the callback returns a promise
        */
        candlesticks: function ( symbol, interval = '5m', callback = false, options = { limit: 500 } ) {
    

    https://github.com/jaggedsoft/node-binance-api/blob/master/node-binance-api.js#L3821-L3851