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.
Try changing the arguments passed to the
candlesticks
method: addfalse
as an argument to the method call after theinterval
parameter: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:
https://github.com/jaggedsoft/node-binance-api/blob/master/node-binance-api.js#L3821-L3851