English Русский 中文 Español Deutsch 日本語
Desenvolvimento de robôs de negociação usando programação visual

Desenvolvimento de robôs de negociação usando programação visual

MetaTrader 5Negociação | 21 fevereiro 2022, 10:45
1 360 1
Evgenii Shcherbakov
Evgenii Shcherbakov

Introdução

Como regra, as estratégias de negociação podem ser reduzidas a um algoritmo que pode ser automatizado. Os robôs de negociação podem realizar operações de trading milhares de vezes mais rápido que um ser humano, mas nem todo trader tem habilidades de programação.

botbrains.app é uma plataforma no-code para desenvolver robôs de negociação. Para criar um robô de negociação no editor BotBrains você não precisa de programação - basta arrastar e soltar os blocos que deseja no esquema, parametrizá-los e estabelecer as ligações entre eles.

O botbrains.app tem documentação (docs.botbrains.app), ela detalha todos os conceitos do editor. Este artigo descreve a interface do editor, seus principais recursos e discute a implementação da estratégia de negociação "cruzamento de médias móveis".


Recursos do Editor

Com o BotBrains você pode não apenas desenvolver robôs de negociação simples (por exemplo, baseados no cruzamento de médias móveis), mas também algoritmos de trading complexos (por exemplo, robôs baseados no spread entre símbolos). O  BotBrains permite vincular o robô de negociação ao bot pessoal do Telegram; com blocos especiais, você pode enviar mensagens com resultados de negociação e enviar capturas de tela de gráficos de qualquer tamanho. Você também pode construir uma interface de robô completa no editor BotBrains - criar botões e atribuir ações a eles, adicionar campos de entrada para controlar os valores das variáveis enquanto o robô está em execução, existem também muitos recursos para criar atribuir interface do robô.

Abaixo está uma tabela de categorias de blocos disponíveis no editor botbrains. No final deste artigo, é fornecida uma lista completa dos blocos disponíveis.

Categoria Descrição
Eventos Os blocos são ativados quando ocorre um determinado evento de negociação, por exemplo, uma alteração no preço do gráfico ou uma alteração livro de ofertas.
Condição
O bloco de condição executa uma verificação.
Loop
Loops têm muitos usos. Por exemplo, com um loop, você pode percorrer todos os símbolos disponíveis e determinar qual fez o maior movimento na última sessão de negociação.
Indicadores
O indicador é uma das principais ferramentas da análise técnica. BotBrains oferece uma ampla gama de indicadores, desde volumes simples até nuvens Ichimoku.
Análise de gráfico
Por exemplo, você pode obter informações sobre uma vela específica, obter o preço máximo/mínimo para um determinado período. Você também pode desenhar linhas verticais e horizontais no gráfico.
Análise de livro de ofertas
Obtém informações sobre o spread e os campos do livro de ofertas.
Transações
Coloca ordens a mercado, limite e stop. Remoção de ordens limite e stop. Fechamento de posições.
Variáveis
Altera os valores das variáveis. Por exemplo, você pode armazenar o número de lotes que o robô negociará numa variável.
Sons
Quando algo acontece, você pode tocar um som específico. Por exemplo, você pode tocar o som "Sinal de compra" quando todas as condições para fazer uma compra forem atendidas.
Obtenção de informações
Recepção de informações sobre: conta, sessão de negociação, ordens limite/stop ativas, símbolo, hora, ordens históricas limite/stop, transações históricas.
Enumerações
Busca exaustiva na lista de símbolos, bem como na lista de ordens limite e stop ativas. Percorre ordens limite/stop e transações históricas.
Telegram
Envio de mensagens e capturas de tela de gráficos no Telegram.
Interface
Constrói toda a interface do robô de negociação. Elementos individuais dentro dela podem ser alterados usando blocos de modificação. Você pode atribuir ações aos botões da interface. Com os blocos de interface "campo de entrada", você pode alterar os valores das variáveis diretamente durante a negociação. Tudo isso permite criar interfaces dinâmicas.
Constantes predefinidas
Basicamente, elas são usadas para verificações. Por exemplo, digamos que temos 3 constantes predefinidas para a direção da posição: compra, venda e sem direção. Você pode obter a direção da posição aberta atual e compará-la com uma das constantes predefinidas.
Depuração
Com o bloco de depuração, você pode enviar informações de depuração para o log do terminal. Por exemplo, com ele, você pode verificar se as variáveis contêm os valores corretos.
Outros blocos
Fechamento do terminal, encerramento do robô, suspensão temporária do robô. Log num arquivo, notificação no terminal, comentário no gráfico.
Operações matemáticas
Adição, subtração, multiplicação, divisão, resto da divisão, raiz quadrada, exponenciação. Comparações: menor que, maior que, menor ou igual a, maior ou igual a.
Operadores lógicos
Existem operadores lógicos para condições de construção: AND, OR, NOT.
Teleporte
Existem blocos para entrar e sair do teleporte. Às vezes, você precisa alternar rápida e convenientemente para a execução de outra seção do esquema - com a ajuda de teleportes, isso é feito em questão de segundos.
Blocos de conversão de tipo
Por padrão, todos os dados do usuário são armazenados como um número. Com os blocos de conversão, podemos especificar explicitamente em qual formato queremos representar os dados. Existem 4 tipos: inteiro, fracionário, string, data e hora.
Seleção de variável ou constante
Escolhe uma variável ou constante.
Inserção de valor
Insere um valor.

Interface do editor BotBrains

O editor tem 3 modos: lógica, interface, código.

Modo "lógica":

No modo lógica, você pode construir um esquema lógico do robô. Neste modo, você pode usar a grande maioria dos blocos: desde o "if" e os que permitem fazer transações até aqueles para enviar mensagens do Telegram e os usados para log do robô. Neste modo, você trabalha na lógica do seu robô de negociação. Com blocos simples, você especifica o que seu robô deve fazer - quando comprar, quando vender, quando enviar mensagens para o Telegram, quando parar de negociar e assim por diante. No total, o editor disponibiliza mais de 140 blocos, com eles você pode implementar praticamente qualquer estratégia de negociação.

Logic mode

Modo "interface":

No modo interface, como o nome indica, você pode construir a interface do robô de negociação. Em apenas alguns minutos, você pode criar uma interface completa. Cada elemento de interface possui configurações de aparência completas. Com o bloco "modificar elemento de interface", você pode alterar os parâmetros dos elementos de interface diretamente enquanto o robô está em execução.

