assessor especializado - perguntas diversas - página 3

 
double LotCalculator(double lots)
  {
   double minlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),
          maxlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX),
          lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots/lotstep)*lotstep;
   lots = MathMax(lots,minlot);
   lots = MathMin(lots,maxlot);
   return(NormalizeDouble(lots,2));
  }
 
honest_knave:
double LotCalculator(double lots){}

Muito apreciado.

Eu só quero começar a escrever esse código :)

Você me salvou mais tempo.

Muito obrigado!

 
Recebi a mesma mensagem para o tamanho do lote.
Eu chamo 'LotCalculator()' em 'OnChartEvent()', então isso não está certo?
 

Estou procurando um bom fórum para o cálculo de'MarketInfo & LotSize'.
Quem conhece esse tipo de bom fórum , por favor, compartilhe comigo.

Obrigado.

 
Por acaso você usou meu trecho de código antes de eu editar a última linha (NormalizeDouble)? Vejo que havia apenas 3 minutos desde meu correio até o seu, e eu o editei quase imediatamente.
 
Max Enrik: Estou usando o NormalizeDouble para minhas EA's. Mas me preocupo com a mensagem'NormalizeDouble', mas vejo o tamanho do lote no gráfico desta forma: 0.07

Portanto, eu preciso de bons conselhos, por favor.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07
  1. NormalizeDuplo retorna um duplo. O ponto flutuante tem um número infinito de decimais, é seu não entendimento do ponto flutuante e que alguns números não podem ser representados com exatidão. (como 1/10.) Formato de ponto flutuante de precisão dupla - Wikipedia, a enciclopédia livreVeja também The == operand. -MQL4 fórum
  2. NÃO utilize o NormalizeDouble, TUDO. Por QUALQUER motivo. É um kludge, não o use. O seu uso é sempre errado.
 
whroeder1:
  1. NÃO useNormalizeDuplo, TUDO. Para QUALQUER Motivo. É um kludge, não o use.O seu uso é sempre errado.

Acredito que você ainda precisa do NormalizeDouble().

Aqui está um exemplo, usando seu código snippet (o mesmo se aplica ao meu exemplo usando MathFloor):

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots                = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(lots);
}

Chamado:

Print(NormalizeLots(2/3.0));

Resultado:

0.7000000000000001

Agora código ajustado:

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots            = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(NormalizeDouble(lots,2));
}

Resultado:

0.7


 

 Result: 0.7000000000000001

Que parte de "seu não entendimento do ponto flutuante e que alguns números não podem ser representados exatamente". (como 1/10.) O formato de ponto flutuante de precisão dupla - Wikipedia, a enciclopédia livre" não estava claro?

NormalizeDouble(0,7, 2) produzirá o mesmo resultado exato (ou possibilidade 0,6999999999999999999.)

 
whroeder1:

Que parte de "seu não entendimento do ponto flutuante e que alguns números não podem ser representados exatamente". (como 1/10.) O formato de ponto flutuante de precisão dupla - Wikipedia, a enciclopédia livre" não estava claro?

NormalizeDouble(0,7, 2) produzirá o mesmo resultado exato (ou possibilidade 0,6999999999999999999).

Não estou dizendo que NormalizeDuplo() é necessário para um OrderSend válido. É por isso que meu primeiro trecho de código o excluiu. Também não estou claro sobre a forma como os números de pontos flutuantes são representados.

Eu editei o trecho para incluí-lo porque senti que ele abordava melhor meu entendimento do problema da OP (essencialmente um problema de exibição, que pode ser resolvido ou usando NormalizeDouble() no código "normalizador de lote", ou usando printf ou DoubleToStr quando o valor precisa ser exibido).

Talvez eu tenha entendido mal o OP.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07

(editado para remover a concisão desnecessária)

 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- get minimum stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- calculated SL and TP prices must be normalized
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
//--- place market order to buy 1 lot
   int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend failed with error #",GetLastError());
     }
   else
      Print("OrderSend placed successfully");
//---
  }

Isto pode ser confuso para as pessoas porque a documentação MQL4 usa a função NormalizeDouble() na maioria dos exemplos.

Chega até a avisar que o preço não normalizado não pode ser aplicado:

Nota

Na abertura de uma ordem de mercado (OP_SELL ou OP_BUY), somente os últimos preços de Bid (para venda) ou Ask (para compra) podem ser usados como preço aberto. Se a operação for realizada com um título diferente do atual, a função MarketInfo() deve ser usada com o parâmetro MODE_BID ou MODE_ASK para que as últimas cotações deste título sejam obtidas.

O preço calculado ou não pode ser aplicado. Se não tiver havido o preço aberto solicitado no tópico de preço ou se não tiver sido normalizado de acordo com a quantidade de dígitos após o ponto decimal, será gerado o erro 129 (ERR_INVALID_PRICE). Se o preço aberto solicitado estiver totalmente desatualizado, o erro 138 (ERR_REQUOTE) será gerado independentemente sobre o parâmetro de deslizamento. Se o preço solicitado estiver desatualizado, mas presente na linha, o pedido será aberto ao preço atual e somente se o preço atual estiver dentro da faixa de preço+deslizamento.

E mesmo em alguns dos melhores livros sobre MQL, eles o utilizam bastante.

Pode depender da sua aplicação, um problema de exibição é menos dramático do que as falhas no pedido ou na modificação.

Pessoalmente, eu sempre me converto a valores inteiros, por isso raramente lido com isso.