Qualquer pergunta de novato, de modo a não desorganizar o fórum. Profissionais, não passem por aqui. Em nenhum lugar sem você - 6. - página 739

 
korobok777:
Lot=NormalizeDouble(Balance*0.001,2);
 
Vinin:
Você escreveu algo errado.

Sim, é uma gralha, corrigiu-a. Ou o princípio está errado? O ponto foi que se o saldo for dividido por 10 sem um restante, o lote é tomado como o produto do lote inicial por 1/10 do saldo. Não é? Como então?


Embora Vadim o tenha escrito mais simples aqui, sim ))))

 
evillive:

Sim, é uma gralha, corrigiu-a. Ou o princípio está errado? O ponto foi que se o saldo for dividido por 10 sem um restante, o lote é tomado como o produto do lote inicial por 1/10 do saldo. Não é? Como você faz então?


Embora Vadim o tenha escrito mais facilmente aqui, sim ))))

O saldo é muito raramente dividido por 10 sem um resto. Em outros casos (a maioria), haveria um lote padrão
 
evillive:
double StartLot=0.01;
if(MathMod(AccountBalance(),10)==0) Lot=StartLot*AccountBalance()/10;

E MarketInfo()?

E MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Você ainda precisa entrar na grade de dígitos de valores de lote permitidos:

#property strict

/******************************************************************************/
double getLot(double factor = 0.001) {
  double minLot = MarketInfo(Symbol(), MODE_MINLOT);

  if (minLot > 0) { // Проверка значения от функции MetaQuotes на вменяемость
    double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);

    if (maxLot >= minLot) { // Проверка второго значения от функции MetaQuotes на вменяемость
      double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);

      if (lotStep > 0) { // Проверка третьего значения от функции MetaQuotes на вменяемость
        double rawLot = AccountBalance() * factor; // Грубо вычисленное значение лота

        // В процессе "рихтования" грубо вычисленного значения лота подразумевается, что "округление" происходит всегда к меньшему
        if (rawLot >= minLot && rawLot < maxLot + lotStep) { // Если грубо вычисленное значение "влезает" в диапазон разрешённых значений лотов
          int stepNum = int((rawLot - minLot) / lotStep); // Количество step'ов, которое надо "отступить вправо на числовой оси" от минимального значения лота (при преобразовании double -> int как раз и происходит нужный тип округления)

          return minLot + lotStep * stepNum; // Вычисляем значение лота в "разрядной сетке" разрешённых лотов.
        }
      }
    }
  }

  return 0; // Какие-то обстоятельства не позволили выдать значение в "разрядной сетке" разрешённых лотов; для индикации данного события выдаётся специальное значение 0.
}

/******************************************************************************/
void OnStart() {
  Print("AccountBalance() = ", AccountBalance(), ", getLot() = ", getLot());
}

Dirigiu-o, conseguiu algo semelhante à verdade:

0       20:09:49.699    Script 3 EURUSDm,H1: loaded successfully
0       20:09:49.699    3 EURUSDm,H1: initialized
0       20:09:49.699    3 EURUSDm,H1: AccountBalance() = 152.82, getLot() = 0.15
0       20:09:49.699    3 EURUSDm,H1: uninit reason 0
0       20:09:49.699    Script 3 EURUSDm,H1: removed

Nenhum erro, eu acho.

 
simpleton:

E MarketInfo()?

E MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Você ainda precisa entrar na grade de dígitos de valores de lote permitidos:

Dirigiu-o, conseguiu algo que se assemelhava à verdade:

Não parece que eu tenha cometido um erro.

Obrigado, já me foi explicado :D

É claro que para mim mesmo escrevo com todos os cheques, como deveria ser, havia apenas um esboço de como trazer o lote para o balanço/10, mas a idéia não teve sucesso...

Mas você tem muito texto, poderia ser mais simples:

  lotstep= MarketInfo(Symbol(),MODE_LOTSTEP);
  lotmax=MarketInfo(Symbol(), MODE_MAXLOT);
  lotmin=MarketInfo(Symbol(), MODE_MINLOT);

lot=lotstep*MathRound(AccountBalance()*0.001/lotstep);
if(lot < lotmin) lot = lotmin;
if(lot > lotmax) lot = lotmax;
 
simpleton:

E MarketInfo()?

E MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Você ainda precisa entrar na grade de dígitos de valores de lote permitidos:

Eu o dirigi, consegui algo parecido com a verdade:

Parece que não consigo entender errado.

por que, quando um programador natural assume um trabalho, uma única linha necessária para atingir o objetivo se transforma em uma lista de meio quilômetro de comprimento?

double Lot = NormalizeDouble(AccountBalance()/1000,2);
if(Lot<Min_Lot)Lot=Min_Lot;
 
_new-rena:

Por que quando um programador natural assume um trabalho, uma linha de código necessária para atingir o objetivo se transforma em uma lista de meio quilômetro de comprimento?

Algumas pessoas têm muitos passos não 0,01 mas, por exemplo, 0,03 ou mesmo 0,1. E como então? São necessários cheques para todos os casos, o bem sabe que não leva muito tempo.
 
evillive:
Algumas pessoas não têm muito passo de 0,01 mas, por exemplo, 0,03. Como então? São necessários cheques para todos os casos, o que não leva muito tempo.
Coloque (abaixo) no inite e você não precisará mais incomodar seu servidor e computador
double Min_Lot=MarketInfo(Symbol(), MODE_MINLOT);
 
