」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 完整指南:在 Telegram 和 MetaTraderm Python 之間建立安全整合機器人

完整指南:在 Telegram 和 MetaTraderm Python 之間建立安全整合機器人

發佈於2024-11-08
瀏覽:228

Guia Completo: Construindo um Bot Seguro de Integração entre Telegram e MetaTraderm Python

Bem-vindo! Este guia é projetado desenvolvedores intusiastas em Python que desejam criar um bot que monitora mensagens no Telegram e interage com o MetaTrader5 (MT5) para executar ordens de negociação com base nos sinais recebidos. Vamos guiá-lo por todo o processo, desde a configuração do ambiente até a compreensão detalhada de cada parte do código.


Índice

  1. Introdução
  2. Pré-requisitos
  3. Configurando o Ambiente
    • 1. Criar um Diretório para o Projeto
    • 2. Configurar um Ambiente Virtual (Opcional, mas Recomendado)
    • 3. Instalar Dependências Necessárias
  4. Criando o Arquivo .env
  5. Entendendo o Script Python
    • Imports e Variáveis de Ambiente
    • Configuração de Logging
    • Configuração das Contas MT5
    • Função de Reconexão com MT5
    • Função para Enviar Ordens para MT5
    • Processando Sinais do Telegram
    • Monitoramento de Conexões
    • Manipulação de Sinais para Encerramento Suave
    • Função Principal (main)
  6. Executando o Script
  7. Boas Práticas e Dicas
  8. Conclusão

Introdução

Neste projeto, você criará um bot em Python que realiza as seguintes tarefas:

  1. Monitora um Grupo no Telegram: O bot monitora mensagens em um grupo específico do Telegram em busca de sinais de negociação (por exemplo, "buy US30").

  2. Processa Sinais: Quando um sinal é detectado, o bot interpreta para determinar qual ativo negociar e se deve comprar ou vender.

  3. Interage com o MetaTrader5 (MT5): Com base no sinal, o bot envia ordens de negociação para sua conta MT5.

  4. Mantém Práticas de Segurança: Informações sensíveis, como chaves de API e senhas, são gerenciadas de forma segura usando variáveis de ambiente.

Ao final deste guia, você terá um bot funcional e seguro que automatiza ações de negociação com base em mensagens do Telegram.


Pré-requisitos

Antes de começar, certifique-se de ter o seguinte:

  1. Conhecimento Básico de Python: Familiaridade com a sintaxe do Python e conceitos como funções, loops e módulos.

  2. Python Instalado: Verifique se você tem o Python 3.7 ou posterior instalado em seu computador. Você pode baixá-lo do site oficial do Python.

  3. Conta no Telegram: Você precisará acessar a API do Telegram. Registre sua aplicação aqui para obter o API_ID e o API_HASH.

  4. Conta no MetaTrader5: Acesse uma conta MT5, incluindo credenciais de login e informações do servidor.

  5. Entendimento de Ambientes Virtuais: Embora opcional, usar ambientes virtuais é recomendado para gerenciar dependências.


Configurando o Ambiente

1. Criar um Diretório para o Projeto

Escolha um local em seu computador e crie um novo diretório para o seu projeto. Por exemplo:

mkdir telegram_mt5_bot
cd telegram_mt5_bot

2. Configurar um Ambiente Virtual (Opcional, mas Recomendado)

Um ambiente virtual isola as dependências do seu projeto das de outros projetos Python em seu sistema.

  • Criar um Ambiente Virtual:

    python -m venv venv
    

    Este comando cria um ambiente virtual chamado venv dentro do diretório do seu projeto.

  • Ativar o Ambiente Virtual:

    • No Windows:

      venv\Scripts\activate
      
    • No macOS e Linux:

      source venv/bin/activate
      

    Após a ativação, o nome do ambiente virtual aparecerá no prompt do terminal, indicando que as dependências instaladas agora serão isoladas para este projeto.

3. Instalar Dependências Necessárias

Com o ambiente virtual ativado, instale as bibliotecas necessárias usando o pip:

pip install telethon MetaTrader5 python-dotenv
  • telethon: Biblioteca para interagir com a API do Telegram.
  • MetaTrader5: Biblioteca para interagir com o MetaTrader5.
  • python-dotenv: Biblioteca para carregar variáveis de ambiente a partir de um arquivo .env.

Além disso, para facilitar o gerenciamento de pacotes, é recomendável criar um arquivo requirements.txt:

pip freeze > requirements.txt

Este arquivo registra todas as dependências do projeto, permitindo que outras pessoas (ou você mesmo em outra máquina) instalem facilmente as mesmas versões com:

pip install -r requirements.txt

Criando o Arquivo .env

Para gerenciar informações sensíveis de forma segura, usaremos um arquivo .env que armazenará variáveis de ambiente. Este arquivo não deve ser versionado ou compartilhado.

1. Criar o Arquivo .env

No diretório raiz do seu projeto (telegram_mt5_bot), crie um arquivo chamado .env e adicione as seguintes linhas, substituindo os valores pelos seus próprios:

# Credenciais do Telegram
TELEGRAM_API_ID=seu_api_id
TELEGRAM_API_HASH=seu_api_hash
TELEGRAM_PHONE_NUMBER=seu_numero_de_telefone
TELEGRAM_GROUP_USERNAME=@superus30

# Credenciais do MetaTrader5 (MT5)
MT5_LOGIN=seu_login_mt5
MT5_PASSWORD=sua_senha_mt5
MT5_SERVER=seu_servidor_mt5
MT5_PATH=C:\Caminho\Para\Seu\MetaTrader5\terminal64.exe

# Configuração de Logging
LOG_FILE=app.log

Notas Importantes:

  • TELEGRAM_API_ID e TELEGRAM_API_HASH: Obtidos ao registrar sua aplicação no Telegram.
  • TELEGRAM_PHONE_NUMBER: Número de telefone associado à sua conta do Telegram.
  • TELEGRAM_GROUP_USERNAME: Nome de usuário do grupo Telegram que o bot irá monitorar.
  • MT5_LOGIN, MT5_PASSWORD, MT5_SERVER: Informações da sua conta MT5.
  • MT5_PATH: Caminho para o executável do MetaTrader5 no seu sistema.

2. Atualizar o Arquivo .gitignore

Para garantir que o arquivo .env não seja versionado (especialmente se você estiver usando o Git), crie ou atualize o arquivo .gitignore no diretório raiz com o seguinte conteúdo:

