Desculpe-me, por acaso estou distraindo-o de escrever outro tutorial ou receita?
Se não, vamos continuar discutindo seu artigo sobre controle na subjanela do indicador. Então, você oferece uma solução em massa (ou uma ideia) de como criar um menu conveniente em um indicador. Ótimo, o objetivo do artigo é muito válido! Mas como um programador "iniciante" pode usar todo esse arsenal? Onde colocar as funções personalizadas? Demonstre-o com um exemplo. E, ao mesmo tempo, explique o que você precisa corrigir no código para usar, por exemplo, 5 botões? Considere essa pergunta como de um iniciante.
Não, não é. Ainda não estou escrevendo nada. Tenho que descansar pelo menos um dia por ano. Apenas descansar não é interessante, especialmente por um longo período. )
Não é uma decisão em massa e eu não escrevi sobre isso. Não vamos atribuir algo que não aconteceu. Já foi dito no início da discussão que essa não é uma solução universal, mas um caso especial. Na minha opinião, é um bom exemplo para um iniciante praticar. E não para obter uma solução pronta de graça e correr, com a boca aberta em um sorriso largo, para encontrar o sol. ) Está entendendo? Eu gostaria de ter um exemplo tão simples e claro logo no início do aprendizado de programação. Especialmente quando essa é a primeira linguagem de programação de sua vida e, antes disso, toda a atividade de sua vida foi em um campo completamente diferente, de forma alguma relacionado a ela.
Para criar 5 botões, nesse caso, precisamos alterar o tamanho das matrizes e excluir elementos desnecessários ao declarar matrizes para os nomes dos objetos-botões, texto exibido nos botões e estados dos botões.
Há uma matriz de estados de botões, portanto, o mesmo princípio pode ser usado para verificar qual botão foi pressionado e, em vez de apenas alterar a cor do botão, executar alguma outra ação (exigida pelo usuário). Isso pode ser, por exemplo, funções de negociação (e não apenas): excluir todas as ordens pendentes, fechar todas as posições etc. As ideias são infinitas. E se não houver ideias, então você escolheu o tipo errado de atividade. )
Para implementar isso, você precisa criar outra matriz, que será inicializada com identificadores de uma enumeração personalizada (que também precisa ser criada), por exemplo, com o nome ENUM_SCRIPT. E os identificadores serão chamados, por exemplo: SCRIPT_01 =0, SCRIPT_02 =2, etc. Também no loop, ao verificar se o botão no painel está pressionado, você precisará determinar qual identificador está vinculado ao botão pressionado e o estado atual do botão e, em seguida, passar a função correspondente ao programa para execução.
Não mostrarei um exemplo de código propositalmente. Que seja um dever de casa para iniciantes. )
#define BUTTON_COLUMNS 5// Número de botões por largura#define BUTTON_ROWS 1// Número de botões por altura
...
//--- Texto exibido nos botõesstring button_texts[BUTTON_ROWS][BUTTON_COLUMNS]=
{
{"Button 01","Button 02","Button 03","Button 04","Button 05"}
};
//--- Nomes de objetosstring button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]=
{
{"button_01","button_02","button_03","button_04","button_05"}
};
...
//--- Estados do botãobool button_states[BUTTON_ROWS][BUTTON_COLUMNS]=
{
{true,false,false,false,false}
};
Mas não entendo como conectar minhas funções aos botões. Mostre-me um exemplo.
Bem, vamos continuar o jogo de "iniciante" iniciado por você. )
Em que ponto você está travado? Mostre uma tentativa de como você entendeu o ponto atual. Crie uma enumeração com cinco identificadores e uma matriz cujos elementos precisam ser atribuídos a esses identificadores.
//--- Rastreamento de cliques do botão esquerdo do mouse em um objeto gráficoif(id==CHARTEVENT_OBJECT_CLICK)
{
//--- Se você clicar no botãoif(InitializeButtonStates(sparam))
{
//--- Definir as cores dos botões
ChangeButtonColorOnClick();
//--- Executar o scriptScriptOn();
}
//--- Atualizar o gráficoChartRedraw();
return;
}
E então você pode pensar em como otimizar o código, se necessário. :)
O programa que tem o rastreamento ativado na inicialização o desativa ao descarregar. E o programa que permanece no gráfico e precisa de rastreamento verifica se ele está ativado e, se estiver desativado, ele o ativa.
Não há necessidade de verificar constantemente se alguém desativou o rastreamento de eventos do mouse. Para ser mais preciso, se quiser se proteger de qualquer situação, você pode verificar, mas acho que isso é demais.
Talvez devêssemos sugerir aos desenvolvedores que gerem CHARTEVENT_CHART_CHANGE quando CHART_EVENT_MOUSE_MOVE for alterado? Assim, seria possível restaurar com elegância a configuração necessária quando o Expert Advisor estiver em execução.
Até o momento, tenho essa variante:
#property copyright"Copyright 2013, komposter"#property link"http://www.komposter.me/"#property version"1.00"#property indicator_chart_windowinputbool EnableMouseDetect = false; // verdadeiro - funciona com o rastreamento do mouse, falso - sem elebool PrevState = false;
//+------------------------------------------------------------------+//| Função de inicialização do indicador personalizado//+------------------------------------------------------------------+intOnInit()
{
if ( EnableMouseDetect )
{
//--- Obter o estado atual
PrevState = (bool)ChartGetInteger(0,CHART_EVENT_MOUSE_MOVE);
//--- Ativar o rastreamento de eventos do mouseif ( PrevState == false ) ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
}
return(0);
}
//+------------------------------------------------------------------+//| Função de desinicialização do especialista//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
if ( EnableMouseDetect )
{
//--- Desativar o rastreamento de eventos do mouseif ( PrevState == false )
{
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
ChartRedraw(); // Sem essa linha, o rastreamento é desativado somente quando um tique chega. É assim que ele foi projetado?
}
}
}
//+------------------------------------------------------------------+//| OnTick|//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime& time[],
constdouble& open[],
constdouble& high[],
constdouble& low[],
constdouble& close[],
constlong& tick_volume[],
constlong& volume[],
constint& spread[])
{
return(rates_total);
}
//+------------------------------------------------------------------+//| Função ChartEvent|//+------------------------------------------------------------------+voidOnChartEvent(constint id,
constlong &lparam,
constdouble &dparam,
conststring &sparam)
{
//--- Rastreamento do movimento do mouse e pressionamento do botão esquerdo do mouseif(id==CHARTEVENT_MOUSE_MOVE)
{
staticint count=1;
Print("CHARTEVENT_MOUSE_MOVE; EXPERT; ",count);
count++;
}
}
//+------------------------------------------------------------------+
Criei um indicador, mas com um parâmetro: executar com EnableMouseDetect = true - controla o rastreamento, false - apenas imprime o número de eventos, se o rastreamento estiver ativado.
------------------ Agora pensei um pouco mais e tenho que concordar: essa opção não funcionará. Se você executar primeiro um programa que rastreia o mouse (ele ativará o rastreamento), depois o segundo (ele verá o que já está ativado) e, em seguida, excluir o primeiro, ele desativará o rastreamento e o segundo ficará sem nada. Ou seja, precisamos criar algum tipo de semáforo para sinalizar que o rastreamento é necessário.
E, à luz da pesquisa realizada aqui (sobre a carga no processador), essas muletas não são necessárias.
Portanto, proponho que minha proposta seja votada pelos desenvolvedores, e o tópico pode ser encerrado.
ChartRedraw(); // Sem essa linha, o rastreamento é desativado somente quando um tique chega. É assim que ele foi projetado?
O MT5 tem atualização assíncrona das propriedades do gráfico. Ou seja, o fato de definirmos uma propriedade não significa que o terminal a tenha captado imediatamente. A função ChartRedraw() é usada para que todas as propriedades sejam lidas novamente pelo terminal. Você também pode usar a função ChartGet... ObjectGet; nesse caso, as propriedades também serão lidas novamente.
Tem certeza de que seu artigo é perfeito?
Estou muito satisfeito por você tê-lo lido.
Terei prazer em responder a todas as perguntas no tópico apropriado.
===
Para que não haja equívocos desnecessários, não tenho nada contra Anatoly! Parabéns a ele pelo artigo! Mas é necessário responder às perguntas...
Desculpe-me, por acaso estou distraindo-o de escrever outro tutorial ou receita?
Se não, vamos continuar discutindo seu artigo sobre controle na subjanela do indicador. Então, você oferece uma solução em massa (ou uma ideia) de como criar um menu conveniente em um indicador. Ótimo, o objetivo do artigo é muito válido! Mas como um programador "iniciante" pode usar todo esse arsenal? Onde colocar as funções personalizadas? Demonstre-o com um exemplo. E, ao mesmo tempo, explique o que você precisa corrigir no código para usar, por exemplo, 5 botões? Considere essa pergunta como de um iniciante.
Não, não é. Ainda não estou escrevendo nada. Tenho que descansar pelo menos um dia por ano. Apenas descansar não é interessante, especialmente por um longo período. )
Não é uma decisão em massa e eu não escrevi sobre isso. Não vamos atribuir algo que não aconteceu. Já foi dito no início da discussão que essa não é uma solução universal, mas um caso especial. Na minha opinião, é um bom exemplo para um iniciante praticar. E não para obter uma solução pronta de graça e correr, com a boca aberta em um sorriso largo, para encontrar o sol. ) Está entendendo? Eu gostaria de ter um exemplo tão simples e claro logo no início do aprendizado de programação. Especialmente quando essa é a primeira linguagem de programação de sua vida e, antes disso, toda a atividade de sua vida foi em um campo completamente diferente, de forma alguma relacionado a ela.
Para criar 5 botões, nesse caso, precisamos alterar o tamanho das matrizes e excluir elementos desnecessários ao declarar matrizes para os nomes dos objetos-botões, texto exibido nos botões e estados dos botões.
Há uma matriz de estados de botões, portanto, o mesmo princípio pode ser usado para verificar qual botão foi pressionado e, em vez de apenas alterar a cor do botão, executar alguma outra ação (exigida pelo usuário). Isso pode ser, por exemplo, funções de negociação (e não apenas): excluir todas as ordens pendentes, fechar todas as posições etc. As ideias são infinitas. E se não houver ideias, então você escolheu o tipo errado de atividade. )
Para implementar isso, você precisa criar outra matriz, que será inicializada com identificadores de uma enumeração personalizada (que também precisa ser criada), por exemplo, com o nome ENUM_SCRIPT. E os identificadores serão chamados, por exemplo: SCRIPT_01 =0, SCRIPT_02 =2, etc. Também no loop, ao verificar se o botão no painel está pressionado, você precisará determinar qual identificador está vinculado ao botão pressionado e o estado atual do botão e, em seguida, passar a função correspondente ao programa para execução.
Não mostrarei um exemplo de código propositalmente. Que seja um dever de casa para iniciantes. )
Fiz as alterações como você disse:
E foi isso que obtive na tela:
Como faço para corrigir isso? (Sou iniciante)
Fiz as alterações como você disse:
E foi isso que obtive na tela:
Como faço para corrigir isso? (Sou iniciante)
Assim:
Que ótimo! Funciona.
Mas não entendo como conectar minhas funções aos botões. Mostre-me um exemplo.
Que ótimo! Funciona.
Mas não entendo como conectar minhas funções aos botões. Mostre-me um exemplo.
Bem, vamos continuar o jogo de "iniciante" iniciado por você. )
Em que ponto você está travado? Mostre uma tentativa de como você entendeu o ponto atual. Crie uma enumeração com cinco identificadores e uma matriz cujos elementos precisam ser atribuídos a esses identificadores.
Então, o que faremos a seguir?
Então, o que faremos a seguir?
Esse é o tipo de matriz de que você precisa:
//--- Scripts ENUM_SCRIPT buttons_scripts[NUMBER_BUTTONS_HEIGHT][NUMBER_BUTTONS_WIDTH]= { {SCRIPT_01,SCRIPT_02,SCRIPT_03,SCRIPT_04,SCRIPT_05} };Então, você precisa escrever uma função como esta:
...e colocar essa função nessa parte do código:
E então você pode pensar em como otimizar o código, se necessário. :)
É assim que eu faço.
O programa que tem o rastreamento ativado na inicialização o desativa ao descarregar. E o programa que permanece no gráfico e precisa de rastreamento verifica se ele está ativado e, se estiver desativado, ele o ativa.
É desejável dar sua variante nos exemplos de Expert Advisor e código de indicador da minha postagem na página anterior para excluir a ambiguidade das declarações.
Não há necessidade de verificar constantemente se alguém desativou o rastreamento de eventos do mouse. Para ser mais preciso, se quiser se proteger de qualquer situação, você pode verificar, mas acho que isso é demais.
Talvez devêssemos sugerir aos desenvolvedores que gerem CHARTEVENT_CHART_CHANGE quando CHART_EVENT_MOUSE_MOVE for alterado? Assim, seria possível restaurar com elegância a configuração necessária quando o Expert Advisor estiver em execução.
Até o momento, tenho essa variante:
Criei um indicador, mas com um parâmetro: executar com EnableMouseDetect = true - controla o rastreamento, false - apenas imprime o número de eventos, se o rastreamento estiver ativado.
------------------
Agora pensei um pouco mais e tenho que concordar: essa opção não funcionará. Se você executar primeiro um programa que rastreia o mouse (ele ativará o rastreamento), depois o segundo (ele verá o que já está ativado) e, em seguida, excluir o primeiro, ele desativará o rastreamento e o segundo ficará sem nada. Ou seja, precisamos criar algum tipo de semáforo para sinalizar que o rastreamento é necessário.
E, à luz da pesquisa realizada aqui (sobre a carga no processador), essas muletas não são necessárias.
Portanto, proponho que minha proposta seja votada pelos desenvolvedores, e o tópico pode ser encerrado.