Cualquier pregunta de novato, para no saturar el foro. Profesionales, no pasen de largo. En ninguna parte sin ti - 6. - página 739

 
korobok777:
Lot=NormalizeDouble(Balance*0.001,2);
 
Vinin:
Has escrito algo mal.

Sí, es una errata, la he corregido. ¿O el principio es erróneo? La cuestión era que si el saldo se divide entre 10 sin que quede resto, el lote se toma como el producto del lote inicial por 1/10 del saldo. ¿No es así? ¿Cómo entonces?


Aunque Vadim lo escribió más sencillo aquí, sí )))

 
evillive:

Sí, es una errata, la he corregido. ¿O el principio es erróneo? La cuestión era que si el saldo se divide entre 10 sin que quede resto, el lote se toma como el producto del lote inicial por 1/10 del saldo. ¿No es así? ¿Cómo se hace entonces?


Aunque Vadim lo escribió más fácil aquí, sí ))))

Es muy raro que el saldo se divida por 10 sin que quede un resto. En otros casos (la mayoría) habría un lote por defecto
 
evillive:
double StartLot=0.01;
if(MathMod(AccountBalance(),10)==0) Lot=StartLot*AccountBalance()/10;

¿Y MarketInfo()?

Y MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Todavía tiene que entrar en la red de dígitos permitidos de los valores del lote:

#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());
}

Lo ejecuté y obtuve algo parecido a la verdad:

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

No hay error, creo.

 
simpleton:

¿Y MarketInfo()?

Y MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Todavía tiene que entrar en la red de dígitos permitidos de los valores del lote:

Lo he comprobado y he obtenido algo parecido a la verdad:

Parece que no me he equivocado.

Gracias, ya me lo han explicado :D

Está claro que para mí escribo con todos los cheques, como debe ser, sólo había un esbozo de cómo llevar el lote a la relación equilibrio/10, pero la idea no tuvo éxito...

Pero tienes mucho texto, podría ser más sencillo:

  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:

¿Y MarketInfo()?

Y MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

Todavía tiene que entrar en la red de dígitos permitidos de los valores del lote:

Lo ejecuté y obtuve algo parecido a la verdad:

Parece que no puedo equivocarme.

¿por qué, cuando un programador natural se encarga de un trabajo, una sola línea necesaria para lograr el objetivo se convierte en un listado de medio kilómetro de longitud?

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

¿Por qué cuando un programador natural se encarga de un trabajo, una línea de código necesaria para lograr el objetivo se convierte en un listado de medio kilómetro de longitud?

Algunas personas tienen mucho paso, no 0,01 sino, por ejemplo, 0,03 o incluso 0,1. ¿Y cómo entonces? Los controles son necesarios para todos los casos, Dios sabe que no lleva mucho tiempo.
 
evillive:
Algunas personas no tienen un paso de 0,01 sino, por ejemplo, de 0,03. ¿Cómo entonces? Los controles son necesarios para todos los casos, lo bueno es que no lleva mucho tiempo.
Establece (abajo) en el inite y no tienes que molestar más al servidor y al ordenador
double Min_Lot=MarketInfo(Symbol(), MODE_MINLOT);
 
Me refiero al terreno de juego, no al lote mínimo, pero bueno, olvídalo.
 
_new-rena:

¿Por qué cuando un programador natural se encarga de un trabajo, una línea de código necesaria para lograr el objetivo se convierte en un listado de medio kilómetro de longitud?

Porque todo tipo de mierda te espera en cada esquina, y tienes que protegerte. Si no te proteges, la calidad será muy baja, lo que puede acabar costándote mucho a largo plazo. El 90% de los esfuerzos se dedican a defenderse del demonio y sólo el 10% se dedica a resolver el problema. En el caso de MT4 y MQL4++ la relación es aún más asimétrica.

La mierda empieza al leer la documentación:

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

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

Todo. Está obligado a devolver la información sobre el instrumento financiero, y nada más. No hay otros resultados. Obtenemos información sobre el 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));
}

Veamos cuáles son los parámetros del lote para esta herramienta:

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 interesantes. No sé por qué la documentación no describe el comportamiento de esta función en caso de errores. Tendremos que utilizar características no documentadas que descubrimos al observar el comportamiento de esta función.

Así, la función MarketInfo() puede devolver 0 para estos parámetros solicitados cuyos valores deben ser diferentes de 0 por naturaleza, lo que constituye una situación de error no documentada. El código debe comprobar si se ha producido un error al solicitar cada uno de los parámetros. Sólo por esta razón, se han previsto 3 comprobaciones en el código.

Siguiente. Obviamente, el tamaño del lote calculado puede no encajar en el rango de tamaños de lote permitidos. ¿No lo comprobamos? ¿O deberíamos programar explícitamente esta situación y luego programar la reacción a la misma en el código de nivel superior, en lugar de "como sucede"? Un ejemplo de lo que parece cuando no todo está programado, y funciona como sucede por sí mismo, podría ser otra versión fresca de MT4, cuando algo se ha movido en algún lugar, en algún lugar milagrosamente glitched, y en algún lugar ha dejado de funcionar por completo. ¿Quizás no sea éste el resultado deseado?

El código está ampliado y comentado para que se pueda ver el proceso de pensamiento y el modelo de cálculo utilizado. Dado que el modelo de lote establecido por MetaQuotes se implementa en forma de una "cuadrícula de valores de órdenes de propagación" definida por los parámetros MINLOT, MAXLOT y LOTSTEP, sería más razonable calcular el valor exacto del lote en esos términos. Por eso el modelo de cálculo está escrito en esos términos.

No veo ningún "medio kilómetro" ni nada parecido. Lo único es que el código se ejecuta en el estilo de lograr el máximo rendimiento cuando las funciones se llaman una vez y los valores resultantes se almacenan en variables, y cada llamada se ejecuta sólo después de otra comprobación cuando resulta que el valor devuelto no es un indicador de error y todavía tiene sentido continuar los cálculos. Una vez que queda claro que se ha producido un error, los recursos informáticos ya no se desperdician en llamadas inútiles.

Para hacer el código más compacto, podríamos obtener los 3 valores a la vez y comprobar las 3 condiciones en un solo if. Pero en caso de que se produzca un error en la primera llamada, las otras 2 llamadas serían un desperdicio de recursos computacionales.

Nótese, que al programar una expresión, que utiliza la división por lotStep, hemos prestado atención a propósito al hecho de que se utiliza bajo los if, que acaban de comprobar que el valor de lotStep es diferente de 0, es decir, la división por 0 allí no puede ocurrir. En principio, el código aún puede mejorarse declarando todas las variables como "double" e "int" y "const double" y "const int", protegiéndose de sí mismo durante posibles modificaciones posteriores del código. En particular, si bajo el código if, que acaba de comprobar si el valor de la variable lotStep es diferente de 0, accidentalmente en algún código recién añadido en este lugar asigna por error el valor 0 a esta variable, entonces se producirá una nueva división por 0 en la expresión. Si la variable se declara como "const double", entonces espero que el compilador informe inmediatamente de un intento no autorizado de modificar la variable lotStep, evitando así que se produzca tal error.

Así que los "medios kilómetros" se deben a condiciones objetivas severas, no al capricho de alguien.

¿Cómo se llama la rama? Si vas a ayudar, hazlo bien, para que realmente aprendas algo.