• Talinn, Estonia
  • support@lnsolutions.ee

Select your language

Bitcoin Trading Bot Development on Discord Trading Signals and LN Markets

Bitcoin Trading Bot Development on Discord Trading Signals and LN Markets

 

Read on Medium

 

Photo by Alex Knight on Unsplash

Introduction

Discord has become a cornerstone platform for communication among gamers, communities, and teams worldwide. The extensibility of Discord through bots has unlocked a plethora of possibilities, enabling automation, moderation, and enhanced user experiences. In this guide, we’ll delve into Discord bot development, using LN Markets as trading platform.

Trading signals Discord channels and groups are online communities where traders come together to share valuable insights, trading signals, and analyses pertaining to the crypto market. These channels and groups are hosted on the Discord messaging platform, enabling seamless real-time communication and information exchange among members.

LN Markets is a platform that enables users to trade Bitcoin futures contracts using the Lightning Network, a second-layer solution for faster and cheaper Bitcoin transactions. LN Markets leverages the Lightning Network’s micro-payment capabilities to provide instant settlement and low transaction fees for trading activities.

Overall, LN Markets provides a unique trading experience for Bitcoin enthusiasts and traders looking to participate in the cryptocurrency markets using the Lightning Network’s innovative technology.

Getting Started with Discord Bot Development

  • Understanding Discord Bots: Bots are automated agents that can perform various tasks on Discord servers, ranging from moderation to information retrieval.
  • Setting Up Your Development Environment: Install Node.js and Discord.js library to begin building your bot.
  • Creating Your First Bot: Let’s create a simple bot that responds to commands and interacts with users.
// Import necessary modules
const Discord = require('discord.js');
const client = new Discord.Client();

// Define bot behavior
client.on('message', message => {
if (message.content === '!hello') {
message.reply('Hello, world!');
}
});

// Log in to Discord with your bot token
client.login('YOUR_DISCORD_BOT_TOKEN');

Essential Bot Features and Functionality

  • Message Handling: Read and respond to messages from users, including commands and regular chat.
  • User Interaction: Engage with users through reactions, mentions, and interactive commands.
  • Server Management: Join servers, manage channels, and handle server events like member joins or leaves.
  • Role Management: Assign roles, manage permissions, and enforce server rules.

Here we will just focus on reading the last message from the trading channel

// Register event for when client receives a message.
client.on('message', message => {
console.log(message.content);
processSignal(message);
});

Parsing the text and trading on LN Markets

We need to install the ln-markets api for our project via this command:

 npm install @ln-markets/api

The next code snippet will open a connection to the LN Markets API.

import { createRestClient } from '@ln-markets/api';

const key = config.lnmarketsKey.trim();
const secret = config.lnmarketsSecret.trim();
const passphrase = config.lnmarketsPassphrase.trim();
const network = 'testnet';
const lnclient = createRestClient({ key, secret, passphrase });

Now we parse the text from the Discord message and trade accordingly. In this example the signal didn’t come in plain text, but it used some rich text features from Discord (message.embeds), so these fields had to be parsed and not only the message.text field.

async function processSignal(message) {
if (message.embeds.length > 0 && message.embeds[0].title.includes('Buy Signal!')) {
// Extract trade information
let entryPrice = null;
let stopLoss = null;
let takeProfit = null;

// Split message content by lines
const createdTimestamp = message.createdTimestamp;
const lines = message.embeds[0].fields;
lines.forEach((line, index) => {
if (line.name.includes('Entry Price')) {
const priceLine = line.value.replace(/`/g, '');
entryPrice = parseFloat(priceLine);
} else if (line.name.includes('Stop Loss')) {
const priceLine = line.value.replace(/`/g, '');
stopLoss = Math.round(parseFloat(priceLine)) + 0.5;
} else if (!line.value.includes('There will be a separate signal to take profit') && line.name.includes('Take Profit')) {
const priceLine = line.value.replace(/`/g, '');
takeProfit = Math.round(parseFloat(priceLine)) + 0.5;
} else if (line.value.includes('There will be a separate signal to take profit that could be higher than this price.')) {
const regex = /```(\d+(\.\d+)?)```/;
// Extract the numeric value using the match method and regular expression
const match = line.value.match(regex);
if (match) {
// Extract the numeric value from the matched string
const priceLine = parseFloat(match[1]);
takeProfit = Math.round(parseFloat(priceLine)) + 0.5;
}
}
});

if (entryPrice !== null && stopLoss !== null) {
console.log(`Entry Price: ${entryPrice}`);
console.log(`Stop Loss: ${stopLoss}`);
if (takeProfit !== null) {
console.log(`Take Profit: ${takeProfit}`);
}

await getBuyTrade(createdTimestamp, takeProfit, stopLoss, entryPrice);
}
} else if (message.embeds.length > 0 && message.embeds[0].title.includes('Sell Signal!')) {
let sellPrice = null;

const createdTimestamp = message.createdTimestamp;
const lines = message.embeds[0].fields;
lines.forEach((line, index) => {
if (line.value.includes('position has been closed at:')) {
const regex = /```(\d+(\.\d+)?)```/;
// Extract the numeric value using the match method and regular expression
const match = line.value.match(regex);
if (match) {
// Extract the numeric value from the matched string
const priceLine = parseFloat(match[1]);
sellPrice = parseFloat(priceLine);
}
}
});

if (sellPrice !== null) {
console.log(`Sell Price: ${sellPrice}`);
await getTradeByTimestamp(createdTimestamp, (err, rows) => {
if (err) {
console.error(err.message);
} else {
// Check if any rows were returned
if (rows.length > 0) {
// Assuming id is the first column in the result set
const tradeId = rows[0].id;
console.log('Trade ID in Sell:', tradeId);
} else if (lastBuyTradeId != null) { // This is a new sell trade
// Perform Sell Trade in LNMarkets
const data = {
id: lastBuyTradeId,
};

console.log(data);

const trade = lnclient.futuresCloseTrade(lastBuyTradeId).then((response) => {
saveToDatabase(response.id, createdTimestamp, 0.0, 0.0, sellPrice, response.pl, 'Sell');
})
.catch((err) => {
// Handle error
console.error(err.message);
});

}
}
});
}
}
}

async function getBuyTrade(createdTimestamp, takeProfit, stopLoss, entryPrice) {
try {
// Call getTradeByTimestamp and wait for it to complete
const rows = await new Promise((resolve, reject) => {
getTradeByTimestamp(createdTimestamp, (err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
});
});

// Check if any rows were returned
if (rows.length > 0) {
const tradeId = rows[0].id;
lastBuyTradeId = tradeId;
console.log('Trade ID in Buy:', tradeId);
} else {
// Perform Trade in LNMarkets
let data = {
"type": 'm',
"side": 'b',
"leverage": LEVERAGE,
"quantity": QUANTITY,
"takeprofit": takeProfit,
"stoploss": stopLoss
};

const trade = await lnclient.futuresNewTrade(data);
saveToDatabase(trade.id, createdTimestamp, entryPrice, stopLoss, takeProfit, 0.0, 'Buy');
}
} catch (error) {
console.error(error.message);
}

In the previous code snippet, the function getBuyTrade uses getTradeByTimestamp, which queries a local sqlite database file to query if this trade was already done. The function saveToDatabase saves the trade to this database when the trade is new. This in order to execute each trade only once.

function saveToDatabase(lnMarketsId, createdTimestamp, entryPrice, stopLoss, takeProfit, profit, tradeType) {
lastBuyTradeId = lnMarketsId;
createTrade(lnMarketsId, createdTimestamp, entryPrice, stopLoss, takeProfit, profit, tradeType, err => {
if (err) {
console.error(err.message);
} else {
console.log(tradeType + " Trade created successfully!");
}
});
}

Finally we add some cleanup code for our database connection

// Clean up database connection when the application exits
process.on('exit', () => {
closeConnection();
console.log('Database connection closed');
});

// Handle Ctrl+C (SIGINT) signal
process.on('SIGINT', () => {
closeConnection();
console.log('Database connection closed');
process.exit();
});

Conclusion

In this guide we saw an introduction on how to program a Bitcoin trading bot on LN Markets, based on trading signals sent to a specific Discord channel. By mastering the concepts and techniques outlined in this guide, you’ll be well-equipped to build bots that take signals on specific trading servers and automate your trading

References

 
recent posts
  • Talinn, Estonia
  • support@lnsolutions.ee
About
We support your software projects and solutions. We specialize in Java Backend, Web development, BPM Workflow design and Bitcoin payment solutions.
Subscribe