# Arquivo de variáveis de ambiente
.env

# Diretório do ambiente virtual
venv/

Isso impede que informações sensíveis sejam acidentalmente compartilhadas em repositórios públicos ou privados.


Entendendo o Script Python

Agora, vamos criar o script Python que integrará o Telegram com o MetaTrader5. Este script realizará as seguintes funções:

  1. Carregar Variáveis de Ambiente: Utiliza o python-dotenv para carregar credenciais e configurações do arquivo .env.

  2. Configurar Logging: Define como e onde os logs serão armazenados, facilitando o monitoramento e a depuração.

  3. Configurar Contas MT5: Define as contas MT5 que serão utilizadas pelo bot.

  4. Funções de Reconexão e Envio de Ordens: Gerencia a conexão com o MT5 e envia ordens de negociação com base nos sinais recebidos.

  5. Processar Sinais do Telegram: Interpreta mensagens do Telegram para determinar as ações de negociação.

  6. Monitorar Conexões: Verifica periodicamente se as conexões com o MT5 estão ativas e tenta reconectar se necessário.

  7. Manipular Sinais de Encerramento: Garante que o bot encerre suas operações de forma suave ao receber sinais de interrupção.

  8. Função Principal (main): Orquestra todas as operações acima, iniciando o cliente Telegram e gerenciando as tarefas assíncronas.

Vamos explorar cada parte do código com detalhes.

1. Imports e Variáveis de Ambiente

Primeiro, importamos todas as bibliotecas necessárias e carregamos as variáveis de ambiente.

import os
import sys
import asyncio
import logging
import signal
import pkg_resources
from datetime import datetime
from dotenv import load_dotenv
from telethon import TelegramClient, events
import MetaTrader5 as mt5

Explicação dos Imports:

  • os: Interage com o sistema operacional, acessando variáveis de ambiente e caminhos de arquivos.
  • sys: Fornece acesso a variáveis e funções que interagem com o interpretador Python.
  • asyncio: Facilita a escrita de código assíncrono, permitindo que múltiplas tarefas sejam executadas concorrentemente.
  • logging: Gerencia o registro de mensagens de log para monitoramento e depuração.
  • signal: Permite a captura de sinais do sistema (como interrupções) para realizar ações específicas.
  • pkg_resources: Gerencia recursos de pacotes Python, aqui utilizado para listar pacotes instalados.
  • datetime: Trabalha com datas e horas.
  • dotenv: Carrega variáveis de ambiente de um arquivo .env.
  • Telethon: Biblioteca para interagir com a API do Telegram de forma assíncrona.
  • MetaTrader5: Biblioteca para interagir com o MetaTrader5.

Carregando Variáveis de Ambiente:

# Carrega variáveis de ambiente do arquivo .env
load_dotenv()

Esta linha lê o arquivo .env e carrega as variáveis de ambiente nele definidas, permitindo que sejam acessadas via os.getenv().

2. Configuração de Logging

O logging é essencial para monitorar o funcionamento do seu bot e depurar problemas. Vamos configurar o logging para registrar mensagens tanto no console quanto em um arquivo.

# Acessa as variáveis de ambiente para configuração
LOG_FILE = os.getenv('LOG_FILE', 'app.log')

# Configura o logging
logging.basicConfig(
    level=logging.INFO,  # Nível mínimo de severidade para registrar
    format='%(asctime)s - %(levelname)s - %(message)s',  # Formato das mensagens de log
    handlers=[
        logging.FileHandler(LOG_FILE),  # Registra logs em um arquivo
        logging.StreamHandler(sys.stdout)  # Exibe logs no console
    ]
)
logger = logging.getLogger(__name__)

Detalhes da Configuração:

  • level: Define o nível mínimo de mensagens que serão registradas. INFO inclui INFO, WARNING, ERROR e CRITICAL.
  • format: Define como cada mensagem de log será formatada, incluindo o timestamp, o nível de severidade e a mensagem.
  • handlers: Define onde as mensagens de log serão enviadas. Aqui, estão sendo enviadas para um arquivo (app.log) e para o console.

3. Configuração das Contas MT5

Definimos as contas MT5 que o bot utilizará para enviar ordens de negociação.

# Configurações das contas MT5
CONTAS_MT5 = [
    {
        "login": os.getenv('MT5_LOGIN'),
        "senha": os.getenv('MT5_PASSWORD'),
        "servidor": os.getenv('MT5_SERVER'),
        "us30": "US30.cash",
        "nas100": "US100.cash",
        "lote": 0.01
    }
]

contas_ativas = []  # Lista para armazenar contas ativas
shutdown_event = asyncio.Event()  # Evento para sinalizar o encerramento do programa

Explicação dos Campos:

  • login: Número de login da conta MT5.
  • senha: Senha da conta MT5.
  • servidor: Nome do servidor MT5.
  • us30 e nas100: Símbolos dos ativos que serão negociados.
  • lote: Volume padrão das ordens a serem enviadas.

4. Função de Reconexão com MT5

Esta função tenta reconectar à conta MT5 caso a conexão seja perdida.

async def reconectar_mt5(conta, max_tentativas=3):
    """
    Tenta reconectar à conta MT5 com um número máximo de tentativas.

    Args:
        conta (dict): Informações da conta MT5.
        max_tentativas (int): Número máximo de tentativas de reconexão.

    Returns:
        bool: True se a reconexão for bem-sucedida, False caso contrário.
    """
    for tentativa in range(max_tentativas):
        try:
            # Tenta inicializar a conexão com MT5
            if mt5.initialize(path=os.getenv('MT5_PATH'), login=int(conta['login']), server=conta['servidor'], password=conta['senha']):
                logger.info(f"Reconexão bem-sucedida para conta {conta['login']}")
                return True
            else:
                erro = mt5.last_error()
                logger.warning(f"Tentativa {tentativa   1} de reconexão falhou para conta {conta['login']}: {erro}")
        except Exception as e:
            logger.error(f"Erro durante a tentativa {tentativa   1} de reconexão para conta {conta['login']}: {e}")
        await asyncio.sleep(5)  # Espera 5 segundos antes de tentar novamente
    logger.error(f"Falha ao reconectar à conta {conta['login']} após {max_tentativas} tentativas")
    return False

