Discussão do artigo "Criamos um auxiliar na negociação manual"

 

Novo artigo Criamos um auxiliar na negociação manual foi publicado:

O número de robôs de negociação para trabalhar nos mercados de moedas ultimamente está crescendo como uma bola de neve. Neles estão compilados diversos conceitos e estratégias, mas vale a pena referir que ainda ninguém conseguiu criar um modelo de inteligência artificial que não esteja submetido a ricos de perda. Por isso, muitos traders continuam empenhados em negociar manualmente. E para esses especialistas são criados assistentes robóticos, chamados de painéis de negociação. Esse artigo é outro exemplo de como criar um painel de negociação "do zero".

Pegamos uma folha de papel em branco e desenhamos o nosso futuro painel de negociação, colocando nele todos os elementos necessários.

Ao projetar o desenho do futuro painel de negociação, temos que pensar sobre a praticidade da sua aplicação. Em primeiro lugar, ele deve ser bastante informativo, fácil de ler e não estar sobrecarregado com elementos desnecessários. Devemos sempre lembrar que é uma ferramenta para um trader real trabalhar, e não apenas uma imagem bonita na tela.

Aqui está a minha versão.

Desenho

Autor: Dmitriy Gizlyk

 

Painéis semelhantes foram postados neste site há muito tempo. Não há utilidade em comparação com o padrão.

Quanto às ideias.

1) Botão de reversão de ordem pendente atrás do stop-loss.

2) Botão de reversão de posição com um botão.

3) Botão de Trall de posição

4) Botão de ordem inversa de Martingale

5) Botão Take Profit 3 a 1 ou personalizável.

Conjunto padrão mínimo.

 
Ilya Vasenin:

Painéis semelhantes foram postados neste site há muito tempo. Não há utilidade em comparação com o padrão.

Quanto às ideias.

1) Botão de reversão de ordem pendente atrás do stop-loss.

2) Botão de reversão de posição com um botão.

3) Botão de Trall de posição

4) Botão de ordem inversa de Martingale

5) Botão Take Profit 3 a 1 ou personalizável.

Padrão mínimo definido.

Sim, há muitos painéis de negociação no Marketplace. Há muitos trabalhos diferentes no Freelance para criar painéis de negociação também. Você, como qualquer outra pessoa, pode usar esse painel pronto gratuitamente. Mas este é um artigo, não um produto do Marketplace. E o objetivo do artigo não é fornecer um produto pronto para uso, mas mostrar a todos e ensinar àqueles que querem aprender como cada um pode criar seu próprio painel de negociação individual, de acordo com suas próprias necessidades.
 
O saldo e o patrimônio líquido da conta são exibidos na parte inferior do painel, o que duplica a guia "Tools" (Ferramentas) do terminal. Em vez disso, proponho mostrar nesse local quantos negócios foram feitos no dia atual, qual é o resultado deles e, no futuro, fazer com que, quando o número especificado de negócios ou a perda especificada para o dia for atingida, o terminal será desligado.
 
Dmitriy Gizlyk:
E o objetivo deste artigo não é fornecer um produto pronto para uso, mas mostrar e ensinar a todos como cada um pode criar seu próprio painel de negociação individual, de acordo com seus próprios requisitos.

Dmitry, hoje comecei a criar um painel no µl 4 de acordo com seu tutorial. Quase tudo funciona, mas quando clico no painel ou em qualquer botão, ele abre apenas a compra. Qual poderia ser o motivo?

//+------------------------------------------------------------------+
//|TradePanel.mq4
//| Copyright 2015, MetaQuotes Software Corp.
//| https://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Button.mqh>

//--- Entradas
extern double Lot        = 0.1;      // lote
extern int StopLoss      = 500;      // alce
extern int TakeProfit    = 500;      // yazi
extern int Slip          = 30;       // requotes
extern int Magic         = 0;        // magik
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
enum label_align
  {
   left=-1,
   right=1,
   center=0
  };
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CTradePanel : public CAppDialog
  {
private:

   CLabel            Lots_label;                      // Exibir o rótulo " Lotes"
   CEdit             Lots;                            // Exibir o volume do próximo pedido
   CButton           SELL,BUY;                        // Botões de compra e venda
   CButton           CloseAll;                        // Botões de fechamento

   //--- Criar objeto Label
   bool              CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align);
   //--- Criar botão
   bool              CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size);
   //--- Criar objeto Edit
   bool              CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size);

   //--- Em funções de evento
   void              LotsEndEdit(void);               // Editar tamanho do lote

   //--- variáveis de valores atuais
   double            cur_lot;                         // Lote do próximo pedido

   void              BuyClick();                      // Clique no botão COMPRAR
   void              SellClick();                     // Clique no botão VENDER
   void              CloseClick();                    // Clique no botão FECHAR 

public:
                     CTradePanel(void){};
                    ~CTradePanel(void){};
   virtual bool      Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420);
   virtual bool      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   virtual void      Destroy(const int reason);
  };

