assessor especializado - perguntas diversas - página 4

 
  1. Sim, eles o usam muito. Todas elas foram escritas quando só havia moedas. Agora há metais e se o tamanho do carrapato != apontar está errado.
  2. 02:00:00.069 - especialista personalizado EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
    O OP continua imprimindo um duplo a 15 dígitos e não consegue entender porque não é exatamente 0,07. Porque algum número não pode ser representado exatamente 1/8. pode 1/10. não pode.
 
honest_knave:
double LotCalculator(double lots)
  {
   ...
   return(NormalizeDouble(lots,2));
  }

Este comentário realmente me ajuda muito, e isto é útil, mas me dá mais decimais.
( mais decimais é normal - porque eu já li sobre isso )

Eu ainda me preocupo com a'NormalizeDouble' e estou procurando outro caminho, que é melhor que 'NormalizeDouble'.

Obrigado!

 

Um grande obrigado a quem escreveu comentários.

@whroeder1- Vou pesquisar amplamente seu comentário (/ links) grande obrigado.
@Marco- Vou usá-lo após a edição do LotSize LotStep. Muito obrigado!

 
Max Enrik:

Este comentário realmente me ajuda muito, e isto é útil, mas me dá mais decimais.
( mais decimais é normal - porque eu já li sobre isso )

Eu ainda me preocupo com a'NormalizeDouble' e estou procurando outro caminho, que é melhor que 'NormalizeDouble'.

Obrigado!

Talvez seja melhor estabelecer exatamente o que você está procurando alcançar.

Se você quiser uma função para devolver um lote válido para fazer um pedido, não precisa usar NormalizeDouble(). Meu snippet original de código ou WHRoeder's irá conseguir isso para você. Há diferenças sutis entre eles que serão uma questão de preferência pessoal.

Mas, se você fizer uma impressão() direta desse valor de lote você pode obter alguns resultados "estranhos"... como seu 0,07000000000000001

Isto não será um problema para a OrderSend() mas pode não ser o que você espera ver.

Se você quiser ver os números exibidos de forma "normal", você tem duas opções:

1. Você pode usar o NormalizeDouble( ) na função. Para uma impressão padrão, o valor será o que você espera. Mas se você imprimir (manualmente) casas decimais suficientes, você eventualmente verá que o número não é exatamente o que você pensa que é. Este é o ponto que o WHRoeder está tentando fazer (eu acho). Esta solução não é a mais elegante, mas é a mais simples. Ou...

2. Você pode deixar o tamanho do lote como ele é (ou seja, não usar NormalizeDouble) e depois ajustar o valor para fins de exibição quando necessário. Você pode usar DoubleToStr() ou StringFormat() ou printf() para conseguir isto, dependendo do que você precisar. Esta é uma abordagem mais flexível.

Lembre-se que o valor real e como esse valor é exibido não tem que ser o mesmo. Você nunca será capaz de armazenar exatamente 0,07:

   double myVal=0.07;
   printf("%.24f",myVal);

Result: 0.070000000000000006661338

Mas certamente você pode exibir 0,07 se for necessário.
 
honest_knave:

Talvez seja melhor estabelecer exatamente o que você está procurando alcançar.
...

Uau, que bom que você escreveu, eu quase entendo como seu comentário.
Por isso vou escrever um novo comentário, em breve.

//--- segunda vez editado

Como mencionei, eu não preciso do LotSize e LotStep mostra logo em exposição, eu preciso do LotSize e LotStep poderia mostrar a mesma coisa em todos os lugares.
Só que eu me preocupo com isso.

 

Bem, se se trata de lotes dinâmicos você pode sempre ligar uma simples caixa de engrenagens.

//Gearbox//
double Lots;
Balance=AccountInfoDouble(ACCOUNT_BALANCE);

if(Balance>10000)
{Lots=10;Print(" Gear Two");}
if(Balance>100000)
{Lots=100;Print(" Gear Three");}
if(Balance>1000000)
{Lots=1000;Print(" Gear Four");}
if(Balance>10000000)
{Lots=10000;Print(" Gear Five");}

if(Balance<10000000)
{Lots=1000;Print(" Gear Four");}
if(Balance<1000000)
{Lots=100;Print(" Gear Three");}
if(Balance<100000)
{Lots=10;Print(" Gear Two");}
if(Balance<10000)
{Lots=1;Print(" Gear One");}
if(Balance>1000000000)
{Lots=0;}
 

Preciso colocar parte dos meus EA com vocês, portanto espero que isso os ajude a me entender mais claramente.
Então, eu preciso saber se esse código é bom ou não?

Por favor, me dêem bons (claros) conselhos ou ajuda, obrigado antecipadamente.

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{

    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, _btnLotMinus, OBJPROP_STATE, false );
        _lotSize -= _lotStep;

        if ( NormalizeDouble( _lotSize, 2 ) <= 0 ) _lotSize = _lotMin;
        _calcUpdade( CALC_CHANGE_LOT );

        Print( " | Lot:   ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

double _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
    return( NormalizeDouble( _lotSize, 2 ) );
}
 
Max Enrik:

Preciso colocar parte dos meus EA com vocês, portanto espero que isso os ajude a me entender mais claramente.
Então, eu preciso saber se esse código é bom ou não?

Por favor, me dê um bom (claro) conselho ou ajuda, obrigado antecipadamente.

Tarde da noite, descompilado, não testado.

Não podemos ver onde você definiu _lotSize... lembre-se que você precisará ter certeza de que _lotSize é sempre um múltiplo de _lotStep.

IMHO seria melhor se você mantivesse todos os seus cálculos de lote juntos, ao invés de dividi-los entre OnChartEvent() e _lotCalc(). Uma função que verifica min / max / step e faz o incremento / decremento.

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{
    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, sparam, OBJPROP_STATE, false );
        _lotSize = fmax(_lotMin, _lotSize-_lotStep);
        _calcUpdade( CALC_CHANGE_LOT );
        printf( " | Lot: %.2f  ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

void _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
}
 
honest_knave:

Tarde da noite, descompilado, não testado.
Não podemos ver onde você definiu o primeiro _lotSize... lembre-se que você precisará ter certeza de que o _lotSize é sempre um múltiplo de _lotStep.
IMHO seria melhor se você mantivesse todos os seus cálculos de lote juntos, ao invés de dividi-los entre OnChartEvent() e _lotCalc(). Uma função que verifica min / max / step e faz o incremento / decremento.

Isso me ajudou muito, o que significa que resolvi meus problemas de tamanho de lote e de perda de etapa.
Muito obrigado, cara.

#Lot 0 (zero) & (entre o tamanho do lote resolvido e o problema da etapa do lote)- Fechado

 

Sim, esqueci o código do tamanho do lote, por isso o uso na funçãoinit.
É um bom lugar para _lotSize?

Obrigado!

int OnInit()
{
    _pip = Point;
    if( Digits == 0 || Digits == 2 || Digits == 3 || Digits == 5 ) _pip = 10 * Point;
    _lotSize = _lotValue * MarketInfo( Symbol(), MODE_MINLOT );

    //...
}