interface mode

Modo "código":

Neste modo, você pode visualizar o código gerado do robô de negociação. Para gerar o código do robô de negociação, basta pressionar a tecla ~ ou clicar no botão correspondente na barra de ferramentas à direita.

Code mode

Inicialização de robô de negociação

Todo o código do seu robô de negociação é gerado em questão de segundos após pressionar uma tecla. Para rodar um robô feito com BotBrains, você precisa ter certeza de que todas as dependências necessárias estão definidas:

  1. Biblioteca botbrains_lib.ex5
  2. Arquivo anexadobotbrains_lib.mqh
  3. Arquivo anexado botbrains_constants.mqh
  4. Arquivos de som

Se as dependências acima não estiverem definidas, os robôs feitos com BotBrains não poderão ser executados ou não funcionarão corretamente.

Você pode baixar todas as dependências necessárias através desse link. A definição de dependências é abordada em detalhes nesse artigo da documentação.

Exemplo: cruzamento de média móvel

Vamos considerar a implementação da estratégia de negociação "cruzamento de médias móveis". Você pode abrir o esquema finalizado logo no editor clicando no link.

Abrimos o editor, e criamos 5 constantes em nosso robô:

  1. slow_ma_period período da média móvel lenta (valor constante: 60)
  2. fast_ma_period - período da média móvel rápida (valor constante: 30)
  3. symbol - código do símbolo negociado  (valor constante: MGCV21 ou qualquer outro símbolo que esteja para ser operado)
  4. admin_id - identificador do usuário Telegram, para o qual nosso robô ira enviar informações sobre os negócios e capturas de tela de gráficos (valor constante: seu ID no Telegram)
  5. lot - quantidade de lotes negociados

constants

Para determinar se duas médias móveis se cruzam, você precisa criar 4 variáveis:

  1. ma_slow - valor atual da média móvel lenta
  2. ma_fast - valor atual da média móvel rápida
  3. ma_slow_prev - valor da média móvel lenta na vela anterior
  4. ma_fast_prev -valor da média móvel rápida na vela anterior


Assim, podemos determinar o cruzamento das médias móveis lentas e rápidas simplesmente comparando os valores dessas variáveis. Note que não definimos o valor inicial para as variáveis, uma vez que o valor dessas variáveis será atualizado quando chegar um novo tick do instrumento negociado.

Vamos fazer com que quando o robô for iniciado, a mensagem "Robot inciado" seja exibida no log do terminal. Para isso, basta arrastar dois blocos para o esquema lógico do robô: o bloco de eventos "Inicialização de robô" e o bloco "Mensagem no log". E conecte os conectores desses blocos:

robot launch message

Assim, especificamos que quando o robô iniciar (o bloco de eventos "Inicialização de robô"), o bloco "Mensagem no log" deve ser executado.

Nas configurações do bloco "Mensagem no log", especificamos a mensagem que deve ser exibida quando o robô iniciar:

journal message block settings

Quando chega um novo tick do instrumento negociado, nosso robô deve alterar os valores das variáveis. Para isso, arrastamos o bloco de eventos "Novo tick" e 4 blocos "Definir o valor calculado da variável" para o esquema lógico do robô. Definimos ligações entre esses blocos:

variables update on new tick

Com o bloco "média móvel", podemos obter o valor correspondente. Este bloco possui os seguintes parâmetros:

  1. Símbolo
  2. Período gráfico 
  3. Número de períodos
  4. Método de suavização
  5. Preço usado
  6. Deslocamento

Com o parâmetro "deslocamento", podemos obter o valor do indicador numa vela específica. Por exemplo, o deslocamento 0 é o valor do indicador na vela atual, enquanto o deslocamento 1 é o valor do indicador na vela anterior. Assim, podemos obter os valores das médias móveis rápidas e lentas nas velas atuais e anteriores. Para isso, você precisa especificar valores diferentes para os parâmetros "Número de períodos" e "Deslocamento". 

Arraste o bloco do indicador "Média móvel" para o corpo do primeiro bloco:


Definimos os parâmetros do bloco "Média móvel":

Note que as constantes correspondentes são usadas como os valores dos parâmetros "Símbolo" e "Número de períodos". Você também pode usar variáveis como valores de parâmetro de blocos.

As variáveis e as constantes são descritas na documentação.

Assim, o valor atual da média móvel lenta será escrito na variável "ma_slow" toda vez que um novo tick do instrumento negociado aparecer.

Vamos fazer o mesmo para a variável "ma_fast":

Nesta fase, estamos atualizando os valores atuais das médias móveis, mas para determinar o cruzamento, você precisa saber o valor das médias móveis na vela anterior. Portanto, nos últimos 2 blocos "Definir o valor calculado da variável", faremos tudo por analogia, mas definiremos o parâmetro "Deslocamento" dos blocos "Média móvel" como 1, para que os valores da variável das médias da vela anterior sejam gravadas nas variáveis "ma_slow_prev" e "ma_fast_prev" .

Fazemos o mesmo para a variável "ma_fast_prev".

Vamos garantir que valores corretos sejam gravados em nossas variáveis. Vamos adicionar o bloco de eventos "Temporizador" ao esquema. Este bloco possui apenas o parâmetro "Intervalo (s)". Este parâmetro é como padrão 1, o que significa que o bloco é chamado a cada segundo por padrão. Em seguida, vamos adicionar o bloco "Informações de depuração" ao diagrama 4 - este bloco simplesmente envia o valor especificado para o log do terminal. Com ele, podemos ver quais valores são gravados em nossas variáveis. Vamos colocar 3 blocos em cada bloco "Informações de depuração" na seguinte ordem:

  1. A entrada de valor é um campo de entrada simples onde podemos inserir um texto arbitrário. No nosso caso, vamos simplesmente inserir os nomes das variáveis para entender a quais variáveis esses ou aqueles valores se referem.
  2. Sinal "+", com a ajuda deste bloco, podemos combinar duas linhas. 
  3. Com o bloco "Seleção de variável", você pode selecionar uma variável cujo valor precisamos obter.

Nosso esquema deve ficar assim:

No BotBrains, todos os valores do usuário são armazenados como um número. Nesse caso, precisamos indicar explicitamente que os blocos de entrada de valor contêm texto para que seja o próprio texto que é exibido e não, sua representação numérica.

