Discusión sobre el artículo "Creación de indicadores personalizados usando la clase CCanvas"

 

Artículo publicado Creación de indicadores personalizados usando la clase CCanvas:

En el artículo se analiza un ejemplo de creación de indicadores de dibujado personalizados con la ayuda de primivitas gráficas de la clase CCanvas.

A diferencia de la indicación en arco simple, la de sección visualmente parece como si tuviese marcas que separasen intervalos iguales de los valores. Al construir la maqueta de este tipo de indicador hemos decidido hacer diez secciones, además, vamos a añadir un nuevo elemento: el marco interior. La estructura básica con indicación en arco con secciones se muestra en la fig.5.


Fig.5 Estructura básica del indicador circular con indicación en arco con secciones.

Autor: Alexander Fedosov

 

Gracias al autor por el artículo. He tomado nota de un montón de soluciones sencillas (pero al mismo tiempo elegantes) para mí, que sin duda utilizaré en mis programas.

 

Oh, ¡qué belleza! Lo añado a mi memorial ;)
 

Me gustaría llamar su atención una vez más sobre el hecho de que cuando se aplican varias copias del mismo indicador implementado utilizando clases CustomGUI, los nombres en el método Create() deben ser diferentes. Como ejemplo, la implementación es la siguiente.

#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//---
#include <CustomGUI\CustomGUI.mqh>
CCircleSection ind;
//+------------------------------------------------------------------+
//| Parámetros de entrada del indicador|
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES   tf=PERIOD_CURRENT;
input int               period=10;
input int               indsize=50;
input ENUM_ORIENTATION  orient=VERTICAL;
input int               X=100;
input int               Y=100;
//---
int      IndHandle;
double   rsi[];
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizada |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- obtener indicador
   IndHandle=iRSI(Symbol(),tf,period,PRICE_CLOSE);
   if(IndHandle==INVALID_HANDLE)
     {
      Print("Failed to get indicator handle");
      return(INIT_FAILED);
     }
   ArraySetAsSeries(rsi,true);
//---
   ind.Radius(indsize);
   ind.LabelSize(15);
   ind.LabelValue("RSI "+"("+IntegerToString(period)+")");
   ind.Orientation(orient);
   ind.Create("rsi_custom"+IntegerToString(MathRand()),X,Y);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizada |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(CopyBuffer(IndHandle,0,0,1,rsi)<1)
      return(0);
   ind.NewValue(rsi[0]);
//--- valor de retorno de prev_calculado para la siguiente llamada
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Función personalizada de desinicialización del indicador ||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ind.Delete();
   ChartRedraw();
  }
//+------------------------------------------------------------------+

El método Create( ) tiene un nombre único.

Archivos adjuntos:
 

gracias.

¿es posible implementar en MT4 o MT5 la función de seleccionar un objeto indicador? (por ejemplo, una línea).

Por ejemplo, hacer doble clic en una línea y se resalta con una línea en negrita, aparece la descripción de la línea, y viceversa.

 
Ilmir Galiev:

gracias.

¿es posible implementar en MT4 o MT5 la función de seleccionar un objeto indicador? (por ejemplo, una línea).

Por ejemplo, al hacer doble clic en una línea, se resalta con una línea en negrita, aparece la descripción de la línea, y viceversa.

No. La esencia de este método es que se trata de una imagen que se vuelve a dibujar cuando cambia alguna condición. No reacciona a los eventos de teclas de acceso rápido o clics del ratón.
 
Alexander Fedosov:
No. La esencia de este método es que es una imagen que se redibuja cuando cambia alguna condición. No responde a eventos de teclas de acceso rápido o clics del ratón.

Vamos. ¿Qué son los clics del ratón? No es "cambiar cualquier condición". Genera un evento, que se utiliza para redibujar el lienzo como debe ser. Ilmir, la respuesta correcta a tu pregunta es por supuesto que puedes.

 

Buen tema. Gracias al autor, va a hacer un indicador de garrapatas en canvas.....

Me di cuenta de esto.

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CCanvasBase
  {
private:
   //--- Nombre del lienzo
   string            m_canvas_name;
   //--- Coordenadas del lienzo
   int               m_x;
   int               m_y;
   //--- Tamaño del lienzo
   int               m_x_size;
   int               m_y_size;
protected:
   CCanvas           m_canvas;
   //--- Crea un recurso gráfico para el objeto
   bool              CreateCanvas(void);
   //--- Borra el recurso gráfico
   bool              DeleteCanvas(void);
public:
                     CCanvasBase(void);
                    ~CCanvasBase(void);
   //--- Establece y devuelve coordenadas
   void              X(const int x)                         { m_x=x;                      }
   void              Y(const int y)                         { m_y=y;                      }
   int               X(void)                                { return(m_x);                }
   int               Y(void)                                { return(m_y);                }
   //--- Establece y devuelve dimensiones
   void              XSize(const int x_size)                { m_x_size=x_size;            }
   void              YSize(const int y_size)                { m_y_size=y_size;            }
   int               XSize(void)                            { return(m_x_size);           }
   int               YSize(void)                            { return(m_y_size);           }
   //--- Establece el nombre del indicador en la creación
   void              Name(const string canvas_name) { m_canvas_name=canvas_name;  }
  };

Hay un miembro de datos privado m_canvas_name, pero el método que establece su valor - Name() - es público. Imho, el principio de encapsulación se viola. Voy a hacer este método privado.

 
Dennis Kirichenko:

Buen tema. Gracias al autor, va a hacer un indicador de garrapatas en canvas....

Como usted tiene bocetos, por favor enviar capturas de pantalla / vídeo. Yo mismo he publicado un indicador de este tipo, pero no fue a la gente. Aunque no he encontrado uno mejor. Es interesante ver otras soluciones en el lienzo.

 
fxsaber:

Yo mismo publiqué un indicador de este tipo, pero no llegó a la gente.

Lo hizo, lo hizo.

Incluso estoy tratando de hacer un indicador de velocidad basado en él.

 
Andrey Khatimlianskii:
Vamos, vamos, vamos.

Incluso estoy tratando de hacer un indicador de la tasa de garrapatas basado en él.

¡Qué buena noticia! ¿Cuál es la idea? ¿En lugar del historial de ticks sustituirlo por una serie temporal personalizada?