Discussão do artigo "Criação de indicadores personalizados usando a classe CCanvas"

 

Novo artigo Criação de indicadores personalizados usando a classe CCanvas foi publicado:

O artigo descreve um exemplo de criação de indicadores personalizados usando as primitivas gráficas da classe CCanvas.

Em contraste com a indicação de arco simples, a indicação de secional visualmente parece como se nela fossem aplicadas etiquetas que dividem valores igualmente espaçados. Ao construir o esquema para um indicador deste tipo, foi decidido fazer dez seções, além da adição de um novo elemento, isto é, a borda interior. A estrutura básica de uma indicação secional de arco é mostrada na Figura 5.


Figura 5 Estrutura básica de um indicador circular com indicação secional de arco.

Autor: Alexander Fedosov

 

Agradeço ao autor pelo artigo. Tomei nota de várias soluções simples (mas ao mesmo tempo elegantes) para mim, que com certeza usarei em meus programas.

 
MetaQuotes Software Corp.:

Artigo publicado Criando indicadores personalizados usando a classe CCanvas:

Autor: Alexander Fedosov


Oh, que beleza! Vou adicioná-lo ao meu memorial ;)
 

Gostaria de chamar sua atenção mais uma vez para o fato de que, ao aplicar várias cópias do mesmo indicador implementado usando classes CustomGUI, os nomes no método Create() devem ser diferentes. Como exemplo, a implementação está abaixo.

#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//---
#include <CustomGUI\CustomGUI.mqh>
CCircleSection ind;
//+------------------------------------------------------------------+
//| Parâmetros de entrada do 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[];
//+------------------------------------------------------------------+
//| Função de inicialização do indicador personalizado
//+------------------------------------------------------------------+
int OnInit()
  {
//--- obter o identificador do 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);
  }
//+------------------------------------------------------------------+
//| Função de iteração de indicador personalizado
//+------------------------------------------------------------------+
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_calculated para a próxima chamada
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Função de desinicialização do indicador personalizado
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ind.Delete();
   ChartRedraw();
  }
//+------------------------------------------------------------------+

O método Create() tem um nome exclusivo.

Arquivos anexados:
 

Obrigado.

É possível implementar no MT4 ou MT5 a função de selecionar um objeto indicador? (por exemplo, uma linha).

Por exemplo, se você clicar duas vezes em uma linha, ela será destacada com uma linha em negrito e a descrição da linha será exibida, e vice-versa.

 
Ilmir Galiev:

Obrigado.

É possível implementar no MT4 ou MT5 a função de selecionar um objeto indicador? (por exemplo, uma linha).

Por exemplo, se você clicar duas vezes em uma linha, ela será destacada com uma linha em negrito e a descrição da linha será exibida, e vice-versa.

Não. A essência desse método é que ele é uma imagem que é redesenhada quando qualquer condição muda. Ele não reage a eventos de teclas de atalho ou de cliques do mouse.
 
Alexander Fedosov:
Não. A essência desse método é que ele é uma imagem que é redesenhada quando alguma condição muda. Ele não responde a eventos de teclas de atalho ou de cliques do mouse.

Ah, vamos lá. O que são cliques do mouse? Não são "alterar quaisquer condições". Ele gera um evento, que é usado para redesenhar a tela como deveria ser. Ilmir, a resposta correta à sua pergunta é: é claro que você pode.

 

Bom tópico. Graças ao autor, farei um indicador de tique no canvas.....

Notei o seguinte.

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CCanvasBase
  {
private:
   //--- Nome da tela
   string            m_canvas_name;
   //--- Coordenadas da tela
   int               m_x;
   int               m_y;
   //--- Tamanho da tela
   int               m_x_size;
   int               m_y_size;
protected:
   CCanvas           m_canvas;
   //--- Cria um recurso gráfico para o objeto
   bool              CreateCanvas(void);
   //--- Exclui o recurso gráfico
   bool              DeleteCanvas(void);
public:
                     CCanvasBase(void);
                    ~CCanvasBase(void);
   //--- Define e retorna 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);                }
   //--- Define e retorna dimensões
   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);           }
   //--- Define o nome do indicador na criação
   void              Name(const string canvas_name) { m_canvas_name=canvas_name;  }
  };

Há um membro de dados privado m_canvas_name, mas o método que define seu valor - Name() - é público. Na minha opinião, o princípio do encapsulamento foi violado. Vou tornar esse método privado.

 
Dennis Kirichenko:

Bom tópico. Graças ao autor, farei um indicador de tique no canvas....

Como você tem esboços, envie capturas de tela/vídeo. Eu mesmo publiquei um indicador desse tipo, mas ele não foi para as pessoas. Embora eu não tenha encontrado um melhor. É interessante ver outras soluções na tela.

 
fxsaber:

Eu mesmo publiquei um indicador desse tipo, mas ele não foi divulgado para as pessoas.

Foi, sim.

Estou até tentando criar um indicador de velocidade do tique-taque com base nele.

 
Andrey Khatimlianskii:
Vai, vai, vai.

Estou até tentando criar um indicador de taxa de tique com base nele.

Essa é uma boa notícia! Qual é a ideia? Em vez do histórico de ticks, substituir por uma série temporal personalizada?