Detalhes da Função:

  • Objetivo: Garantir que o bot mantenha a conexão com o MT5, tentando reconectar em caso de falha.
  • Parâmetros:
    • conta: Dicionário contendo as informações da conta MT5.
    • max_tentativas: Número máximo de tentativas de reconexão antes de desistir.
  • Processo:
    • Tenta inicializar a conexão com MT5 usando as credenciais fornecidas.
    • Se falhar, registra um aviso e aguarda 5 segundos antes de tentar novamente.
    • Após exceder o número máximo de tentativas, registra um erro e retorna False.

5. Função para Enviar Ordens para MT5

Esta função envia ordens de negociação para o MT5 com base nos sinais processados.

async def enviar_ordem(conta, simbolo, acao, lote):
    """
    Envia uma ordem de negociação para o MT5.

    Args:
        conta (dict): Informações da conta MT5.
        simbolo (str): Símbolo do ativo a ser negociado.
        acao (int): Tipo de ação (compra ou venda).
        lote (float): Volume da ordem.

    Returns:
        bool: True se a ordem for enviada com sucesso, False caso contrário.
    """
    # Tenta reconectar à conta MT5 antes de enviar a ordem
    if not await reconectar_mt5(conta):
        logger.error(f"Não foi possível enviar ordem para {conta['login']} devido a falha na reconexão")
        return False

    # Obtém informações do símbolo
    symbol_info = mt5.symbol_info(simbolo)
    if symbol_info is None:
        logger.error(f"Símbolo {simbolo} não encontrado")
        return False

    # Verifica se o símbolo está disponível para trading
    if not symbol_info.visible:
        logger.warning(f"Símbolo {simbolo} não está visível, tentando habilitá-lo")
        if not mt5.symbol_select(simbolo, True):
            logger.error(f"Falha ao selecionar o símbolo {simbolo}")
            return False

    # Obtém o tick atual do símbolo
    tick = mt5.symbol_info_tick(simbolo)
    if tick is None:
        logger.error(f"Não foi possível obter o tick para o símbolo {simbolo}")
        return False

    # Define o preço baseado na ação (compra ou venda)
    price = tick.ask if acao == mt5.ORDER_TYPE_BUY else tick.bid

    # Prepara a estrutura do pedido
    pedido = {
        "action": mt5.TRADE_ACTION_DEAL,  # Tipo de ação de negociação
        "symbol": simbolo,                # Símbolo do ativo
        "volume": float(lote),            # Volume da ordem
        "type": acao,                     # Tipo de ordem (compra ou venda)
        "price": price,                   # Preço da ordem
        "deviation": 20,                  # Desvio permitido no preço
        "magic": 234000,                   # Identificador único para a ordem
        "comment": "python script order",  # Comentário para a ordem
        "type_time": mt5.ORDER_TIME_GTC,   # Tipo de tempo da ordem (Good Till Cancelled)
        "type_filling": mt5.ORDER_FILLING_IOC,  # Tipo de preenchimento (Immediate or Cancel)
    }

    # Envia a ordem para o MT5
    resultado = mt5.order_send(pedido)
    if resultado.retcode != mt5.TRADE_RETCODE_DONE:
        logger.error(f"Erro ao enviar ordem para {conta['login']}: {resultado.comment}")
        logger.debug(f"Detalhes do pedido: {pedido}")
        logger.debug(f"Código de retorno: {resultado.retcode}")
        return False
    else:
        logger.info(f"Ordem enviada com sucesso para {conta['login']} com lote {lote}")
        logger.debug(f"Detalhes da ordem: {resultado}")
        return True

Detalhes da Função:

  • Objetivo: Enviar uma ordem de compra ou venda para o MT5 com base nos sinais recebidos.
  • Parâmetros:
    • conta: Informações da conta MT5.
    • simbolo: Símbolo do ativo a ser negociado (por exemplo, "US30.cash").
    • acao: Tipo de ação (mt5.ORDER_TYPE_BUY para compra ou mt5.ORDER_TYPE_SELL para venda).
    • lote: Volume da ordem (por exemplo, 0.01).
  • Processo:
    • Reconecta à conta MT5 se necessário.
    • Verifica se o símbolo está disponível e visível para negociação.
    • Obtém o preço atual do símbolo (ask para compra, bid para venda).
    • Prepara a estrutura do pedido com todos os parâmetros necessários.
    • Envia a ordem para o MT5 e verifica se foi bem-sucedida.

6. Processando Sinais do Telegram

Esta função interpreta mensagens recebidas no Telegram para determinar quais ações de negociação devem ser executadas.

async def processar_sinal(mensagem):
    """
    Processa uma mensagem recebida do Telegram para determinar a ação de negociação.

    Args:
        mensagem (str): Texto da mensagem recebida.

    """
    logger.info(f"Mensagem recebida do Telegram: {mensagem}")

    palavras = mensagem.lower().split()

    ativo = None
    acao = None

    # Verifica o ativo na mensagem
    if 'us30' in palavras:
        ativo = 'us30'
    elif 'nas100' in palavras:
        ativo = 'nas100'

    # Verifica a ação na mensagem
    if 'buy' in palavras:
        acao = mt5.ORDER_TYPE_BUY
    elif 'sell' in palavras:
        acao = mt5.ORDER_TYPE_SELL

    # Se nenhum ativo for reconhecido, encerra a função
    if not ativo:
        logger.info("Nenhum ativo reconhecido na mensagem.")
        return

    # Se nenhuma ação for reconhecida, encerra a função
    if acao is None:
        logger.info("Nenhuma ação (compra/venda) reconhecida na mensagem.")
        return

    acao_str = "COMPRA" se acao == mt5.ORDER_TYPE_BUY else "VENDA"
    logger.info(f"Interpretação: Ativo: {ativo.upper()}, Ação: {acao_str}")

    # Itera sobre todas as contas ativas para enviar a ordem
    for conta in contas_ativas[:]:  # Cria uma cópia da lista para iteração segura
        try:
            simbolo = conta.get(ativo)
            if not simbolo:
                logger.warning(f"Ativo {ativo} não configurado para a conta {conta['login']}. Pulando.")
                continue
            sucesso = await enviar_ordem(conta, simbolo, acao, conta['lote'])
            if not sucesso:
                logger.warning(f"Falha ao processar sinal para conta {conta['login']}. Removendo da lista de contas ativas.")
                contas_ativas.remove(conta)
        except Exception as e:
            logger.error(f"Erro ao processar sinal para conta {conta['login']}: {e}")
            logger.warning(f"Removendo conta {conta['login']} da lista de contas ativas devido a erro")
            contas_ativas.remove(conta)

