Erros, bugs, perguntas - página 1931

 

É sempre melhor pela manhã... :)

 
Aleksey Vyazmikin:

No helpdesk

MT4:

Para objectos com tamanho fixo: OBJ_BUTTON, OBJ_RECTANGLE_LABEL e OBJ_EDIT propriedades OBJPROP_XDISTANCE e OBJPROP_YDISTANCE definem a posição do ponto superior esquerdo do objecto em relação ao canto do gráfico (OBJPROP_CORNER), a partir do qual serão contadas as coordenadas X e Y em pixels.


MT5:

Para objectos com tamanho fixo: OBJ_BUTTON, OBJ_RECTANGLE_LABEL, OBJ_EDIT e OBJ_CHART, as propriedades OBJPROP_XDISTANCE e OBJPROP_YDISTANCE definem a posição do ponto superior esquerdo do objecto em relação ao canto do gráfico (OBJPROP_CORNER), a partir do qual serão medidas as coordenadas X e Y em pixels.

A questão é que a versão antiga do MT4 usando ObjectSet permite colocar objectos relativos às suas arestas (cantos) - para objectos na parte esquerda o cálculo dos pixels é efectuado a partir do primeiro símbolo, para objectos na parte direita - a partir do último símbolo, enquanto a nova versão efectua sempre o cálculo a partir do primeiro símbolo, o que torna difícil o posicionamento de etiquetas com texto, porque nem sempre se sabe quantos símbolos de texto serão. Peço aos programadores que adicionem um método de alinhamento de texto à escolha!


Se alguém souber como obter alinhamento à esquerda e à direita no MT5, por favor partilhe a função correspondente!

E não se zangue, mas leia atentamente a ajuda:

Para objectos OBJ_LABEL, OBJ_BITMAP_LABEL e OBJ_RECTANGLE_LABEL pode definir o ângulo do gráfico, relativamente ao qual o ponto de ancoragem do objecto é posicionado. Este ângulo é definido através da propriedade OBJPROP_CORNER, que pode ter um dos quatro valores da enumeração ENUM_BASE_CORNER:

Identificador

Descrição

CANTO_ESQUERDA_ACIMA

Coordenadas do ponto de ancoragem em relação ao canto superior esquerdo do gráfico

CANTO_ESQUERDA_BAIXO

As coordenadas do ponto de ancoragem são dadas em relação ao canto inferior esquerdo do gráfico

CANTO_DIREITA_BAIXO

As coordenadas do ponto de ancoragem são definidas em relação ao canto inferior direito do gráfico

CORNER_RIGHT_UPPER

As coordenadas do ponto de ancoragem são definidas em relação ao canto superior direito do gráfico

A posição do ponto de ancoragem do objecto é especificada pela propriedade OBJPROP_ANCHOR e pode ser um dos 9 valores da enumeração ENUM_ANCHOR_POINT:

Identificador

Descrição

ÂNCORA_ESQUERDA_ACIMA

Ponto de ancoragem no canto superior esquerdo

ANCHOR_LEFT

Âncora aponta para a esquerda no centro

ANCHOR_LEFT_LOWER

Ponto de ancoragem no canto inferior esquerdo

ANCHOR_LOWER

Ponto de ancoragem abaixo do centro

ANCHOR_RIGHT_LOWER

Ponto de ancoragem no canto inferior direito

ANCHOR_RIGHT

Âncora aponta para a direita no centro

ANCHOR_RIGHT_UPPER

Ponto de ancoragem no canto superior direito

ANCHOR_UPPER

Ponto de ancoragem no centro superior

ANCHOR_CENTER

Ponto de ancoragem exactamente no centro do objecto

 
Artyom Trishkin:

Devo subir o item da lista que está a tentar rotular com o número 4, que não está lá? Torna-se zero - e tudo está no seu devido lugar.

Claro que mudei tudo - talvez eu seja estúpido...