Estou falando do campo, não do lote mínimo, mas tudo bem, esqueça.
 
_new-rena:

Por que quando um programador natural assume um trabalho, uma linha de código necessária para atingir o objetivo se transforma em uma lista de meio quilômetro de comprimento?

Porque todos os tipos de merda esperam a cada volta, e você tem que se proteger. Se você não se proteger, haverá uma qualidade muito baixa, o que pode acabar custando muito caro a longo prazo. 90% dos esforços são gastos na defesa contra o diabo e apenas 10% são gastos na solução do problema. No caso do MT4 e MQL4++, a relação é ainda mais assimétrica.

A merda começa enquanto se lê a documentação:

Возвращаемое значение

Информация о финансовом инструменте. Часть информации о текущем финансовом инструменте хранится в предопределенных переменных.

Tudo. É obrigado a devolver as informações sobre o instrumento financeiro, e nada mais. Não há outros resultados. Obtemos informações sobre o instrumento:

#property strict

/******************************************************************************/
void OnStart() {
  Print("MarketInfo(\"Фигня\", MODE_MINLOT) = ", MarketInfo("Фигня", MODE_MINLOT));
  Print("MarketInfo(\"Фигня\", MODE_MAXLOT) = ", MarketInfo("Фигня", MODE_MAXLOT));
  Print("MarketInfo(\"Фигня\", MODE_LOTSTEP) = ", MarketInfo("Фигня", MODE_LOTSTEP));
}

Vejamos quais são os parâmetros de lote para esta ferramenta:

0       21:12:18.980    Script 3 EURUSDm,H1: loaded successfully
0       21:12:18.980    3 EURUSDm,H1: initialized
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_MINLOT) = 0.0
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_MAXLOT) = 0.0
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_LOTSTEP) = 0.0
0       21:12:18.980    3 EURUSDm,H1: uninit reason 0
0       21:12:18.980    Script 3 EURUSDm,H1: removed

Parâmetros interessantes. Não sei por que a documentação não descreve o comportamento desta função em caso de erros. Teremos que usar recursos não documentados que descobrimos ao observar o comportamento desta função.

Portanto, a função MarketInfo() pode retornar 0 para estes parâmetros solicitados cujos valores devem ser diferentes de 0 por natureza, o que é uma situação de erro não documentado. O código deve verificar se ocorreu um erro ao solicitar cada um dos parâmetros. Somente por este motivo, 3 verificações são fornecidas no código.

A seguir. Obviamente, o tamanho de lote calculado pode não se encaixar na faixa de tamanhos de lote permitidos. Não vamos verificar isso? Ou devemos programar explicitamente esta situação e depois programar a reação a ela no código de nível superior, em vez de "como acontece"? Um exemplo de como ele é quando nem tudo está programado, e funciona como acontece por si só, poderia ser outra nova versão do MT4, quando algo se moveu em algum lugar, em algum lugar milagrosamente brilhante, e em algum lugar ele parou de funcionar completamente. Talvez este não seja o resultado desejado?

O código é expandido e comentado para mostrar o processo de pensamento e o modelo de cálculo utilizado. Como o modelo de lote definido pela MetaQuotes é implementado na forma de uma "grade de valores de ordem de propagação" definida pelos parâmetros MINLOT, MAXLOT e LOTSTEP, seria mais razoável calcular o valor exato do lote nesses termos. É por isso que o modelo de cálculo está escrito nesses termos.

Não vejo nenhum "meio-quilômetro" ou qualquer outra coisa. A única coisa é que o código é executado no estilo de atingir a máxima performance quando as funções são chamadas uma vez e os valores resultantes são armazenados em variáveis, e cada chamada é executada somente após outra verificação quando se verifica que o valor retornado não é um indicador de erro e ainda faz sentido continuar os cálculos. Uma vez que fica claro que ocorreu um erro, os recursos computacionais não são mais desperdiçados em chamadas inúteis.

Para tornar o código mais compacto, poderíamos obter todos os 3 valores de uma só vez e verificar todas as 3 condições em um se. Mas em caso de erro na primeira chamada, as outras 2 chamadas seriam um desperdício de recursos computacionais.

Note que ao programar uma expressão, que usa divisão por loteStep, prestamos atenção propositalmente ao fato de que ela é usada sob o "se", o qual apenas verificou que o valor do loteStep é diferente de 0, ou seja, a divisão por 0 não pode acontecer. Em princípio, o código ainda pode ser melhorado declarando todas as variáveis como "double" e "int" e "const double" e "const int", protegendo-se contra si mesmo durante outras possíveis modificações de código. Em particular, se sob o código de if, que acabou de verificar se o valor da variável lotStep é diferente de 0, acidentalmente em algum código recém-adicionado neste local atribuir erroneamente o valor 0 a esta variável, então ocorrerá uma nova divisão por 0 na expressão. Se a variável for declarada como "const double", então espero que o compilador informe imediatamente uma tentativa não autorizada de modificar a variável lotStep, impedindo assim de cometer tal erro.

Portanto, os "meios quilômetros" são devidos a condições objetivas severas, não ao capricho de alguém.

Como se chama o ramo? Bem, se você vai ajudar, faça-o corretamente, para que você possa realmente aprender alguma coisa.