Para fazer isso, você precisa usar o bloco de conversão "String normal". Você só precisa mover este bloco para cada bloco de entrada de valor:

Nesta fase, poderemos compilar o código do robô e até executá-lo, os valores das variáveis especificadas serão exibidos no log do terminal de acordo com o temporizador. No entanto, durante a compilação será gerado o aviso "implicit conversion from 'number' to 'string'":

Na verdade, em nosso esquema, estamos tentando adicionar um valor de string (bloco de entrada de valor convertido numa string) com um valor numérico (valores de variáveis). Para corrigir isso, precisamos apenas converter os valores de nossas variáveis em strings. Podemos fazer isso de duas maneiras:

  1. Com o mesmo bloco de conversão "String normal"
  2. Com o bloco para converter "Número fracionário" - este bloco difere do bloco "String normal" apenas porque podemos limitar o número de casas decimais

Vamos usar o segundo método. Para fazer isso, vamos transferir o bloco de conversão "Número fracionário" para cada bloco de seleção de variável:

Nas configurações de cada bloco "Número fracionário", especifique 2 como o único parâmetro - "Casas decimais":

Os tipos são descritos em detalhes na documentação.

Vamos abrir o terminal e adicionar 2 indicadores "Moving Average" ao gráfico do instrumento negociado com os mesmos parâmetros que são utilizados em nosso robô, para que possamos comparar os valores das variáveis com os valores dos indicadores no gráfico:

Vamos gerar o código do robô clicando em ~ ou no botão correspondente na barra de ferramentas à direita:

Vamos rodar nosso robô no terminal e comparar os valores que são exibidos no log do terminal com os valores reais dos indicadores no gráfico:

Visto que todos os valores convergem, podemos continuar trabalhando.

Resta apenas comparar os valores das variáveis quando surge um novo tick do instrumento negociado para determinar o cruzamento das médias móveis e fazer um negócio se todas as condições forem atendidas.

Primeiro, vamos definir as condições para entrar. Para entrar numa posição longa, deverão ser atendidas 3 condições:

  1. O valor atual da média móvel rápida deverá ser maior que o valor atual da média móvel lenta
  2. O valor atual da média móvel rápida na vela anterior deverá ser menor do que o valor atual da média móvel lentana vela anterior
  3. A direção da posição atual não deverá ser "compra"

É fácil esquecer a última condição, por causa dela nosso robô pode começar a fazer muitas transações num pequeno período de tempo, pois a condição 1 e a condição 2 podem ser atendidas várias vezes por segundo. A condição número 3 faz com que o robô não faça nenhuma compra acima de uma posição longa existente.

Nota: no editor BotBrains você pode especificar a frequência máxima e suspeita de transação para todos os robôs. Se a frequência máxima de negócios for atingida, o robô fechará imediatamente todas as posições abertas e removerá todas as ordens feitas, e o robô também o notificará via Telegram e/ou o notificará diretamente no terminal, dependendo dos parâmetros que você tiver definido nas configurações de segurança do robô. Se o robô atingir uma frequência suspeita de negócios, ele não fechará as posições e retirará as ordens; em vez disso, ele apenas o notificará via Telegram e/ou fará uma notificação no terminal.

Para entrar no curto, devem ser atendidas as seguintes condições:

  1. O valor atual da média móvel rápida deverá ser menor do que o valor atual da média móvel lenta
  2. O valor atual da média móvel rápida na vela anterior deverá ser maior do que o valor atual da média móvel lenta na vela anterior
  3. A direção da posição atual não deverá ser "venda"

Vamos criar uma condição para entrar no longo:

O bloco "Informações de posição" possui 2 parâmetros: 

  1. Símbolo- símbolo da posição de que precisamos obter informação
  2. Valor do bloco - parâmetro de posição de que precisamos. Opções disponíveis: volume da posição, tempo de abertura da posição, preço de abertura da posição, lucro da posição atual e direção da posição

Como parâmetro "Símbolo", utilizamos a constante "symbol" - nesta constante armazenamos o código do instrumento negociado. Como parâmetro "Valor do bloco" usamos "Direção da posição".

Assim, o valor do bloco "Informações sobre a posição" será igual à direção da posição do símbolo negociado.

Este bloco é seguido por dois blocos: "NOT" e "EQUAL". Depois deles vem o bloco da constante predefinida "Direção" - este bloco armazena todas as direções possíveis: "Direção de compra", "Direção de venda" e "Sem direção". Verificamos que a direção da posição atual não é igual à direção de compra.

Adicionamos o bloco "Ordem a mercado" ao esquema e o vinculamos ao conector "Sim" do bloco de condição:

O bloco de ordens a mercado tem 3 parâmetros:

  1. Símbolo - símbolo com o qual a ordem a mercado deve ser colocada
  2. Direção - direção da ordem (compra/venda)
  3. Volume - volume da ordem


Note que usamos constantes como valores para muitos dos parâmetros. Isso nos permite configurar facilmente o robô, em outras palavras, podemos simplesmente alterar o valor de uma constante num local e o novo valor será usado automaticamente em todos os locais onde tal constante for usada.

Se houver constantes no robô de negociação feitas no editor BotBrains, elas serão listadas no topo do código gerado:

/********** <EA CONSTANTS> **********/

const double __slow_ma_period = user_value("60");
const double __fast_ma_period = user_value("30");
const double __symbol         = user_value("MGCV21");
const double __admin_id       = user_value("744875082");
const double __lot            = user_value("1");

/********** </EA CONSTANTS> **********/

Você pode pensar em constantes como configurações do robô. Por exemplo, se você decidir negociar outro instrumento, basta alterar o valor da constante do símbolo ou alterar o valor da constante diretamente no editor BotBrains e gerar novamente o código se não quiser trabalhar diretamente com o arquivo.

Assim, nesta fase, o robô de negociação abrirá uma posição longa quando a média móvel rápida cruzar a média móvel lenta de baixo para cima. Vamos adicionar alertas:

  1. Exibição de uma mensagem no log do terminal
  2. Criamos uma notificação no terminal
  3. Vamos adicionar um registro sobre a transação concluída ao arquivo de log do robô
  4. Vamos tocar o som "Sinal de compra"
  5. Vamos enviar uma mensagem para o Telegram
  6. Enviaremos uma captura de tela do gráfico para o Telegram

