Em outro momento eu escrevi um tutorial aqui no blog sobre como fazer um bot que envia mensagens via Telegram. Isso é extremamente útil para quem deseja montar uma sala de sinais automatizada, por exemplo, pois aí seu bot fica monitorando o mercado e enviando os sinais conforme os indicadores configurados nele. No tutorial de hoje eu quero fazer o caminho contrário: imagina que você tem/está em uma sala de sinais e deseja programar um bot de Telegram para aguardar por estes sinais e efetuar os trades automaticamente para você conforme o que eles dizem.
Vamos lá!
(se preferir, pode assistir ao vídeo abaixo, com o mesmo conteúdo)
#1 – Setup do Bot
A primeira coisa que você tem de fazer é criar o bot de Telegram que fará o envio de mensagens para você. Para fazer isso, primeiro fale com o BotFather. O BotFather é o bot que lhe ajuda na criação de bots. Após chamar o @BotFather para conversar (pode clicar no link do nome dele), clique no botão de start na tela do Telegram (abaixo estou usando o TelegramWeb).
Vai se abrir uma série de comandos que você pode digitar, e você precisa usar primeiro o /newbot, dando um nome ao seu bot logo em seguida, sendo que ele deve terminar sempre com ‘bot’. O meu vai se chamar LuizToolsBot. Sim, não sou criativo.
Uma vez que termine a criação, você receberá a URL para conversar com seu bot e um token, que você deve salvar para usarmos a seguir no nosso código de interação com o bot. Cuidado, pois quem tiver esse token pode tomar o controle do seu bot!
Na sequência, se você pretende colocar o seu bot em um grupo de Telegram para ouvir sinais, você precisa desativar a funcionalidade de privacidade. Por padrão bots até podem ser adicionados em grupos, mas não podem receber as mensagens gerais do mesmo. Então chame o botfather novamente, escolha a opção /setprivacy, depois escolha seu bot e por último selecione a opção disabled para que a privacidade do bot em grupos seja desativada.
Isso vai fazer com que seu bot esteja criado e pronto para receber mensagens em grupos que você colocar ele, mesmo que não estejam direcionadas a ele.
#2 – Setup do Projeto
Para este projeto você vai precisar ter o ambiente preparado para programar Node.js. Caso não tenha, o vídeo abaixo ensina a configurar.
Uma vez com tudo instalado e funcionando, crie uma nova pasta para o projeto, que eu vou chamar de binance-telegram e dentro rode o comando abaixo para inicializar o projeto.
1 2 3 |
npm init -y |
Depois, instale a dependência do Telegraf, com o comando abaixo. O Telegraf é uma biblioteca JavaScript para comunicação no Telegram usando um bot.
1 2 3 |
npm i telegraf dotenv axios |
Também instalei o pacote DotEnv, para nos ajudar com as configurações do projeto e o pacote Axios para as chamadas à API que faremos mais tarde.
Agora crie um arquivo .env na raiz do projeto também, com o conteúdo abaixo. Preencha seu bot token adequadamente, conforme recebido no passo anterior.
1 2 3 |
BOT_TOKEN=<SEU BOT TOKEN> |
Pronto, com isso temos tudo pronto e configurado, hora de programar o bot.
#3 – Programando o Bot
Agora crie um arquivo index.js que é onde vamos programar usando Telegraf. Ele vai usar as variáveis de ambiente que configuramos para ter acesso ao bot token.
1 2 3 4 5 6 7 8 9 10 11 12 |
require('dotenv').config(); const { Telegraf } = require('telegraf'); const { message } = require('telegraf/filters'); const bot = new Telegraf(process.env.BOT_TOKEN); //tratamento das mensagens vai aqui bot.launch(); |
O código acima carrega as variáveis de ambiente na primeira linha e inicializa o Telegraf com o token do seu bot. A partir de então o seu bot vai estar escutando por qualquer mensagem enviada no seu grupo e você pode programá-lo para interpretá-la, como abaixo, onde programei para que quando ele receber uma mensagem de texto vindo de uma pessoa específica, que ele responda ela.
1 2 3 4 5 6 7 8 |
bot.on(message('text'), async (ctx) => { if(ctx.from.username !== "luiztools") return; console.log(ctx.message.text); await ctx.reply(`Hello ${ctx.from.first_name}`); }); |
Assim como adicionei uma condição em cima do from da mensagem recebida, podemos adicionar lógica em cima do conteúdo da mensagem, seja com ifs, seja com regex, o céu é o limite aqui. Abaixo, um exemplo de condição baseada no sinal, se ele é de compra ou de venda.
1 2 3 4 5 6 7 8 9 10 11 12 |
bot.on(message('text'), async (ctx) => { if (ctx.from.username !== "luiztools") return; console.log(ctx.message.text); if (ctx.message.text.indexOf("BUY") !== -1 || ctx.message.text.indexOf("LONG") !== -1) ctx.reply("Bora Comprar"); else if (ctx.message.text.indexOf("SELL") !== -1|| ctx.message.text.indexOf("SHORT") !== -1) ctx.reply("Bora Vender"); }); |
Essa é a parte com a maior variação pois cada grupo de sinais envia de um jeito as mensagens. Você vai ter de analisar alguns sinais já enviados no seu grupo para determinar quais os testes são necessários a fim de tomar a decisão de entrar ou sair das posições.
#4 – Enviando as Ordens
Eu já ensinei em outros tutoriais aqui do blog sobre como fazer compra/venda com robô nos mercados Spot e Futures. Você pode juntar tudo o que aprendeu nos referidos tutoriais neste bot aqui. Abaixo vou mostrar um exemplo simples de como você pode enviar ordens LIMIT no mercado Binance Futures toda vez que receber um sinal para isso. Usarei ordens LIMIT em Futures como exemplo porque a maior parte dos grupos de sinais que conheço são para esse mercado e os sinais são para preços futuros do ativo e não para compra/venda imediata (MARKET).
Para isso, vamos criar um novo arquivo chamado api.js e nele vamos criar a função que envia as ordens para a Binance Futures.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
const axios = require('axios'); const crypto = require('crypto'); const apiKey = process.env.API_KEY; const apiSecret = process.env.SECRET_KEY; const apiUrl = process.env.API_URL; async function newOrder(symbol, quantity, side, price) { const data = { symbol, side, type: "LIMIT", quantity, price, timeInForce: "GTC" }; const timestamp = Date.now(); const recvWindow = 60000;//máximo permitido, default 5000 const signature = crypto .createHmac('sha256', apiSecret) .update(`${new URLSearchParams({ ...data, timestamp, recvWindow }).toString()}`) .digest('hex'); const newData = { ...data, timestamp, recvWindow, signature }; const qs = `?${new URLSearchParams(newData).toString()}`; const result = await axios({ method: 'POST', url: `${apiUrl}/v1/order${qs}`, headers: { 'X-MBX-APIKEY': apiKey } }); return result.data; } module.exports = { newOrder } |
Repare que para este módulo funcionar (ele é melhor explicado no tutorial de Bot Binance Futures) é necessário que você adicione mais algumas variáveis de ambiente no seu .env, a saber.
1 2 3 4 5 |
API_KEY=<sua API Key> SECRET_KEY=<sua API Secret> API_URL=<https://testnet.binancefuture.com/fapi ou https://fapi.binance.com/fapi> |
Repare que a API URL a ser escolhida deve ser condizente se seu robô irá operar em modo de teste (Testnet) ou produção e esta configuração deve ser condizente com as chaves que estiver usando (chaves de prod com URL de prod e chaves de teste com URL de teste). Caso não possua chaves de API da Binance Futures, eu ensino como obter as suas no vídeo abaixo (tanto em produção quanto em desenvolvimento).
Agora modifique o script do seu robô para que ele chame a função de envio de ordem do api.js adequadamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
bot.on(message('text'), async (ctx) => { if (ctx.from.username !== "luiztools") return; console.log(ctx.message.text); const symbol = ctx.message.text.split("#")[1].split(" ")[0].trim(); const quantity = "0.01"; const price = ctx.message.text.split("Target 1: ")[1].split("\n")[0].trim(); let result; if (ctx.message.text.indexOf("BUY") !== -1 || ctx.message.text.indexOf("LONG") !== -1) { ctx.reply("Bora Comprar"); result = await newOrder(symbol, quantity, "BUY", price); } else if (ctx.message.text.indexOf("SELL") !== -1 || ctx.message.text.indexOf("SHORT") !== -1) { ctx.reply("Bora Vender"); result = await newOrder(symbol, quantity, "SELL", price); } console.log(result); }); |
Acima eu deixei alguns exemplos de como você pode pegar as informações necessárias ao envio da ordem usando splits dentro da string do sinal. Abaixo o sinal que usei como exemplo para montar esta lógica, para você entender melhor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
📩 #ADAUSDT ADA5 M 📉 Long Entry Zone: 0.3778-0.3704 BINANCE ADAUSDT.P - ⏳ - Signal details: Target 1: 0.379689 Target 2: 0.381578 Target 3: 0.383467 Target 4: 0.389134 🧲Trend-Line: 0.3704 ❌Stop-Loss: 0.368548 💡Leverage: 10x cross |
Repare como tem muitas outras informações úteis nesse sinal que você pode estar utilizando no seu bot, mas a base é exatamente a que montei acima.
Um abraço e até a próxima!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.