Detalhes da Função:

  • Objetivo: Interpretar a mensagem recebida do Telegram para determinar qual ativo negociar e se deve comprar ou vender.
  • Parâmetros:
    • mensagem: Texto da mensagem recebida no Telegram.
  • Processo:
    • Converte a mensagem para letras minúsculas e divide em palavras.
    • Identifica o ativo mencionado (us30 ou nas100).
    • Identifica a ação (buy para compra ou sell para venda).
    • Itera sobre todas as contas ativas e envia a ordem correspondente.
    • Se a ordem falhar, remove a conta da lista de contas ativas para evitar tentativas futuras.

7. Monitoramento de Conexões

Esta função verifica periodicamente se as conexões com as contas MT5 estão ativas e tenta reconectar se necessário.

async def verificar_conexoes():
    """
    Verifica periodicamente se as contas MT5 estão conectadas e tenta reconectar se necessário.
    """
    while not shutdown_event.is_set():
        for conta in contas_ativas[:]:
            if shutdown_event.is_set():
                break
            if not await reconectar_mt5(conta):
                logger.warning(f"Conta {conta['login']} removida da lista de contas ativas devido a falha na conexão")
                contas_ativas.remove(conta)
        await asyncio.sleep(60)  # Verifica a cada 60 segundos

Detalhes da Função:

  • Objetivo: Garantir que todas as contas MT5 ativas mantenham uma conexão estável.
  • Processo:
    • Enquanto o evento de encerramento não for sinalizado, itera sobre todas as contas ativas.
    • Para cada conta, tenta reconectar.
    • Se a reconexão falhar após as tentativas definidas, remove a conta da lista de contas ativas.
    • Aguarda 60 segundos antes da próxima verificação.

8. Manipulação de Sinais para Encerramento Suave

Esta função lida com sinais de interrupção (como Ctrl C) para encerrar o programa de forma limpa.

def signal_handler(signum, frame):
    """
    Manipula sinais de interrupção para encerrar o programa de forma suave.

    Args:
        signum: Número do sinal.
        frame: Frame atual.
    """
    logger.info("Sinal de interrupção recebido. Encerrando o programa...")
    asyncio.get_event_loop().call_soon_threadsafe(shutdown_event.set)

Detalhes da Função:

  • Objetivo: Capturar sinais de interrupção e iniciar o processo de encerramento do bot de forma ordenada.
  • Processo:
    • Quando um sinal de interrupção é recebido (como SIGINT ou SIGTERM), registra uma mensagem de log.
    • Sinaliza o evento de encerramento para que todas as tarefas assíncronas possam finalizar adequadamente.

9. Função Principal (main)

Esta é a função central que coordena todas as operações do bot.

async def main():
    """
    Função principal que inicializa o bot e gerencia suas operações.
    """
    # Configurar o manipulador de sinais
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    # Inicializar contas MT5
    for conta in CONTAS_MT5:
        if await reconectar_mt5(conta):
            contas_ativas.append(conta)

    if not contas_ativas:
        logger.error("Nenhuma conta pôde ser inicializada. Encerrando o programa.")
        return

    logger.info(f"Programa continuando com {len(contas_ativas)} conta(s) ativa(s)")

    # Inicializar o cliente Telegram
    client = TelegramClient('session', os.getenv('TELEGRAM_API_ID'), os.getenv('TELEGRAM_API_HASH'))

    @client.on(events.NewMessage(chats=os.getenv('TELEGRAM_GROUP_USERNAME')))
    async def handler(event):
        """
        Manipulador de eventos para novas mensagens no Telegram.
        """
        if not shutdown_event.is_set():
            try:
                logger.info(f"Nova mensagem recebida do grupo {os.getenv('TELEGRAM_GROUP_USERNAME')}")
                await processar_sinal(event.message.text)
            except Exception as e:
                logger.error(f"Erro ao processar mensagem do Telegram: {e}")

    # Iniciar a tarefa de verificação de conexões
    verificar_task = asyncio.create_task(verificar_conexoes())

    try:
        await client.start(phone=os.getenv('TELEGRAM_PHONE_NUMBER'))
        logger.info("Bot Telegram iniciado. Aguardando mensagens...")
        await shutdown_event.wait()  # Aguarda até que o evento de encerramento seja sinalizado
    except Exception as e:
        logger.error(f"Erro no cliente Telegram: {e}")
    finally:
        await client.disconnect()
        verificar_task.cancel()
        for conta in contas_ativas:
            if mt5.shutdown():
                logger.info(f"MT5 desligado para a conta {conta['login']}")
            else:
                logger.warning(f"Falha ao desligar MT5 para a conta {conta['login']}")
        logger.info("Programa encerrado.")

Detalhes da Função:

  • Configuração de Sinais:

    • Associa os sinais de interrupção (SIGINT e SIGTERM) à função signal_handler para garantir um encerramento suave.
  • Inicialização das Contas MT5:

    • Itera sobre todas as contas definidas em CONTAS_MT5.
    • Tenta reconectar a cada conta e adiciona à lista de contas_ativas se bem-sucedido.
    • Se nenhuma conta puder ser inicializada, registra um erro e encerra o programa.
  • Inicialização do Cliente Telegram:

    • Cria uma instância do TelegramClient usando as credenciais do Telegram.
    • Define um manipulador de eventos (handler) que será chamado sempre que uma nova mensagem for recebida no grupo especificado.
    • O manipulador chama a função processar_sinal para interpretar e agir sobre a mensagem.
  • Iniciar Tarefas Assíncronas:

    • Cria uma tarefa assíncrona para verificar periodicamente as conexões MT5 (verificar_conexoes).
    • Inicia o cliente Telegram e aguarda até que o evento de encerramento seja sinalizado.
  • Encerramento:

    • Ao receber um sinal de encerramento, desconecta o cliente Telegram.
    • Cancela a tarefa de verificação de conexões.
    • Desliga o MT5 para todas as contas ativas.
    • Registra que o programa foi encerrado.

10. Executando o Script

Para executar o script, crie um arquivo chamado bot.py no diretório do seu projeto e cole o seguinte código completo, que integra todas as partes que discutimos:

import os
import sys
import asyncio
import logging
import signal
import pkg_resources
from datetime import datetime
from dotenv import load_dotenv
from telethon import TelegramClient, events
import MetaTrader5 as mt5

# Carrega variáveis de ambiente do arquivo .env
load_dotenv()

