Any rookie question, so as not to clutter up the forum. Professionals, don't pass by. Nowhere without you - 6. - page 739

 
Vinin:
You wrote something wrong.

Yes, it's a typo, corrected it. Or is the principle wrong? The point was that if the balance is divided by 10 without a remainder, the lot is taken as the product of the initial lot by 1/10 of the balance. Isn't it? How then?


Although Vadim wrote it simpler here, yes )))

 
evillive:

Yes, it's a typo, corrected it. Or is the principle wrong? The point was that if the balance is divided by 10 without a remainder, the lot is taken as the product of the initial lot by 1/10 of the balance. Isn't it? How do you do it then?


Although Vadim wrote it simpler here, yes )))

The balance is very rarely divided by 10 without a remainder. In other cases (most) there would be a default lot
 
evillive:
double StartLot=0.01;
if(MathMod(AccountBalance(),10)==0) Lot=StartLot*AccountBalance()/10;

And MarketInfo()?

AND MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

You still need to get into the allowed digit grid of lot values:

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

Ran it, got something similar to the truth:

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 error, I think.

 
simpleton:

And MarketInfo()?

AND MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

You still need to get into the allowed digit grid of lot values:

Ran it, got something resembling the truth:

I don't seem to have made a mistake.

Thanks, it's already been explained to me :D

It is clear that for myself I write with all checks, as it should be, there was just an outline of how to bring the lot to the balance/10 ratio, but the idea was unsuccessful...

But you have a lot of text, it could be simpler:

  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:

And MarketInfo()?

AND MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP?

You still need to get into the allowed digit grid of lot values:

I ran it, got something similar to the truth:

I don't seem to be able to get it wrong.

why, when a natural programmer takes on a job, a single line needed to achieve the goal turns into a half-kilometre-long listing?

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

Why is it that when a natural programmer takes on a job, one line of code necessary to achieve the goal turns into a half-kilometre-long listing?

Some people have a lot step not 0.01 but, for example, 0.03 or even 0.1. And how then? Checks are needed for all cases, goodness knows it doesn't take much time.
 
evillive:
Some people do not have a lot step of 0.01 but, for example, 0.03. How then? Checks are needed for all cases, good thing it doesn't take much time.
Set (below) in the inite and you don't have to bother the server and the computer anymore
double Min_Lot=MarketInfo(Symbol(), MODE_MINLOT);
 
I'm talking about the pitch, not the min. lot, but okay, forget it.
 
_new-rena:

Why is it that when a natural programmer takes on a job, one line of code necessary to achieve the goal turns into a half-kilometre-long listing?

Because all sorts of shit awaits at every turn, and you have to protect yourself. If you don't protect yourself, there will be very low quality, which can end up costing you a lot in the long run. 90% of efforts are spent on defending against the devil and only 10% are spent on solving the problem. In the case of MT4 and MQL4++ the ratio is even more asymmetric.

The shit starts while reading the documentation:

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

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

Everything. Is obliged to return the information on the financial instrument, and nothing else. There are no other outcomes. We obtain information about the instrument:

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

Let's look at what the lot parameters are for this tool:

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

Interesting parameters. I don't know why the documentation doesn't describe this function's behavior in case of errors. We will have to use undocumented features we found out when observing this function's behavior.

So, the MarketInfo() function may return 0 for these requested parameters whose values must be different from 0 by nature, which is an undocumented error situation. The code must check if an error occurred when requesting each of the parameters. For this reason alone, 3 checks are provided in the code.

Next. Obviously, the calculated lot size may not fit into the range of allowed lot sizes. Let's not check it? Or should we explicitly program this situation and then program the reaction to it in the upper-level code, instead of "as it happens"? An example of what it looks like when not everything is programmed, and it works the way it happens by itself, could be another fresh release of MT4, when something moved off somewhere, somewhere miraculously glitched, and somewhere it stopped working altogether. Perhaps this is not the desired result?

The code is expanded and commented out to show the thought process and the calculation model used. Since the lot model set by MetaQuotes is implemented in the form of a "spread order values grid" defined by parameters MINLOT, MAXLOT and LOTSTEP, it would be more reasonable to calculate the exact value of the lot in those terms. That's why the calculation model is written in those terms.

I don't see any "half-kilometers" or anything else. The only thing is that the code is executed in the style of achieving maximum performance when functions are called once and the resulting values are stored in variables, and each call is executed only after another check when it turns out that the returned value is not an error indicator and it still makes sense to continue calculations. Once it becomes clear that an error has occurred, the computational resources are no longer wasted on useless calls.

To make the code more compact, we could get all the 3 values at once and check all the 3 conditions in one if. But in case of an error on the first call, the other 2 calls would be a waste of computational resources.

Note, that when programming an expression, which uses division by lotStep, we purposely paid attention to the fact that it is used under the if's, which just checked that the value of lotStep is different from 0, that is, division by 0 there can not happen. In principle, the code can still be improved by declaring all the variables as "double" and "int" and "const double" and "const int", protecting itself against itself during further possible code modifications. In particular, if under if's code, which just checked if the value of lotStep variable is different from 0, accidentally in some newly added in this place code mistakenly assign value 0 to this variable, then further division by 0 will occur in expression. If the variable is declared as "const double", then I hope the compiler will immediately report an unauthorized attempt to modify lotStep variable, thereby preventing from making such an error.

So "half-kilometers" are due to severe objective conditions, not someone's whim.

What's the branch called? Well, if you're going to help, do it properly, so that you can really learn something.

 
evillive:
I'm talking about the pitch, not the min. lot, but okay, forget it.
Oh, yes, of course, if you're not writing for yourself, you have to take that into account.
Reason: