Discusión sobre el artículo "Creando un ayudante para el comercio manual"

 

Artículo publicado Creando un ayudante para el comercio manual:

El número de robots comerciales para trabajar en los mercados de divisas está creciendo últimamente como una bola de nieve. En ellos se implementan diferentes conceptos y estrategias, pero nadie ha conseguido hasta el momento crear una muestra perfecta de inteligencia artificial que nunca tenga pérdidas. Por eso, muchos tráders se mantienen fieles al comercio manual. Precisamente para esos especialistas se crean los ayudantes robotizados, los llamados paneles comerciales. Este artículo es otro ejemplo más de la creación de un panel comercial partiendo "desde cero".

Tomemos una hoja de papel limpia y dibujemos nuestro futuro panel, colocando en él todos los elementos necesarios.

Al pensar en el diseño del futuro panel comercial, es necesario reflexionar sobre la practicidad de su uso. En primer lugar, deberá ser lo suficientemente informativo, a la vez que fácil de leer, y por supuesto se deberá evitar la sobrecarga con elementos prescindibles. Deberemos recordar siempre que se trata de un instrumento real para el trabajo del tráder, y no simplemente una imagen bonita en la pantalla.

Esta es mi variante.

Maket 

Autor: Dmitriy Gizlyk

 

Paneles similares se han publicado en este sitio durante mucho tiempo. No hay uso en comparación con el estándar.

En cuanto a las ideas.

1) Botón de invertir orden pendiente detrás del stop-loss.

2) Botón de inversión de posición.

3) Botón de posición Trall

4) Botón de orden inversa Martingale

5) Botón de Take Profit 3 a 1 o personalizable.

Ajuste mínimo estándar.

 
Ilya Vasenin:

Paneles similares se han publicado en este sitio durante mucho tiempo. No hay uso en comparación con el estándar.

En cuanto a las ideas.

1) Botón de invertir orden pendiente detrás del stop-loss.

2) Botón de inversión de posición.

3) Botón de posición Trall

4) Botón de orden inversa Martingala

5) Botón de Take Profit 3 a 1 o personalizable.

Estándar mínimo establecido.

Sí, hay un montón de paneles de negociación en el Mercado. También hay muchos trabajos diferentes en Freelance para crear paneles de trading. Usted, como cualquier otra persona, puede utilizar este panel ya hecho de forma gratuita. Pero esto es un artículo, no un producto del Mercado. Y el propósito del artículo no es dar un producto listo para usar, sino mostrar a todos y enseñar a aquellos que quieran aprender cómo cada uno puede crear su propio panel de negociación individual, de acuerdo a sus propias necesidades.
 
El Balance y el Patrimonio de la cuenta se muestran en la parte inferior del panel, que duplica la pestaña "Herramientas" del terminal. En su lugar, propongo mostrar en este lugar cuántas operaciones se han realizado en el día actual, cuál es su resultado y, en el futuro, hacer que cuando se alcance el número especificado de operaciones o la pérdida especificada para el día, el terminal se apague.
 
Dmitriy Gizlyk:
Y el propósito de este artículo no es dar un producto ya hecho para su uso, sino mostrar y enseñar a todos cómo cada uno puede crear su propio panel de negociación individual, de acuerdo a sus propias necesidades.

Dmitry, hoy he empezado a crear un panel en µl 4 siguiendo tu tutorial. Casi todo funciona, pero cuando hago clic en el panel o en cualquier botón sólo se abre comprar. ¿Cuál podría ser la razón?

//+------------------------------------------------------------------+
//|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;                      // Mostrar etiqueta " Lotes"
   CEdit             Lots;                            // Mostrar volumen del siguiente pedido
   CButton           SELL,BUY;                        // Botones de compra y venta
   CButton           CloseAll;                        // Botones de cierre

   //--- Crear objeto Etiqueta
   bool              CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align);
   //--- Crear botón
   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);
   //--- Crear 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);

   //--- Funciones On Event
   void              LotsEndEdit(void);               // Editar tamaño del lote

   //--- variables de valores actuales
   double            cur_lot;                         // Lote del siguiente pedido

   void              BuyClick();                      // Haga clic en el botón COMPRAR
   void              SellClick();                     // Pulse el botón VENDER
   void              CloseClick();                    // Pulse el botón CERRAR 

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;
//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
// Crear panel de comercio
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización experta|
//+------------------------------------------------------------------+
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 los objetos deben tener un nombre separado
   string name=m_name+"Label"+(string)ObjectsTotal(chart,-1,OBJ_LABEL);
//--- Llamar a la función Crear
   if(!object.Create(chart,name,subwindow,x,y,0,0))
     {
      return false;
     }
//--- Ajustar texto
   if(!object.Text(text))
     {
      return false;
     }