Note que, se tocarmos o som "Sinal de compra" imediatamente após a transação ser feita, provavelmente nosso som não será reproduzido, pois o MetaTrader reproduz automaticamente seu som toda vez que uma transação é feita. Por isso, você precisa reproduzir o som não imediatamente, mas em um determinado intervalo após a transação, por exemplo, 1 segundo. 

Pode parecer que a implementação de todos os 6 pontos levará muito tempo, de fato, também existem blocos especiais para tudo isso. Demorará literalmente 20-30 segundos implementar todos os 6 pontos. Tudo o que fizemos antes também pode ser feito em questão de minutos, mais rápido do que escrever código à mão.

Para que os blocos do Telegram funcionem corretamente, você precisa registrar seu bot no bot do Telegram @BotFather, obter seu token e especificá-lo nas configurações do robô no editor BotBrains. Você também precisa saber seu ID no Telegram - você pode encontrá-lo no bot @getmyid_bot. Tudo isso é descrito em detalhes na documentação. Os blocos do Telegram também estão disponíveis apenas para usuários pro.

Por analogia, implementamos uma verificação para posição curta. Para isso, basta selecionar todos os blocos relacionados à abertura de posição longa, copiar (CTRL + C), colá-los (CTRL + V) e fazer as alterações necessárias.

Vamos gerar o código do robô, compilá-lo e executá-lo no terminal para verificar seu desempenho.

Teste os robôs de negociação apenas em uma conta demo! Por padrão, nas configurações de segurança de todos os robôs feitos no editor BotBrains, é proibido negociar em uma conta real! Mude para uma conta real somente depois de testar completamente seu robô de negociação em uma conta demo!

Vamos definir períodos aleatórios de médias móveis e rodar um robô de negociação em um período gráfico de minuto. Nesta fase, é importante testarmos o desempenho do nosso robô, detectar possíveis erros e eliminá-los. Após 80 minutos de negociação, o robô abriu 4 posições. Após abrir cada posição, o robô fez uma notificação com sucesso no terminal, tocou os sons respectivos, fez as entradas correspondentes no arquivo de log do robô e no log do terminal. Além disso, enviou mensagens e capturas de tela de gráficos diretamente para o meu Telegram sem problemas. E depois de tudo isso, não escrevemos uma única linha de código. O esquema de um robô tão simples como esse pode ser construído em apenas alguns minutos.


Pode parecer que tudo está em ordem. No entanto, após um exame detalhado das transações feitas pelo nosso robô, podemos descobrir que em cada posição, exceto na primeira, ele entrou em duas transações: a primeira para sair da posição aberta atual e a segunda para abrir a próxima posição. Isso é fácil de ver, basta olhar para o gráfico, verificar o arquivo de log, ver as mensagens enviadas pelo robô de negociação para nós ao Telegram ou simplesmente ouvir quantas vezes ele gera um alerta sonoro depois que uma negociação é feita . Também podemos analisar o histórico de transações no terminal.

No editor BotBrains, nas configurações de segurança do robô, você pode especificar a frequência suspeita e máxima das transações. Por padrão, a frequência máxima de transações é de 2 transações a cada 10 segundos. Quando a frequência máxima de transações for atingida, o robô de negociação fechará com urgência todas as posições abertas, removerá todas as ordens colocadas e notificará no Telegram e/ou no terminal.

O problema não é apenas que, como resultado da abertura de posições em duas etapas, faremos o dobro de transações necessárias e entraremos na maioria das posições com o pior preço, mas também que em algum momento nosso robô atingirá a frequência máxima de transações e parará. Foi exatamente o que aconteceu no meu caso. Preste atenção às últimas entradas no arquivo de log:

Vamos corrigir este problema. Vamos criar outra variável, full_lot:

Ao iniciar o robô (bloco de evento "Inicialização de robô") definimos o valor da variável full_lot no valor da constante lot:

Em seguida, nos blocos de transação, em vez de uma constante lot, usaremos a variável full_lot:

A seguir, após inserir a posição, definimos o valor da variável full_lot no valor dobrado da constante lot. Depois de fazer a primeira transação, o robô começará a negociar o dobro do volume. Assim, ele fechará a posição existente e abrirá uma nova com uma transação:

Agora o robô de negociação entrará em todas as posições com uma única transação. Vamos verificar isso executando o robô no terminal. Se observarmos o histórico de transações, veremos que o robô abriu uma primeira transação de 1 lote e as seguintes de 2 lotes:



Vamos criar uma interface para o robô de negociação. Para fazer isso, vamos para o modo "Interface" do editor e usamos blocos especiais para construir a mesma:

Para a construção, basta usar os seguintes blocos de interface:

  1. Retângulo
  2. Texto
  3. Botão

Vamos garantir que, em vez de traços, sejam colocados os valores reais das médias móveis rápidas e lentas. Para fazer isso, devemos usar o bloco "Modificar elemento de interface", para alterar as propriedades do bloco com o ID especificado.

Vamos transferir 4 blocos "Modificar elemento de interface" para o esquema lógico do robô:

Para copiar o ID do bloco, devemos fazer o seguinte:

  1. Pressionamos CTRL
  2. Sem soltar CTRL, clicamos duas vezes no bloco desejado

Copiamos o ID do primeiro traço:

Vamos abrir as configurações do primeiro bloco "Modificar elemento de interface" e especificar os valores dos parâmetros. Em primeiro lugar, especificamos o ID do bloco cujas propriedades queremos alterar. No nosso caso, este é o ID copiado do primeiro traço. Como tipo de modificação, selecionamos "Texto". Como o novo texto, especificamos a variável ma_fast_prev:


Por analogia, definimos os parâmetros dos 3 blocos restantes para modificar os elementos da interface. Assim, quando um novo tick para um instrumento negociado aparece, nas variáveis ma_fast, ma_slow, ma_fast_prev e ma_slow_prev são gravados os valores correspondentes das médias móveis e, logo, os valores dessas variáveis são gravados nos devidos elementos de texto da interface.

Agora vamos atribuir as ações apropriadas aos botões da interface. Para isso, vamos transferir três blocos para o esquema lógico do robô: 2 blocos "Ordem a mercado" e 1 bloco "Fechar posição":

Definimos as configurações destes blocos:

Vamos copiar o ID do 1º bloco "Ordem a mercado" e especificar o ID copiado como o valor do parâmetro "ID do bloco relacionado" do primeiro botão:

Assim, ao clicar no botão "Comprar", será chamado o bloco correspondente. Por analogia, atribuiremos ações aos botões restantes. Vamos gerar o código do robô e executá-lo no terminal para verificar seu desempenho:


 

Observe que a interface que construímos no editor foi completamente transferida para o terminal de negociação. Os botões da interface funcionam e em vez de traços podemos ver os valores reais das médias móveis.

Por fim, o código do robô de negociação gerado fica assim:

//+------------------------------------------------------------------+
//|                                         moving_average_cross.mq5 |
//|                                                    botbrains.app |
//+------------------------------------------------------------------+

#include <botbrains_constants.mqh>
#include <botbrains_lib.mqh>

/********** <EA CONSTANTS> **********/

const double __slow_ma_period = user_value("60");
const double __fast_ma_period = user_value("30");
const double __symbol         = user_value("MGCZ21");
const double __admin_id       = user_value("744875082");
const double __lot            = user_value("1");

/********** </EA CONSTANTS> **********/

/********** <EA VARIABLES> **********/

double __ma_slow      = user_value("");
double __ma_fast      = user_value("");
double __ma_slow_prev = user_value("");
double __ma_fast_prev = user_value("");
double __full_lot     = user_value("");

/********** </EA VARIABLES> **********/

int OnInit(){

  //Is auto trading allowed in the terminal:
  if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)){
    MessageBox("Auto trading in the terminal is disabled, the Expert Advisor will be unloaded");
    ExpertRemove();
    return(-1);
  }

  //Can the robot trade on a real account:
  if(AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_REAL){
    MessageBox("The EA is not allowed to trade on a real account!");
    ExpertRemove();
    return(-1);
  }

  //Set the EA name:
  set_robot_name("moving_average_cross");

  //Set the license key:
  set_license_key("2L5J7K-K986ND-KMPT94-1Q");

  //Set the language:
  set_lang("ru");

  //Generate the EA stamp (magic number):
  generate_magic();

  //Set the deposit amount at the time of the EA launch:
  set_init_account_balance();

  //Set the parameters of the suspicious frequency of deals:
  set_suspicous_deals_frequency(60, 3, false, true);

  //Set the parameters of the maximum frequency of deals:
  set_max_deals_frequency(10, 2, false, true);

  //Set the timer with an interval of 1 second:
  EventSetTimer(1);

  //Blocks called when the EA is launched:
  block_bYi6ikfde();
  block_bYUS6GLT0();

  //Create the interface elements:
  create_rectangle("b1ELCu5iq", 0, 0, CORNER_LEFT_UPPER, 15, 15, 390, 195, C'20,20,20', BORDER_FLAT, STYLE_SOLID, C'10,191,254', 2, 0, false, false, false);
  create_button("b4rh5uKlb", 0, 0, CORNER_LEFT_UPPER, 195, 165, 150, 30, "Sell", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'255,51,0', false, 0, false, false, false);
  create_text("b5BGSldua", 0, 0, CORNER_LEFT_UPPER, 120, 135, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("b9EjNpibO", 0, 0, CORNER_LEFT_UPPER, 30, 30, "Trading robot \"MA Cross\"", "Ubuntu Mono", 14, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_button("bBTrBQlkS", 0, 0, CORNER_LEFT_UPPER, 30, 165, 150, 30, "Buy", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'51,255,0', false, 0, false, false, false);
  create_text("bEncRhDIR", 0, 0, CORNER_LEFT_UPPER, 285, 75, "Current candle:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bI0vadsS2", 0, 0, CORNER_LEFT_UPPER, -195, 270, "Text", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bK1cW1i6s", 0, 0, CORNER_LEFT_UPPER, 30, 135, "MA slow:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bLcIIkYqO", 0, 0, CORNER_LEFT_UPPER, 285, 135, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bSDWBsxbk", 0, 0, CORNER_LEFT_UPPER, 285, 105, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bTK8r1zb1", 0, 0, CORNER_LEFT_UPPER, 30, 105, "MA fast:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bhKcJ2pwx", 0, 0, CORNER_LEFT_UPPER, 120, 75, "Previous candle:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bj6MtjhZF", 0, 0, CORNER_LEFT_UPPER, 120, 105, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_button("bympSPhAp", 0, 0, CORNER_LEFT_UPPER, 360, 165, 30, 30, "X", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'255,51,0', false, 0, false, false, false);

  ChartRedraw();

  //EA initialization is successful:
  return(INIT_SUCCEEDED);

}

void OnDeinit(const int reason){

  Comment("");
  PlaySound(NULL);

  //Remove all graphical objects of the chart the EA was launched on:
  remove_all_objects(0);

}

void OnTimer(){

  //Timer with the interval of 1 second (bgP4YbxaQ):
  block_bTonyumSN();
  block_bO7LNEs4m();
  block_bS1JODjZj();
  block_bM4s77Wvc();

  // Reset the completed deals counter (maximum deal frequency) once per 10 seconds:
  if(get_timer_tick_index() % 10 == 0){

    deals_max_frequency_counter_reset();

  }

  // Reset the completed deals counter (suspicious deal frequency) once per 60 seconds:
  if(get_timer_tick_index() % 60 == 0){

    deals_suspicious_frequency_counter_reset();

  }

  timer_tick_index_increment();

}

void OnTick(void){

  //Blocks called when a new tick arrives for the symbol whose chart features the EA:
  block_bHxbWWtwW();
  block_bvIvs7SMe();
  block_boHVNlqnO();

}

void OnTrade(){

  //Check the deal frequency:
  check_deals_frequency();

}

void OnChartEvent(
  const int      id,      // event ID
  const long&    lparam,  // event parameter of long type
  const double&  dparam,  // event parameter of double type
  const string&  sparam   // event parameter of string type
){

  if(id == CHARTEVENT_OBJECT_CLICK){

    string object_name = sparam;

    if(ObjectGetInteger(0, object_name, OBJPROP_TYPE) == OBJ_BUTTON){

      if(object_name == "b4rh5uKlb"){

        block_bYGEhpZDM();

      }

      if(object_name == "bBTrBQlkS"){

        block_bCa4uSC92();

      }

      if(object_name == "bympSPhAp"){

        block_bXRrICVna();

      }

      Sleep(100);
      ObjectSetInteger(0, object_name, OBJPROP_STATE, false);
      ChartRedraw();

    }

  }

}

//b0Wkfq6OD block function (set_complex_variable_value):
void block_b0Wkfq6OD(){

  vset(__ma_fast, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__fast_ma_period, MODE_SMA, PRICE_CLOSE, 0) ));

  block_b6LYVQGej();

}

//b1VYatoxs block function (interface_element_modify):
void block_b1VYatoxs(){

  modify_text("b5BGSldua", DoubleToString(__ma_slow_prev, 2) );

}

//b3UJfY74N block function (interface_element_modify):
void block_b3UJfY74N(){

  modify_text("bSDWBsxbk", DoubleToString(__ma_fast, 2) );

}

//b3crj4ayK (log) block function:
void block_b3crj4ayK(){

  log_to_file("Open short!");

  block_bzVyOb4tW();

}

//b6LYVQGej block function (set_complex_variable_value):
void block_b6LYVQGej(){

  vset(__ma_slow_prev, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__slow_ma_period, MODE_SMA, PRICE_CLOSE, 1) ));

  block_bQMre45Bd();

}

//bCa4uSC92 block function (place_market_order):
void block_bCa4uSC92(){

  place_market_order(to_string(__symbol), "BUY", __lot);

}

//bHxbWWtwW block function (condition):
void block_bHxbWWtwW(){

  if (( __ma_fast > __ma_slow ) && ( __ma_fast_prev < __ma_slow_prev ) && ( get_position_info(to_string(__symbol), "POSITION_DIRECTION") != BUY_DIRECTION )){

    block_bUySCvh6M();

  }

}

//bM4s77Wvc block function (print_debug_info):
void block_bM4s77Wvc(){

  print_debug_info(( to_string(to_double("ma_fast_prev = ")) + DoubleToString(__ma_fast_prev, 2) ));

}

//bMgaVnT74 block function (pause):
void block_bMgaVnT74(){

  pause(1000);

  block_bT8xv0qGj();

}

//bO7LNEs4m block function (print_debug_info):
void block_bO7LNEs4m(){

  print_debug_info(( to_string(to_double("ma_fast = ")) + DoubleToString(__ma_fast, 2) ));

}

//bPlXoF1uA block function (set_complex_variable_value):
void block_bPlXoF1uA(){

  vset(__full_lot, ( __lot * to_double("2") ));

}

//bQ4zsFoIh block function (log):
void block_bQ4zsFoIh(){

  log_to_file("Open long!");

  block_bMgaVnT74();

}

//bQMre45Bd block function (set_complex_variable_value):
void block_bQMre45Bd(){

  vset(__ma_fast_prev, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__fast_ma_period, MODE_SMA, PRICE_CLOSE, 1) ));

  block_bRUr8MnXh();
  block_b1VYatoxs();
  block_b3UJfY74N();
  block_bofgi9HOT();

}

//bRUr8MnXh block function (interface_element_modify):
void block_bRUr8MnXh(){

  modify_text("bj6MtjhZF", DoubleToString(__ma_fast_prev, 2) );

}

//bS1JODjZj block function (print_debug_info):
void block_bS1JODjZj(){

  print_debug_info(( to_string(to_double("ma_slow_prev = ")) + DoubleToString(__ma_slow_prev, 2) ));

}

//bT8xv0qGj block function (buy_signal_sound):
void block_bT8xv0qGj(){

  play_sound("buy_signal");

  block_bPlXoF1uA();

}

//bTonyumSN block function (print_debug_info):
void block_bTonyumSN(){

  print_debug_info(( to_string(to_double("ma_slow = ")) + DoubleToString(__ma_slow, 2) ));

}

//bTs8fZtAO block function (telegram_send_chart_screenshot):
void block_bTs8fZtAO(){

  telegram_send_chart_screenshot(to_string(__symbol), 2160, 720, (int)__admin_id);

}

//bUySCvh6M block function (place_market_order):
void block_bUySCvh6M(){

  place_market_order(to_string(__symbol), "BUY", __full_lot);

  block_bfrp6ajWk();
  block_bjBTLJMym();
  block_boX0sSwri();
  block_bQ4zsFoIh();

}

//bWkG0nSQa block function (telegram_send_message):
void block_bWkG0nSQa(){

  telegram_send_message("Open short!", (int)__admin_id);

}

//bX2tY0y68 block function (terminal_print):
void block_bX2tY0y68(){

  terminal_print("Open short!");

}

//bXRrICVna block function (close_position):
void block_bXRrICVna(){

  close_position(to_string(__symbol));

}

//bYGEhpZDM block function (place_market_order):
void block_bYGEhpZDM(){

  place_market_order(to_string(__symbol), "SELL", __lot);

}

//bYUS6GLT0 block function (set_complex_variable_value):
void block_bYUS6GLT0(){

  vset(__full_lot, ( __lot ));

}

//bYi6ikfde block function (terminal_print):
void block_bYi6ikfde(){

  terminal_print("EA launched!");

}

//bfrp6ajWk block function (terminal_print):
void block_bfrp6ajWk(){

  terminal_print("Open long!");

}

//biLE3RJAD block function (sell_signal_sound):
void block_biLE3RJAD(){

  play_sound("sell_signal");

  block_bPlXoF1uA();

}

//bjBTLJMym block function (telegram_send_message):
void block_bjBTLJMym(){

  telegram_send_message("Open long!", (int)__admin_id);

}

//boHVNlqnO block function (set_complex_variable_value):
void block_boHVNlqnO(){

  vset(__ma_slow, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__slow_ma_period, MODE_SMA, PRICE_CLOSE, 0) ));

  block_b0Wkfq6OD();

}

//boX0sSwri block function (telegram_send_chart_screenshot):
void block_boX0sSwri(){

  telegram_send_chart_screenshot(to_string(__symbol), 2160, 720, (int)__admin_id);

}

//bofgi9HOT block function (interface_element_modify):
void block_bofgi9HOT(){

  modify_text("bLcIIkYqO", DoubleToString(__ma_slow, 2) );

}

//bugmLdNsU block function (place_market_order):
void block_bugmLdNsU(){

  place_market_order(to_string(__symbol), "SELL", __full_lot);

  block_bX2tY0y68();
  block_bWkG0nSQa();
  block_bTs8fZtAO();
  block_b3crj4ayK();

}

//bvIvs7SMe block function (condition):
void block_bvIvs7SMe(){

  if (( __ma_fast < __ma_slow ) && ( __ma_fast_prev > __ma_slow_prev ) && ( get_position_info(to_string(__symbol), "POSITION_DIRECTION") != SELL_DIRECTION )){

    block_bugmLdNsU();

  }

}

//bzVyOb4tW block function (pause):
void block_bzVyOb4tW(){

  pause(1000);

  block_biLE3RJAD();

}

No editor BotBrains, esse robô de negociação pode ser construído em minutos e a geração de código leva uma fração de segundo.

Blocos disponíveis

Existem mais de 140 blocos disponíveis no editor BotBrains. Abaixo está uma tabela completa dos blocos disponíveis. Observe que, para entender completamente o princípio de funcionamento do editor, recomendo a leitura da documentação.

Blocos de eventos:

Bloco Descrição
Inicialização do robô
O bloco é ativado 1 vez quando o robô é iniciado.
Encerramento do robô
O bloco é ativado 1 vez quando o robô é desligado.
Mudança no livro de ofertas
O bloco é ativado toda vez que o livro de ofertas muda para o símbolo especificado.
Novo tick
O bloco é ativado toda vez que chega um novo tick do símbolo no gráfico onde iniciado o robô.
Mudança no volume aberto
O bloco é ativado toda vez que o volume aberto para o símbolo especificado muda.
Mudança no número de ordens limite
O bloco é ativado toda vez que o número de ordens limite ativas para o símbolo especificado muda.
Mudança no número de ordens stop
O bloco é ativado toda vez que o número de ordens stop ativas para o símbolo especificado muda.
Temporizador
O bloco é ativado 1 vez com o número de segundos especificado.
Pressionamento de tecla
O bloco é chamado quando uma tecla com o código especificado é pressionada.

Condição:

Bloco Descrição
Bloco "Se"
Cria uma bifurcação lógica no esquema do robô. O bloco tem 1 entrada e 2 saídas.
Loop:

O bloco de loop é usado principalmente para busca exaustiva de valores. Por exemplo, um bloco de loop pode ser usado para percorrer a lista de ordens limite ativas.

Bloco
Descrição
Loop "Até"
O bloco permanece ativo enquanto a condição especificada for verdadeira.
Indicadores de tendência:
Bloco
Adaptive Moving Average
Average Directional Movement Index
Average Directional Movement Index by Welles Wilder
Bollinger Bands
Double Exponential Moving Average
Envelopes
Fractal Adaptive Moving Average
Ichimoku
Moving Average
Parabolic SAR
Standard Deviation
Triple Exponential Moving Average
Variable Index Dynamic Average

Osciladores:

Bloco
Average True Range
Bears Power
Bulls Power
Chaikin Oscillator
Commodity Channel Index
DeMarker
Force Index
MACD
Momentum
Moving Average of Oscillator
RSI (Relative Strength Index)
Relative Vigor Index
Stochastic Oscillator
TRIX (Triple Exponential Moving Averages Oscillator)
Larry Williams' Percent Range
Accumulation / Distribution
Money Flow Index
On Balance Volume
Volumes

Indicadores de Bill Williams:

Bloco
Accelerator Oscillator
Alligator
Awesome Oscillator
Fractals
Gator
Market Facilitation Index

Blocos de análise de gráfico:

Bloco Descrição
Dados da vela
Obtém informações sobre uma vela específica do gráfico.
Informações do gráfico
Obtém informações sobre o gráfico. Por exemplo, o número de velas do gráfico, o horário de abertura da primeira ou última vela disponível.
Máx. preço
Obtém o preço máximo para o período especificado.
Min. preço
Obtém o preço mínimo para o período especificado.
Preço médio
Obtém o preço médio para o período especificado.
Desenhar linha horizontal
Desenha uma linha horizontal no gráfico.
Desenhar linha vertical
Desenha uma linha vertical sobre o gráfico.
Excluir todas as linhas
Remove todas as linhas horizontais e verticais do gráfico.

Blocos de análise do livro de ofertas:

Bloco Descrição
Informações da cotação
Obtenção de informações sobre cotações individuais do livro de ofertas.
Spread
Obtém o spread para o símbolo especificado em ticks.

Transações:

Bloco Descrição
Ordem a mercado
Coloca uma ordem a mercado.
Ordem limite
Coloca uma ordem limite.
Remover ordem limite
Remove uma ordem limite.
Remover todas as ordens limite
Cancela todas as ordens limite para o símbolo especificado.
Ordem stop
Coloca uma ordem de parada.
Remover ordem stop
Remove uma ordem stop.
Remover todas as ordens stop
Remove todas as ordens stop para o símbolo especificado.
Fechar posição
Fecha a posição do símbolo especificado.
Fechar todas as posições abertas
Fecha todas as posições que foram abertas pelo robô atual.

Variáveis:

Bloco Descrição
Definir valor de variável simples
O novo valor da variável é definido através de um campo de entrada. Ou seja, com este bloco, você pode escrever algo específico na variável - um número ou um texto.
Definir valor calculado de variável
O novo valor da variável é determinado pelo valor calculado. Por exemplo, com este bloco, você pode escrever o tamanho atual do depósito ou o preço atual do símbolo negociado numa variável.
Seleção de variável
Seleciona uma variável. Por exemplo, um bloco "selecionar variável" pode ser usado dentro de um bloco de condição para verificar o valor respectivo.

Sons:

Bloco Descrição
Som suave
Reproduz o som "Som suave"
Sirene
Reproduz o som "Sirene"
Sinal de compra
Reproduz o som "Sinal de compra"
Sinal de venda
Reproduz o som "Sinal de venda"

Informações:

Bloco
Informações da conta
Informações de posição
Informações da ordem limite
Informações sobre todas as ordens limite
Informações da ordem stop
Informações de todas as ordens stop
Informações sobre a ordem limite histórica
Informações sobre a ordem stop histórica
Informações sobre a transação histórica
Informações da sessão de negociação
Informações do símbolo
Informações de tempo

Enumerações:

Blocos de enumeração são necessários para busca exaustivamente algo. Por exemplo, uma lista de símbolos ou uma lista de ordens limite/stop ativas pode ser enumerada usando blocos de enumeração.