# Acessa as variáveis de ambiente para configuração
API_ID = os.getenv('TELEGRAM_API_ID')
API_HASH = os.getenv('TELEGRAM_API_HASH')
PHONE_NUMBER = os.getenv('TELEGRAM_PHONE_NUMBER')
GROUP_USERNAME = os.getenv('TELEGRAM_GROUP_USERNAME')

MT5_LOGIN = os.getenv('MT5_LOGIN')
MT5_PASSWORD = os.getenv('MT5_PASSWORD')
MT5_SERVER = os.getenv('MT5_SERVER')
MT5_PATH = os.getenv('MT5_PATH')

LOG_FILE = os.getenv('LOG_FILE', 'app.log')

# Configura logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(LOG_FILE),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

# Configurações das contas MT5
CONTAS_MT5 = [
    {
        "login": MT5_LOGIN,
        "senha": MT5_PASSWORD,
        "servidor": MT5_SERVER,
        "us30": "US30.cash",
        "nas100": "US100.cash",
        "lote": 0.01
    }
]

contas_ativas = []
shutdown_event = asyncio.Event()

async def reconectar_mt5(conta, max_tentativas=3):
    """
    Tenta reconectar à conta MT5 com um número máximo de tentativas.

    Args:
        conta (dict): Informações da conta MT5.
        max_tentativas (int): Número máximo de tentativas de reconexão.

    Returns:
        bool: True se a reconexão for bem-sucedida, False caso contrário.
    """
    for tentativa in range(max_tentativas):
        try:
            # Tenta inicializar a conexão com MT5
            if mt5.initialize(path=MT5_PATH, login=int(conta['login']), server=conta['servidor'], password=conta['senha']):
                logger.info(f"Reconexão bem-sucedida para conta {conta['login']}")
                return True
            else:
                erro = mt5.last_error()
                logger.warning(f"Tentativa {tentativa   1} de reconexão falhou para conta {conta['login']}: {erro}")
        except Exception as e:
            logger.error(f"Erro durante a tentativa {tentativa   1} de reconexão para conta {conta['login']}: {e}")
        await asyncio.sleep(5)  # Espera 5 segundos antes de tentar novamente
    logger.error(f"Falha ao reconectar à conta {conta['login']} após {max_tentativas} tentativas")
    return False

async def enviar_ordem(conta, simbolo, acao, lote):
    """
    Envia uma ordem de negociação para o MT5.

    Args:
        conta (dict): Informações da conta MT5.
        simbolo (str): Símbolo do ativo a ser negociado.
        acao (int): Tipo de ação (compra ou venda).
        lote (float): Volume da ordem.

    Returns:
        bool: True se a ordem for enviada com sucesso, False caso contrário.
    """
    # Tenta reconectar à conta MT5 antes de enviar a ordem
    if not await reconectar_mt5(conta):
        logger.error(f"Não foi possível enviar ordem para {conta['login']} devido a falha na reconexão")
        return False

    # Obtém informações do símbolo
    symbol_info = mt5.symbol_info(simbolo)
    if symbol_info is None:
        logger.error(f"Símbolo {simbolo} não encontrado")
        return False

    # Verifica se o símbolo está disponível para trading
    if not symbol_info.visible:
        logger.warning(f"Símbolo {simbolo} não está visível, tentando habilitá-lo")
        if not mt5.symbol_select(simbolo, True):
            logger.error(f"Falha ao selecionar o símbolo {simbolo}")
            return False

    # Obtém o tick atual do símbolo
    tick = mt5.symbol_info_tick(simbolo)
    if tick is None:
        logger.error(f"Não foi possível obter o tick para o símbolo {simbolo}")
        return False

    # Define o preço baseado na ação (compra ou venda)
    price = tick.ask if acao == mt5.ORDER_TYPE_BUY else tick.bid

    # Prepara a estrutura do pedido
    pedido = {
        "action": mt5.TRADE_ACTION_DEAL,  # Tipo de ação de negociação
        "symbol": simbolo,                # Símbolo do ativo
        "volume": float(lote),            # Volume da ordem
        "type": acao,                     # Tipo de ordem (compra ou venda)
        "price": price,                   # Preço da ordem
        "deviation": 20,                  # Desvio permitido no preço
        "magic": 234000,                   # Identificador único para a ordem
        "comment": "python script order",  # Comentário para a ordem
        "type_time": mt5.ORDER_TIME_GTC,   # Tipo de tempo da ordem (Good Till Cancelled)
        "type_filling": mt5.ORDER_FILLING_IOC,  # Tipo de preenchimento (Immediate or Cancel)
    }

    # Envia a ordem para o MT5
    resultado = mt5.order_send(pedido)
    if resultado.retcode != mt5.TRADE_RETCODE_DONE:
        logger.error(f"Erro ao enviar ordem para {conta['login']}: {resultado.comment}")
        logger.debug(f"Detalhes do pedido: {pedido}")
        logger.debug(f"Código de retorno: {resultado.retcode}")
        return False
    else:
        logger.info(f"Ordem enviada com sucesso para {conta['login']} com lote {lote}")
        logger.debug(f"Detalhes da ordem: {resultado}")
        return True

async def processar_sinal(mensagem):
    """
    Processa uma mensagem recebida do Telegram para determinar a ação de negociação.

    Args:
        mensagem (str): Texto da mensagem recebida.
    """
    logger.info(f"Mensagem recebida do Telegram: {mensagem}")

    palavras = mensagem.lower().split()

    ativo = None
    acao = None

    # Verifica o ativo na mensagem
    if 'us30' in palavras:
        ativo = 'us30'
    elif 'nas100' in palavras:
        ativo = 'nas100'

    # Verifica a ação na mensagem
    if 'buy' in palavras:
        acao = mt5.ORDER_TYPE_BUY
    elif 'sell' in palavras:
        acao = mt5.ORDER_TYPE_SELL

    # Se nenhum ativo for reconhecido, encerra a função
    if not ativo:
        logger.info("Nenhum ativo reconhecido na mensagem.")
        return

    # Se nenhuma ação for reconhecida, encerra a função
    if acao is None:
        logger.info("Nenhuma ação (compra/venda) reconhecida na mensagem.")
        return

    acao_str = "COMPRA" se acao == mt5.ORDER_TYPE_BUY else "VENDA"
    logger.info(f"Interpretação: Ativo: {ativo.upper()}, Ação: {acao_str}")

    # Itera sobre todas as contas ativas para enviar a ordem
    for conta in contas_ativas[:]:  # Cria uma cópia da lista para iteração segura
        try:
            simbolo = conta.get(ativo)
            if not simbolo:
                logger.warning(f"Ativo {ativo} não configurado para a conta {conta['login']}. Pulando.")
                continue
            sucesso = await enviar_ordem(conta, simbolo, acao, conta['lote'])
            if not sucesso:
                logger.warning(f"Falha ao processar sinal para conta {conta['login']}. Removendo da lista de contas ativas.")
                contas_ativas.remove(conta)
        except Exception as e:
            logger.error(f"Erro ao processar sinal para conta {conta['login']}: {e}")
            logger.warning(f"Removendo conta {conta['login']} da lista de contas ativas devido a erro")
            contas_ativas.remove(conta)