//--- Alinear el texto a la rejilla del cuadro de diálogo
   ObjectSetInteger(chart,object.Name(),OBJPROP_ANCHOR,(align==left ? ANCHOR_LEFT_UPPER :(align==right ? ANCHOR_RIGHT_UPPER : ANCHOR_UPPER)));
//--- Añadir objeto a los 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 los objetos deben tener un nombre separado
   string name=m_name+"Button"+(string)ObjectsTotal(chart,-1,OBJ_BUTTON);
//--- Llamar a la función Crear
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Ajustar texto
   if(!object.Text(text))
     {
      return false;
     }
//--- fijar la bandera del botón para desbloquear
   object.Locking(false);
//--- poner el botón como no pulsado
   if(!object.Pressed(false))
     {
      return false;
     }
//--- Añadir objeto a los 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 los objetos deben tener un nombre separado
   string name=m_name+"Edit"+(string)ObjectsTotal(chart,-1,OBJ_EDIT);
//--- Llamar a la función Crear
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Ajustar texto
   if(!object.Text(text))
     {
      return false;
     }
//--- Alinear texto en el cuadro de edición
   if(!object.TextAlign(ALIGN_CENTER))
     {
      return false;
     }
//--- establecer la bandera de sólo lectura a false
   if(!object.ReadOnly(false))
     {
      return false;
     }
//--- Añadir objeto a los 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)
  {
// En la primera llamada crear función de la clase padres
   CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2);

// Calcular coordenadas y tamaño del objeto BID

// Crear 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);
  }
//+------------------------------------------------------------------+
//| Manejo 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)
//+------------------------------------------------------------------+
//| Haga clic en el botón COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::BuyClick(void)
  {
   PutOrder(0,Ask);
  }
//+------------------------------------------------------------------+
//| Haga clic en el botón COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::SellClick(void)
  {
   PutOrder(1,Bid);
  }
//+------------------------------------------------------------------+
//| Haga clic en el botón COMPRAR|
//+------------------------------------------------------------------+
void CTradePanel::CloseClick(void)
  {
   CloseAll();
  }
//+------------------------------------------------------------------+
//| Leer el valor del lote después de la edición|
//+------------------------------------------------------------------+
void CTradePanel::LotsEndEdit(void)
  {
//--- Leer y normalizar el valor del lote
   cur_lot=NormalizeDouble(StringToDouble(Lots.Text()),2);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización de la aplicación.
//+------------------------------------------------------------------+
void CTradePanel::Destroy(const int reason)
  {
   CAppDialog::Destroy(reason);
   return;
  }
//+------------------------------------------------------------------+
//| Establecer una orden|
//+------------------------------------------------------------------+
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;
  }
//+------------------------------------------------------------------+
//| Cerrar una posición por tipo de orden|
//+------------------------------------------------------------------+
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);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Función tick experto|
//+------------------------------------------------------------------+
void OnTick()
  {
//---

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

Dmitry, hoy he empezado a hacer un panel en µl 4 siguiendo tu tutorial. Casi todo funciona, pero al hacer clic en el panel o en cualquier botón sólo se abre comprar. ¿Cuál podría ser la razón?

Buenas noches, Andrew.
Has hecho todo correctamente en la descripción de la clase. Tu único error es que en la función OnInit después de crear la clase panel de negociación no has iniciado su ejecución con la función Run.

int OnInit()
  {
//---
// Crear panel de comercio
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
   TradePanel.Run();
//---
   return(INIT_SUCCEEDED);
  }

Saludos,

Dmitry.

 
Dmitriy Gizlyk:

Buenas noches, Andrey.
Has hecho todo correctamente en la descripción de la clase. Tu único error es que en la función OnInit después de crear la clase del panel de operaciones no has iniciado su ejecución con la función Run.

Saludos,

Dmitry.

¡Gracias, Dmitry!
¡Funcionó!
 
He descargado su panel de comercio a metatrader, pero no funciona. Es una lástima.
 
19681:
He descargado su panel de comercio a metatrader, pero no funciona. Es una pena.
¿Cómo se manifiesta?
Para que el panel funcione, así como cualquier otro programa de trading, es necesario activar el auto trading en el terminal.
 
Dmitriy Gizlyk:
¿En qué se manifiesta?
Para que el panel funcione, como cualquier otro programa de trading, es necesario activar el auto-trading en el terminal.
Por supuesto, el auto-trading está activado. Y se manifiesta en que los botones no funcionan (al pulsar sobre vender o comprar aparece "error de orden de compra abierta").
 
19681:
El autotrading está por supuesto activado. Y se manifiesta en que los botones no funcionan (al pulsar sobre vender o comprar aparece "error de orden de compra abierta").
Compruebe si el comercio en el símbolo se permite en absoluto? Debido a los últimos acontecimientos (Brexit) algunos brokers han restringido temporalmente las operaciones de trading