Bloco Descrição
Nome do símbolo
Obtém o código do símbolo.
Consulta de lista de ordens ativas
Solicita a lista de ordens ativas.
Ticket da ordem limite ativa
Obtém o ticket da ordem limite ativa.
Ticket da ordem stop ativa
Retorna o ticket da ordem stop ativa.
Histórico:
Bloco Descrição
Consulta de dados históricos
Solicita os dados históricos de um período específico.
Ticket da transação no histórico
Obtém o ticket da transação do histórico.
Ticket da ordem limite no histórico
Obtém o ticket da ordem limite desde o histórico.
Ticket da ordem stop no histórico
Obtém o ticket da ordem stop desde o histórico.
Telegram:
Bloco Descrição
Enviar mensagem
Envia a mensagem especificada ao Telegram do usuário com o ID indicado.
Enviar uma captura de tela do gráfico
Envie uma captura de tela do gráfico do símbolo especificado para o Telegram do usuário com o ID especificado.
Quebra de linha
Usado para criar uma quebra de linha dentro da mensagem do Telegram.

Outros:

Bloco Descrição
Mensagem no log
Exibe uma mensagem no log do terminal.
Notificação no terminal
Envia uma notificação no terminal.
Comentário sobre o gráfico
Mostra o comentário especificado no gráfico do símbolo especificado.
Log em arquivo
Faz um log no respectivo arquivo do robô.
Pausa
Pausa o robô o número especificado de milissegundos.
Desativar robô
Desativa o robô.
Fechar terminal
Fecha o terminal.

Elementos da interface:

Bloco Descrição
Retângulo
Elemento de interface "retângulo".
Botão
Elemento de interface "botão".
Texto
Elemento de interface "texto".
Campo de entrada
Elemento de interface "campo de entrada".

Modificações de elementos de interface:

Bloco Descrição
Modificar elemento de interface
Alterar a propriedade de elemento de interface.

Informações sobre elementos de interface:

Bloco Descrição
Informações do elemento de interface
O bloco retorna o valor da propriedade de bloco especificada com o ID especificado.

Constantes predefinidas:

Constantes predefinidas são os valores possíveis de determinados parâmetros. Por exemplo, o bloco "direção" contém constantes predefinidas de possíveis direções: compra, venda, sem direção.

Bloco Descrição
Direção
Possíveis direções (comprar, venda, sem direção).
Maneira de mudar de posição
Possíveis formas de alterar a posição (entrada no mercado, saída do mercado, reversão, fechamento com a posição oposta).
Tipo de transação
Possíveis tipos de transações (compra, venda, uso de saldo, registro de ajuste, etc.)

Depuração:

Bloco Descrição
Informações de depuração
Imprime a mensagem no log do terminal.

Operadores matemáticos:
Bloco Descrição
+
Adição
-
Subtração
/
Divisão
*
Multiplicação

Raiz quadrada
^
Exponenciação
%
Restante da divisão
(
Colchete de abertura
)
Colchete de fechamento
>
Maior
<
Menor
>=
Maior ou igual
<=
Menor ou igual

Operadores lógicos:

Bloco Descrição
E
"E" lógico
OU "OU" lógico
NÃO "NÃO" lógico

Teleportes:

Os teleportes são usados quando você precisa passar para outra seção do esquema. Os teleportes para a entrada e saída são interconectados por número.
Bloco
Entrada no teleporte
Saída do teleporte

Seleção de variável ou de constante:

Bloco
Seleção de variável
Seleção de constante

Valor de entrada:

Bloco Descrição
Inserção de valor
Este bloco pode ser usado para definir determinados valores diretamente no esquema.

Tipo:

Por padrão, todos os dados são representados como um número. Com os blocos de conversão de tipo, você pode especificar explicitamente o formato no qual um determinado valor será representado.

Bloco Descrição
Strings regular
Converte o valor em uma string normal.
String em formato de data e hora
Converte o valor em formato de data e hora.
Inteiro
Converte o valor num inteiro.
Número fracionário
Converte o valor num número fracionário.


Conclusão

Mais de um mês de trabalho foi gasto no desenvolvimento deste projeto. Se você tiver alguma ideia ou comentário sobre o trabalho do editor, você pode escrever para support@botbrains.app. Sua opinião será levada em consideração.


Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/9998

Últimos Comentários | Ir para discussão (1)
Combinatória e teoria da probabilidade para negociação (Parte V): análise de curva Combinatória e teoria da probabilidade para negociação (Parte V): análise de curva
Neste artigo, explorei as possibilidades de reduzir amostras multiestado complexas a amostras simples de estado duplo. O objetivo principal é obter uma análise e umas conclusões que possam ajudar no desenvolvimento de algoritmos de negociação escaláveis baseados na teoria da probabilidade. Naturalmente, a matemática também está envolvida, mas dada a experiência de artigos anteriores, vejo que informações mais gerais são muito mais úteis do que detalhes.
Combinatória e teoria da probabilidade para negociação (Parte IV): lógica de Bernoulli Combinatória e teoria da probabilidade para negociação (Parte IV): lógica de Bernoulli
Neste artigo decidi destacar o conhecido esquema Bernoulli e mostrar como este pode ser usado ao descrever uma matriz de dados relacionados ao trading, para uso posterior no caminho à criação de um sistema de negociação auto-adaptável. Também manusearemos um algoritmo mais geral, nomeadamente a fórmula de Bernoulli e encontraremos sua aplicação.
Stop-loss fixo com base na ação do preço e RSI (stop-loss "inteligente") Stop-loss fixo com base na ação do preço e RSI (stop-loss "inteligente")
O Stop-loss é a principal ferramenta de gerenciamento de dinheiro na negociação. O uso eficaz do stop-loss, take-profit e tamanho do lote pode tornar a negociação mais consistente e, em geral, mais lucrativa. No entanto, fazer uso disto tem suas próprias dificuldades. A principal delas é a caça ao stop-loss. Neste artigo analisaremos como minimizar o efeito da caça ao stop-loss e compararemos isto com o uso clássico de stop loss para determinar lucratividade.
Indicadores múltiplos em um gráfico (Parte 02): Primeiros experimentos Indicadores múltiplos em um gráfico (Parte 02): Primeiros experimentos
No artigo anterior, múltiplos indicadores em um gráfico , apresentei os conceitos e bases para você usar múltiplos indicadores em um gráfico. Aqui irei apresentar e dissecar o código fonte.