async def verificar_conexoes():
    """
    Verifica periodicamente se as contas MT5 estão conectadas e tenta reconectar se necessário.
    """
    while not shutdown_event.is_set():
        for conta in contas_ativas[:]:
            if shutdown_event.is_set():
                break
            if not await reconectar_mt5(conta):
                logger.warning(f"Conta {conta['login']} removida da lista de contas ativas devido a falha na conexão")
                contas_ativas.remove(conta)
        await asyncio.sleep(60)  # Verifica a cada 60 segundos

def signal_handler(signum, frame):
    """
    Manipula sinais de interrupção para encerrar o programa de forma suave.

    Args:
        signum: Número do sinal.
        frame: Frame atual.
    """
    logger.info("Sinal de interrupção recebido. Encerrando o programa...")
    asyncio.get_event_loop().call_soon_threadsafe(shutdown_event.set)

async def main():
    """
    Função principal que inicializa o bot e gerencia suas operações.
    """
    # Configurar o manipulador de sinais
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    # Inicializar contas MT5
    for conta in CONTAS_MT5:
        if await reconectar_mt5(conta):
            contas_ativas.append(conta)

    if not contas_ativas:
        logger.error("Nenhuma conta pôde ser inicializada. Encerrando o programa.")
        return

    logger.info(f"Programa continuando com {len(contas_ativas)} conta(s) ativa(s)")

    # Inicializar o cliente Telegram
    client = TelegramClient('session', API_ID, API_HASH)

    @client.on(events.NewMessage(chats=GROUP_USERNAME))
    async def handler(event):
        """
        Manipulador de eventos para novas mensagens no Telegram.
        """
        if not shutdown_event.is_set():
            try:
                logger.info(f"Nova mensagem recebida do grupo {GROUP_USERNAME}")
                await processar_sinal(event.message.text)
            except Exception as e:
                logger.error(f"Erro ao processar mensagem do Telegram: {e}")

    # Iniciar a tarefa de verificação de conexões
    verificar_task = asyncio.create_task(verificar_conexoes())

    try:
        await client.start(phone=PHONE_NUMBER)
        logger.info("Bot Telegram iniciado. Aguardando mensagens...")
        await shutdown_event.wait()  # Aguarda até que o evento de encerramento seja sinalizado
    except Exception as e:
        logger.error(f"Erro no cliente Telegram: {e}")
    finally:
        await client.disconnect()
        verificar_task.cancel()
        for conta in contas_ativas:
            if mt5.shutdown():
                logger.info(f"MT5 desligado para a conta {conta['login']}")
            else:
                logger.warning(f"Falha ao desligar MT5 para a conta {conta['login']}")
        logger.info("Programa encerrado.")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except Exception as e:
        logger.critical(f"Erro crítico no programa: {e}")
        sys.exit(1)

Explicação Completa do Código:

  1. Carregamento das Variáveis de Ambiente:

    • Usa load_dotenv() para carregar as variáveis definidas no arquivo .env.
    • Acessa essas variáveis usando os.getenv() para configurar o Telegram e MT5.
  2. Configuração de Logging:

    • Configura o logging para registrar mensagens tanto em um arquivo (app.log) quanto no console.
    • Define o nível mínimo de registro como INFO.
  3. Configuração das Contas MT5:

    • Define uma lista CONTAS_MT5 contendo dicionários com as informações necessárias para cada conta MT5.
    • Inicializa uma lista vazia contas_ativas para armazenar contas que estão conectadas.
  4. Função de Reconexão (reconectar_mt5):

    • Tenta reconectar à conta MT5 até um número máximo de tentativas.
    • Registra mensagens de sucesso ou falha no log.
  5. Função para Enviar Ordens (enviar_ordem):

    • Garante que a conexão com MT5 está ativa.
    • Verifica se o símbolo está disponível e visível.
    • Obtém o preço atual do símbolo (ask para compra, bid para venda).
    • Prepara a ordem com os parâmetros necessários e a envia para o MT5.
    • Registra o resultado da ordem no log.
  6. Função para Processar Sinais (processar_sinal):

    • Interpreta a mensagem recebida no Telegram para determinar qual ativo negociar e qual ação (compra ou venda) executar.
    • Itera sobre todas as contas ativas e envia a ordem correspondente.
    • Se uma ordem falhar, remove a conta da lista de contas ativas para evitar tentativas futuras.
  7. Função de Monitoramento de Conexões (verificar_conexoes):

    • Executa em um loop contínuo, verificando a conexão de cada conta MT5 ativa a cada 60 segundos.
    • Tenta reconectar se a conexão estiver perdida e remove contas que não puderam ser reconectadas.
  8. Manipulador de Sinais (signal_handler):

    • Captura sinais de interrupção (como Ctrl C) e sinaliza o encerramento do programa.
    • Garante que todas as tarefas assíncronas sejam finalizadas corretamente.
  9. Função Principal (main):

    • Configura os manipuladores de sinais.
    • Inicializa as contas MT5 e adiciona as contas bem-sucedidas à lista de contas ativas.
    • Inicializa o cliente Telegram e define um manipulador de eventos para novas mensagens.
    • Inicia a tarefa assíncrona de monitoramento de conexões.
    • Aguarda até que um sinal de encerramento seja recebido.
    • Ao encerrar, desconecta o cliente Telegram, cancela a tarefa de monitoramento e desliga o MT5 para todas as contas ativas.
  10. Execução do Script:

    • Verifica se o script está sendo executado diretamente.
    • Executa a função principal usando asyncio.run().
    • Captura quaisquer exceções críticas, registra no log e encerra o programa com um código de erro.