CTradePanel TradePanel;
//+------------------------------------------------------------------+
//| Função de inicialização de especialista|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
// Criar painel de comércio
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Função de desinicialização de especialista|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   TradePanel.Destroy(reason);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align)
  {
// Todos os objetos devem ter um nome separado
   string name=m_name+"Label"+(string)ObjectsTotal(chart,-1,OBJ_LABEL);
//--- Chamar a função Create
   if(!object.Create(chart,name,subwindow,x,y,0,0))
     {
      return false;
     }
//--- Ajustar o texto
   if(!object.Text(text))
     {
      return false;
     }
//--- Alinhar o texto à grade da caixa de diálogo
   ObjectSetInteger(chart,object.Name(),OBJPROP_ANCHOR,(align==left ? ANCHOR_LEFT_UPPER :(align==right ? ANCHOR_RIGHT_UPPER : ANCHOR_UPPER)));
//--- Adicionar objeto aos controles
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size)
  {
// Todos os objetos devem ter um nome separado
   string name=m_name+"Button"+(string)ObjectsTotal(chart,-1,OBJ_BUTTON);
//--- Chamar a função Create
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Ajustar o texto
   if(!object.Text(text))
     {
      return false;
     }
//--- definir o sinalizador do botão para desbloquear
   object.Locking(false);
//--- definir o sinalizador do botão como não pressionado
   if(!object.Pressed(false))
     {
      return false;
     }
//--- Adicionar objeto aos controles
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size)
  {
// Todos os objetos devem ter um nome separado
   string name=m_name+"Edit"+(string)ObjectsTotal(chart,-1,OBJ_EDIT);
//--- Chamar a função Create
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Ajustar o texto
   if(!object.Text(text))
     {
      return false;
     }
//--- Alinhar texto na caixa de edição
   if(!object.TextAlign(ALIGN_CENTER))
     {
      return false;
     }
//--- definir o sinalizador Somente leitura como falso
   if(!object.ReadOnly(false))
     {
      return false;
     }
//--- Adicionar objeto aos controles
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420)
  {
// Na primeira chamada, crie a função da classe dos pais
   CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2);

// Calcular coordenadas e tamanho do objeto BID

// Criar objeto
   CreateLabel(chart,subwin,Lots_label,"LOT",55,5,0);
   CreateEdit(chart,subwin,Lots,"0.1",33,35,60,20);
   CreateButton(chart,subwin,BUY,"BUY",33,65,60,20);
   CreateButton(chart,subwin,SELL,"SELL",33,95,60,20);
   CreateButton(chart,subwin,CloseAll,"CLOSE",33,125,60,20);

   return(true);
  }
//+------------------------------------------------------------------+
//| Tratamento de eventos|
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CTradePanel)
ON_EVENT(ON_END_EDIT,Lots,LotsEndEdit)
ON_EVENT(ON_CLICK,BUY,BuyClick)
ON_EVENT(ON_CLICK,SELL,SellClick)
ON_EVENT(ON_CLICK,CloseAll,CloseClick)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Clique no botão COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::BuyClick(void)
  {
   PutOrder(0,Ask);
  }
//+------------------------------------------------------------------+
//| Clique no botão COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::SellClick(void)
  {
   PutOrder(1,Bid);
  }
//+------------------------------------------------------------------+
//| Clique no botão COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::CloseClick(void)
  {
   CloseAll();
  }
//+------------------------------------------------------------------+
//| Ler o valor dos lotes após a edição|
//+------------------------------------------------------------------+
void CTradePanel::LotsEndEdit(void)
  {
//--- Ler e normalizar o valor do lote
   cur_lot=NormalizeDouble(StringToDouble(Lots.Text()),2);
  }
//+------------------------------------------------------------------+
//| Função de desinicialização do aplicativo
//+------------------------------------------------------------------+
void CTradePanel::Destroy(const int reason)
  {
   CAppDialog::Destroy(reason);
   return;
  }
//+------------------------------------------------------------------+
//| Definição de um pedido|
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0)   sl=NormalizeDouble(price+StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0)   sl=NormalizeDouble(price-StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   r=OrderSend(NULL,type,Lot,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
   return;
  }
//+------------------------------------------------------------------+
//| Fechamento de uma posição por tipo de ordem|
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Função de tique de especialista|
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Função ChartEvent|
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   TradePanel.OnEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+
 
Andrew Kornishkin:

Dmitry, hoje comecei a criar um painel no µl 4 de acordo com seu tutorial. Quase tudo funciona, mas ao clicar no painel ou em qualquer botão, ele abre apenas a compra. Qual poderia ser o motivo?

Boa noite, Andrew.
Você fez tudo corretamente na descrição da aula. Seu único erro é que na função OnInit, após criar a classe do painel de negociação, você não iniciou sua execução com a função Run.

int OnInit()
  {
//---
// Criar painel de comércio
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
   TradePanel.Run();
//---
   return(INIT_SUCCEEDED);
  }

Atenciosamente,

Dmitry.

 
Dmitriy Gizlyk:

Boa noite, Andrey.
Você fez tudo corretamente na descrição da classe. Seu único erro é que na função OnInit, após criar a classe do painel de negociação, você não iniciou sua execução com a função Run.

Atenciosamente,

Dmitry.

Obrigado, Dmitry!
Funcionou!
 
Baixei seu painel de negociação para o Metatrader, mas ele não funciona. Isso é muito ruim.
 
19681:
Baixei seu painel de negociação para o Metatrader, mas ele não funciona. É uma pena.
Como isso se manifesta?
Para que o painel funcione, assim como qualquer outro programa de negociação, é necessário ativar a negociação automática no terminal.
 
Dmitriy Gizlyk:
Em que isso se manifesta?
Para que o painel funcione, como qualquer outro programa de negociação, é necessário ativar a negociação automática no terminal.
É claro que a negociação automática está ativada. E isso se manifesta no fato de que os botões não funcionam (quando você clica em vender ou comprar, recebe a mensagem "error of open BUY ORDER").
 
19681:
É claro que a negociação automática está ativada. E isso se manifesta no fato de que os botões não funcionam (quando você clica em vender ou comprar, aparece "error of open BUY ORDER").
Verificar se a negociação no símbolo é permitida? Devido a eventos recentes (Brexit), algumas corretoras restringiram temporariamente as operações de negociação