void OnStart()
  {
      Label("0",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "0 - Центр координат в левом верхнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            0        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );     
      Label("1",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "1 - Центр координат в левом нижнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            1        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );     
      Label("2",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "2 - Центр координат в правом нижнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            2        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );
      Label("3",//Название
            0,       //Окно
            10,     //X
            32,      //Y
            "3 - Центр координат в правом верхнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            3      //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            ); 

  }

//+------------------------------------------------------------------+
//|Функция вывода информации на экран -- Старый вариант              |
//+------------------------------------------------------------------+
void Label(string _name,int _window,int _x,int _y,string _text,int _font,color _color,int corner)
  {
   ObjectDelete(_name);
   ObjectCreate(_name,OBJ_LABEL,_window,0,0);
   ObjectSet(_name,OBJPROP_CORNER,corner);
   ObjectSet(_name,OBJPROP_XDISTANCE,_x);
   ObjectSet(_name,OBJPROP_YDISTANCE,_y);
   ObjectSetText(_name,_text,_font,"Arial",_color);
  }
/*
//+------------------------------------------------------------------+
//|Функция вывода информации на экран -- Новый вариант               |
//+------------------------------------------------------------------+
void Label(string _name,int _window,int _x,int _y,string _text,int _font,color _color,int corner)
  {
   //corner=4;
   ObjectDelete(0,_name);
   ObjectCreate(0,_name,OBJ_LABEL,_window,0,0);
   ObjectSetInteger(0,_name,OBJPROP_CORNER,corner);
   ObjectSetInteger(0,_name,OBJPROP_XDISTANCE,_x);
   ObjectSetInteger(0,_name,OBJPROP_YDISTANCE,_y);
   ObjectSetText(_name,_text,_font,"Arial",_color);
  }
*/   
 
Artyom Trishkin:

E não fique zangado, leia atentamente a ajuda:

Para objectos OBJ_LABEL, OBJ_BITMAP_LABEL e OBJ_RECTANGLE_LABEL pode definir o ângulo do gráfico, relativamente ao qual o ponto de ancoragem do objecto é posicionado. Este ângulo é definido através da propriedade OBJPROP_CORNER, que pode ter um dos quatro valores da enumeração ENUM_BASE_CORNER:

Identificador

Descrição

CANTO_ESQUERDA_ACIMA

Coordenadas do ponto de ancoragem em relação ao canto superior esquerdo do gráfico

CANTO_ESQUERDA_BAIXO

As coordenadas do ponto de ancoragem são dadas em relação ao canto inferior esquerdo do gráfico

CANTO_DIREITA_BAIXO

As coordenadas do ponto de ancoragem são definidas em relação ao canto inferior direito do gráfico

CORNER_RIGHT_UPPER

As coordenadas do ponto de ancoragem são definidas em relação ao canto superior direito do gráfico

A posição do ponto de ancoragem do objecto é especificada pela propriedade OBJPROP_ANCHOR e pode ser um dos 9 valores da enumeração ENUM_ANCHOR_POINT:

Identificador

Descrição

ÂNCORA_ESQUERDA_ACIMA

Ponto de ancoragem no canto superior esquerdo

ANCHOR_LEFT

Âncora aponta para a esquerda no centro

ANCHOR_LEFT_LOWER

Ponto de ancoragem no canto inferior esquerdo

ANCHOR_LOWER

Ponto de ancoragem abaixo do centro

ANCHOR_RIGHT_LOWER

Ponto de ancoragem no canto inferior direito

ANCHOR_RIGHT

Âncora aponta para a direita no centro

ANCHOR_RIGHT_UPPER

Ponto de ancoragem no canto superior direito

ANCHOR_UPPER

Ponto de ancoragem no centro superior

ANCHOR_CENTER

Ponto de ancoragem directamente no centro do objecto

Obrigado, tentarei pensar em algo amanhã...

 
prostotrader:

É sempre melhor pela manhã... :)

Normalmente é :)
 
O SD diz que é a coisa certa a fazer neste caso

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Insectos, insectos, perguntas

fxsaber, 2017.07.18 09:51

Quase uma pergunta infantil: porque é que é assim?
void OnStart()
{
  const double Norm = NormalizeDouble(8905 / 1000.0, 3);
  Print(Norm); // 8.904999999999999
  Print(DoubleToString(Norm, 3)); // 8.905
  
  const double Norm2 = (double)DoubleToString(Norm, 3);
  Print(Norm2); // 8.904999999999999
  Print(Norm == Norm2); // true
}

Por alguma razão tinha a certeza de que a DoubleToString não fazia sentido após a sua normalização. Mas não, como mostra o guião. Porque é que é este o caso?

Parece que a dupla -> conversão de cordas não funciona correctamente.


Este exemplo é bastante complicado de entender, por isso dei-vos outro.

void OnStart()
{
  Print((double)"8.905" == 8.905); // true
  Print(((string)(double)"8.905")); // 8.904999999999999
}

Eis o que quero dizer.

Строковая в double переводится без проблем. Обратно - получаем другой результат.

Ou seja, pegou na corda "8.905", converteu-a para o dobro e imediatamente para corda, obtendo 8.9049999999999999999. Mas a primeira linha do OnStart mostra que (duplo) "8.905" == 8.905. Ou seja, 8.905 deve ser impresso.

Naturalmente, a situação óbvia de fim zero não deve funcionar:

Se a condição(duplo) "8.9050" == "8.9050"for satisfeita, então a condição(fio)(duplo) "8.9050" == "8.9050"também deve ser satisfeita.

Tendo investigado um pouco o assunto, cheguei à seguinte situação

void OnStart()
{
  const double Num = 8.274;
  const double Norm = NormalizeDouble(Num, 3);
  
  Print(Num);  // 8.273999999999999
  Print(Norm); // 8.274000000000001
}

Explique por favor porque é que a conversão double -> string ainda é considerada correcta. O último exemplo está a dar-me cabo da cabeça.

 
fxsaber:

Explique por favor porque é que a dupla -> conversão de cordas ainda é considerada correcta. O último exemplo é um sopro de mente tão completo.

Comentário sobre o último exemplo

Os números reais podem ser considerados idênticos se tiverem sido submetidos às mesmas conversões. Mesmo conversões aparentemente idênticas - num*0,5 e num/2,0 levam a resultados diferentes. O mesmo se pode dizer das operações de espelhamento. num*=num2, num/=num2. O número resultante não será igual ao número original. Bem-vindo ao mundo dos números reais.

Durante o processo de normalização, foram realizadas 3 operações nesta amostra com um número real - num*=1000, num+=0,5, num/=1000.

Pode verificar os passos no depurador

 
fxsaber:
SD diz que é correcto neste caso.

Porque é que é confuso?

A grande maioria dos números decimais reais não são representáveis como uma fracção binária sem um resto. Colocar um formato de armazenamento duplo em cima disso e obtém-se um material tão feio.

Na verdade, o tipo decimal seria agradável, é útil.

 
Slava:

Comentário sobre o último exemplo

Os números reais podem ser considerados idênticos se as mesmas conversões forem efectuadas neles. Mesmo conversões aparentemente idênticas - num*0,5 e num/2,0 levam a resultados diferentes. O mesmo se pode dizer das operações de espelhamento. num*=num2, num/=num2. O número resultante não será igual ao número original. Bem-vindo ao mundo dos números reais.

Neste exemplo, 3 operações - num*=1000, num+=0,5, num/=1000 - foram realizadas com um número real durante a normalização.

Pode verificar os passos no depurador


Uma explicação muito construtiva, obrigado!


Mas este contra-exemplo impressiona-me.

void OnStart()
{
  const double Num = 8.274;
  const double Norm = NormalizeDouble(Num, 3);
   
  Print(Num);  // 8.273999999999999
  Print(Norm); // 8.274000000000001
  
  Print((double)DoubleToString(Num, 3) == Num);     // true - без нормализации все замечательно
  Print((double)DoubleToString(Norm, 3) == Norm);   // false - а после нормализации полный облом!
}

É assim que a normalização deve funcionar?

 
Комбинатор:

Porque é que é confuso?

Depois da explicação de Slava não é confusa, mas depois há um exemplo que nos faz questionar a correcção da própria NormalizeDouble.