Executando o Script

Após configurar o ambiente e criar o arquivo bot.py, siga os passos abaixo para executar o bot.

1. Ativar o Ambiente Virtual

Se você configurou um ambiente virtual, ative-o:

  • No Windows:

    venv\Scripts\activate
    
  • No macOS e Linux:

    source venv/bin/activate
    

2. Executar o Script

No diretório do seu projeto, execute o seguinte comando:

python bot.py

O que esperar:

  • Logs no Console: Você verá mensagens informando sobre o status da conexão com o MT5 e do cliente Telegram.
  • Arquivo de Log: Todas as mensagens de log também serão gravadas no arquivo app.log (ou outro definido em LOG_FILE).

Interagindo com o Bot:

  • Envie mensagens no grupo do Telegram especificado (@superus30) com comandos como "buy US30" ou "sell NAS100".
  • O bot interpretará esses sinais e enviará ordens de negociação correspondentes para a conta MT5 configurada.

3. Encerrando o Bot

Para encerrar o bot de forma segura, pressione Ctrl C no terminal onde o script está sendo executado. Isso acionará o manipulador de sinais, que garantirá que todas as conexões sejam fechadas corretamente antes de encerrar o programa.


Boas Práticas e Dicas

  1. Manutenção da Segurança:

    • Nunca compartilhe seu arquivo .env ou exponha suas credenciais em repositórios públicos.
    • Use Ambientes Virtuais para isolar as dependências do projeto.
  2. Monitoramento e Logs:

    • Revise regularmente os logs (app.log) para identificar e resolver possíveis problemas.
    • Implementar Rotação de Logs: Para evitar que o arquivo de log cresça indefinidamente, considere implementar rotação usando bibliotecas como logging.handlers.
  3. Testes em Ambiente de Demonstração:

    • Antes de operar em contas reais, teste seu bot em ambientes de demonstração para garantir que tudo funcione conforme o esperado.
    • Verifique as Ordens: Assegure-se de que as ordens estão sendo enviadas corretamente e que o volume está adequado.
  4. Gerenciamento de Erros:

    • Tratamento Robusto de Exceções: Certifique-se de que todas as possíveis exceções sejam tratadas para evitar que o bot pare inesperadamente.
    • Alertas: Considere implementar alertas (por exemplo, enviando mensagens de log críticas para seu email) para notificá-lo sobre falhas graves.
  5. Atualizações de Dependências:

    • Mantenha suas bibliotecas atualizadas para aproveitar melhorias de segurança e correções de bugs.
    • Verifique as Documentações: Consulte as documentações oficiais das bibliotecas para entender mudanças ou atualizações.
  6. Escalabilidade:

    • Gerencie Múltiplas Contas: Se você pretende usar múltiplas contas MT5, expanda a configuração de CONTAS_MT5 conforme necessário.
    • Adicionar Mais Ativos: Atualize o script para suportar mais ativos além de "US30" e "NAS100" conforme sua estratégia de negociação.
  7. Documentação e Comentários:

    • Comente Seu Código: Mantenha comentários atualizados e relevantes para facilitar futuras manutenções.
    • Documente Configurações: Mantenha um documento com detalhes sobre como configurar e executar o bot.

Conclusão

Parabéns! Você criou um bot em Python que integra o Telegram com o MetaTrader5, capaz de automatizar ordens de negociação com base em sinais recebidos no Telegram. Ao seguir este guia, você não apenas implementou a funcionalidade desejada, mas também adotou práticas de segurança e organização de código que são fundamentais para projetos de software robustos.

Próximos Passos:

  • Expandir Funcionalidades: Adicione mais funcionalidades, como diferentes tipos de ordens, gerenciamento de riscos ou integração com outras plataformas.
  • Interface de Usuário: Considere criar uma interface gráfica ou um dashboard para monitorar o desempenho do bot.
  • Automatizar Deployments: Se desejar que o bot funcione continuamente, explore opções de deployment em servidores ou serviços de nuvem.

Recursos Adicionais:

  • Documentação do Telethon: Para aprofundar-se nas funcionalidades da biblioteca Telethon.
  • Documentação do MetaTrader5 Python: Para entender todas as possibilidades de interação com o MT5.
  • Python Logging Best Practices: Para aprimorar suas habilidades de logging.
  • Python Asyncio Documentation: Para dominar a programação assíncrona em Python.
  • Gerenciamento de Segredos em Python: Para aprender mais sobre como gerenciar configurações e segredos de forma segura.

? Fique Seguro e Boas Operações! ?

A segurança das suas credenciais é fundamental para proteger suas contas e dados. Sempre siga as melhores práticas para garantir a integridade e confidencialidade das suas informações.

版本聲明 本文轉載於:https://dev.to/vital7388/guia-completo-construindo-um-bot-seguro-de-integracao-entre-telegram-e-metatrader5-em-python-1lg1?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 當條件涉及字串欄位的非零值時,為什麼 MySQL 查詢會傳回所有行?
    當條件涉及字串欄位的非零值時,為什麼 MySQL 查詢會傳回所有行?
    MySQL查詢傳回所有欄位值非零的行:分析與解決方案當查詢MySQL表時,條件如「 email= 0”,其中電子郵件欄位僅包含非零值,因此無法收到所有傳回的行。此行為可能會損害資料完整性並帶來潛在的安全風險。 要了解發生這種情況的原因,請務必注意 MySQL 在比較過程中以不同方式處理資料類型。當字...
    程式設計 發佈於2024-11-08
  • 在伺服器上使用 Matplotlib 時如何解決「_tkinter.TclError:無顯示名稱且無 $DISPLAY 環境變數」錯誤?
    在伺服器上使用 Matplotlib 時如何解決「_tkinter.TclError:無顯示名稱且無 $DISPLAY 環境變數」錯誤?
    解決「_tkinter.TclError:沒有顯示名稱和沒有$DISPLAY 環境變數」錯誤在伺服器上執行涉及Matplotlib 的Python 腳本時,您可能會遇到到錯誤「_tkinter.TclError:沒有顯示名稱,也沒有$DISPLAY環境變數。然而,伺服器環境通常缺乏此功能。 要解決此...
    程式設計 發佈於2024-11-08
  • Cypress Web 測試深入指南
    Cypress Web 測試深入指南
    在 Web 开发领域,测试是确保 Web 应用程序的可靠性、性能和用户体验的关键步骤。随着应用程序变得越来越复杂,对有效、高效且易于使用的测试工具的需求变得更加明显。这就是现代端到端测试框架 Cypress 的闪光点。在本文中,我们将探讨什么是 Cypress Web 测试、为什么它在其他测试工具...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中實作立即呼叫函數表達式 (IIFE)?
    如何在 PHP 中實作立即呼叫函數表達式 (IIFE)?
    PHP 的立即函數呼叫在PHP 中,立即呼叫函數表達式(IIFE) 在PHP 7 中具有部分等價性,因為您可以在函數執行完後立即呼叫該函數。定義。但是,PHP 5.x 不支援此功能。 對於PHP 7,示例如下:(function() { echo "yes, this works in P...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中將字串編碼和解碼為 Base64?
    如何在 JavaScript 中將字串編碼和解碼為 Base64?
    在JavaScript 中將字串編碼和解碼為Base64處理二進位資料時,通常需要將其編碼為更方便的格式字串表示。 Base64 是一種流行的編碼方案,它將二進位資料表示為一串可列印字元。這使得在 Web 應用程式和其他場景中傳輸和儲存資料變得更加容易。 在 JavaScript 中將字串編碼為 B...
    程式設計 發佈於2024-11-08
  • 為什麼 `Class.getResource()` 在載入「GeoIP.dat」時返回 Null 以及如何修復它?
    為什麼 `Class.getResource()` 在載入「GeoIP.dat」時返回 Null 以及如何修復它?
    URL資源載入失敗:Class.getResource回傳Null嘗試使用getResource()方法檢索資源的URL時,有些使用者遇到該方法傳回null 的問題。當嘗試載入“GeoIP.dat”檔案時,會特別出現此問題。這裡更深入地探討了潛在原因和載入資源的替代方法。 可能的原因getResou...
    程式設計 發佈於2024-11-08
  • 了解 PHP 元程式設計:動態程式碼操作
    了解 PHP 元程式設計:動態程式碼操作
    PHP 元程式設計 是指編寫可以產生或操作其他程式碼的程式碼。換句話說,它使程式能夠在運行時檢查、修改甚至產生新程式碼,從而具有更大的靈活性。它還可能涉及反射、動態程式碼生成和內省等技術。 在 PHP 中,元程式設計最常被使用: Reflection API:允許在執行時間檢查類別、方法、屬性等。...
    程式設計 發佈於2024-11-08
  • Python 日誌記錄
    Python 日誌記錄
    日誌,記錄。它是什麼以及如何使用 Python 註冊事件 使用日誌記錄建立日誌使我們能夠在程式碼中獲得許多功能和靈活性。在這篇簡短的文章中,我向您展示了基礎知識和更多內容,以開始將其合併到您的專案中。 什麼是日誌記錄?還有日誌? 日誌記錄是監視事件的一種方式。這些事件透過描述性訊息...
    程式設計 發佈於2024-11-08
  • 字串 - JavaScript 挑戰
    字串 - JavaScript 挑戰
    您可以在 repo Github 上找到這篇文章中的所有程式碼。 字串相關的挑戰 是字母數字 /** * @param {any} char * @return {Boolean} */ function isAlphaNumeric(char) { re...
    程式設計 發佈於2024-11-08
  • 如何使用遷移在應用程式之間移動 Django 模型?
    如何使用遷移在應用程式之間移動 Django 模型?
    透過遷移在 Django 應用程式之間移動模型將模型組織到單獨的 Django 應用程式結構中可以增強專案的可維護性和結構。雖然之前使用 South 的嘗試可能被證明很困難,但 Django 1.7 的遷移系統提供了一個無縫的解決方案。 過程使用遷移。 SeparateDatabaseAndStat...
    程式設計 發佈於2024-11-08
  • 人工智慧中的分塊 - 你缺少的秘密武器
    人工智慧中的分塊 - 你缺少的秘密武器
    大家好! ? 你知道是什么让我彻夜难眠吗?思考如何让我们的人工智能系统更智能、更高效。今天,我想谈谈一些听起来很基础但在构建强大的人工智能应用程序时至关重要的事情:分块 ✨. 到底什么是分块? ? 将分块视为人工智能将大量信息分解为可管理的小部分的方式。就像你不会尝试一次将整个披萨...
    程式設計 發佈於2024-11-08
  • 如何使用Python有效率地跨多個目錄搜尋檔案?
    如何使用Python有效率地跨多個目錄搜尋檔案?
    在 Python 中尋找檔案當檔案的位置在不同系統中不同時,在 Python 中尋找檔案可能是一個挑戰。幸運的是,Python 提供了 os.walk 模組,讓您可以輕鬆遍歷目錄並定位檔案。 os.walk 用於檔案搜尋os.walk 建立一個生成器迭代目錄及其子目錄的對象,每次迭代產生三個元組: ...
    程式設計 發佈於2024-11-08
  • 為什麼會出現“getaddrinfo 失敗”以及如何修復?
    為什麼會出現“getaddrinfo 失敗”以及如何修復?
    探索“getaddrinfo failed”錯誤名稱解析過程中發生錯誤“getaddrinfo failed”,其中主機名稱被翻譯轉換為IP 位址。它顯示所提供的主機名的解析有問題。 深入研究錯誤情境從提供的錯誤追蹤中,我們可以將原因追溯到套接字。 getaddrinfo(主機,連接埠)方法。當無法...
    程式設計 發佈於2024-11-08
  • 如何將 React Hooks 整合到我現有的類別元件中?
    如何將 React Hooks 整合到我現有的類別元件中?
    將React Hooks 整合到現有的React 類別元件中正如您所注意到的,React hooks 提供了另一種管理狀態和邏輯的方法反應應用程式。然而,您可能希望逐步遷移現有的基於類別的元件以接受鉤子的優勢。 幸運的是,有一個解決方案可以解決這個挑戰:高階組件(HOC)。 HOC 提供了一種使用注...
    程式設計 發佈於2024-11-08
  • 如何使用 PHP 產生時區下拉清單?
    如何使用 PHP 產生時區下拉清單?
    用 PHP 產生時區下拉清單大多數網站需要一種方法來顯示使用者首選時區的日期。以下是可以使用的兩個時區列表,以及使用 PHP 5 及更高版本中提供的內建 PHP DateTime 類別的方法。 使用硬編碼時區列表此方法涉及手動建立時區列表,可以作為 HTML 元素中的值,也可以作為數組中的鍵。下面...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3