Ошибки, баги, вопросы - страница 2492

 

Хочу ещё раз поднять тему "проблема средневзвешенной цены"  в описании CPositionInfo, команды PriceOpen()

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Сервисдеск. Жалобы, предложения.

Francuz, 2019.06.13 11:36

Ошибка в описании стандартной библиотеки

Конкретно в описании CPositionInfo, команды PriceOpen()

https://www.mql5.com/ru/docs/standardlibrary/tradeclasses/cpositioninfo/cpositioninfopriceopen

Возвращаемое значение не "цена открытия", а "средневзвешенная цена открытия"

Для примера:

Открываем позицию на 1 лот по цене 61532. PriceOpen() в этом случае вернёт 61532.

Дополнительно увеличиваем позицию ещё на 1 лот по цене 61615. PriceOpen() в этом случае вернёт средневзвешенную цену двух лотов 61573,5, а не цену открытия позиции.

Хотелось бы видеть не только исправление одного слова в описании, но и краткое пояснение-иллюстрацию.


Проблема средневзвешенной цены открытия имеет неприятные последствия.

Дело в том что если позицию увеличить до количества при котором невозможно деления без остатка, то начинают делится копейки, что при округлении происходит их потеря. И в итоге в конце не сходится баланс. Все сделки производятся сугубо целыми рублями, а итоговый баланс не сходится из-за потерянных копеек.

Схема воспроизведения ошибки с потерей копейки в балансе, даже при ручной торговле.

Купить 1 лот по чётной цене, купить 1 лот по нечётной цене, купить 1 лот по чётной цене, продать 1 лот, продать 1 лот, продать 1 лот.

Дополнительно разъясню что за ошибка:

Пояснения

Столбец "А" - это фактаж (цены совершения сделок). Столбец "Б" это производное от столбца "А" с потерей точности. Любой квалифицированный бухгалтер пояснит, что сводить баланс нужно только по фактажу, и ни в коем случае не по производным с потерей точности.

Копейка не просто неверно отображается в терминале, она реально перемещается между счетами клиента и брокера. Любой юрист или налоговый инспектор вам пояснит, что это "залёт" и данный факт может быть предметом юридического разбирательства между трейдером и брокером.

Что это?

Подтверждая утверждение, что копейки реально потерянны, является проведение коррекции спустя значительное время. Что за коррекция? Почему такими странными объёмами?

Документация по MQL5: Стандартная библиотека / Торговые классы / CPositionInfo / PriceOpen
Документация по MQL5: Стандартная библиотека / Торговые классы / CPositionInfo / PriceOpen
  • www.mql5.com
Стандартная библиотека / Торговые классы / CPositionInfo / PriceOpen - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Francuz:

Хочу ещё раз поднять тему "проблема средневзвешенной цены"  в описании CPositionInfo, команды PriceOpen()

Это проверим.

Вы нам очень поможете, если дадите в личке временно инвесторский пароль на пару часов. Мы хотим проверить цены и возможные округления в таблице ваших сделок. К вам обратятся.

Подтверждая утверждение, что копейки реально потерянны, является проведение коррекции спустя значительное время. Что за коррекция? Почему такими странными объёмами?

Коррекция - это другое.

 
MetaQuotes Software Corp.:

Это проверим.

Вы нам очень поможете, если дадите в личке временно инвесторский пароль на пару часов. Мы хотим проверить цены и возможные округления в таблице ваших сделок. К вам обратятся.

Коррекция - это другое.

Открытие Брокер

Сервер : Open-Demo
Login : 1010955
Password : B7NhSEwx
Investor  : B7NhSEwx (read only password)

На демо пароль инвестора совпадает с паролем аккаунта, по этому различия между ними нет.
 

По горячим следам: https://www.mql5.com/ru/signals/596871

Копейки исчезли...

Торговые сигналы для MetaTrader 5: Error
Торговые сигналы для MetaTrader 5: Error
  • www.mql5.com
Символ Сделки Sell Buy Символ Общая прибыль, USD Убыток, USD Прибыль, USD Символ Общая прибыль, pips Убыток, pips Прибыль, pips Точечные графики распределения MFE и MAE Для каждой открытой позиции в течение ее жизни записываются значения максимальной прибыли (MFE) и максимального убытка (MAE). Эти показатели дополнительно...
 
Ilyas:

Если мне не изменяет память, то несколько лет назад мы с Вами обсуждали уже эту особенность, правда речь тогда шла о том, какую перегрузку лучше вызывать ближайшую по наследованию или более точную по параметрам.

Да... помню... С++ использует ближайшую по наследованию перегрузку - чтобы последующие изменения в базовых классах (появление новой перегрузки - более точной по параметрам) не влияли на порядок вычислений в производных (не вызывалась бы эта новая перегрузка)

Обратите еще пожалуйста внимание на следующее:

void f( int a,     int b = 2 ); //(1)
//...
void f( int a = 1, int b     ); //(2) //Error: 'b' - missing default value for parameter
//...
void f( int a, int b ) {}

Казалось бы мелочь - напиши

void f( int a = 1, int b = 2 ); //(2) //нормально

и радуйся, но смысл как раз в том что не нужно дважды и более раз писать b = 2, а значит при последующем изменении на допустим: b = 3 - нужно будет поменять только в одном месте (а не в двух и более), а значит (с учетом распределенности программы) нельзя забыть это сделать в других местах

[Удален]  

Подскажите

2019.07.02 19:41:56.305 my_HMA7C_121 (FTSE100,H6)       BarsCalculated() вернул -1, код ошибки 4806

ERR_INDICATOR_DATA_NOT_FOUND

4806

Запрошенные данные не найдены

При этом индикатор на графике отображается нормально.

Куда копать?

 
Сергей Таболин:

Куда копать?

Нужно подождать - кабинка занята (данные на момент обращения не были рассчитаны)

 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL5 MT5 MetaTrader 5".
 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL5 MT5 MetaTrader 5".
[Удален]  

Словил ошибку

...tested with error "critical runtime error 502 in OnTester function (array out of range, module ....ex5, file ....mqh, line 237, col 51...

Вот сам код:

//+-------------------
   // коррекция
   int      correcton_index[3];
            correcton_index[0]   = 1;
            correcton_index[1]   = (int)MathRound(balance_arr_size / 2);
            correcton_index[2]   = balance_arr_size;
   int      correcton_index3[5];
            correcton_index3[0]  =  1;
            correcton_index3[1]  = (int)MathRound(correcton_index[1] / 2);
            correcton_index3[2]  = correcton_index[1];
            correcton_index3[3]  = (int)MathRound((balance_arr_size - correcton_index[1]) / 2);
            correcton_index3[4]  = balance_arr_size;
   int      correcton_index7[9];
            correcton_index7[0]  = 1;
            correcton_index7[1]  = (int)MathRound(correcton_index3[1] / 2);
            correcton_index7[2]  = correcton_index3[1];
            correcton_index7[3]  = (int)MathRound((correcton_index3[2] - correcton_index3[1]) / 2);
            correcton_index7[4]  = correcton_index3[2];
            correcton_index7[5]  = (int)MathRound((correcton_index3[3] - correcton_index3[2]) / 2);
            correcton_index7[6]  = correcton_index3[3];
            correcton_index7[7]  = (int)MathRound((balance_arr_size - correcton_index3[3]) / 2);
            correcton_index7[8]  = balance_arr_size;
   
   double   correcton   = NormalizeDouble((balance_arr[correcton_index[2]-1] / balance_arr[correcton_index[1]-1]) / (balance_arr[correcton_index[1]-1] / balance_arr[correcton_index[0]-1]),8);
   double   correcton3[3];
   double   correcton7[7];
   double   crr         = 1;
   ArrayInitialize(correcton3,EMPTY_VALUE);
   ArrayInitialize(correcton7,EMPTY_VALUE);
   for(int i = 0; i < 3; i++)
   {
      correcton3[i]  = NormalizeDouble((balance_arr[correcton_index3[i+2]-1] / balance_arr[correcton_index3[i+1]-1]) / (balance_arr[correcton_index3[i+1]-1] / balance_arr[correcton_index3[i+0]-1]),8);
      crr            = NormalizeDouble(crr * correcton3[i],8);
   }
   correcton         = NormalizeDouble(correcton * crr,8);
   crr               = 1;
   for(int i = 0; i < 7; i++)
   {
      correcton7[i]  = NormalizeDouble((balance_arr[correcton_index7[i+2]-1] / balance_arr[correcton_index7[i+1]-1]) / (balance_arr[correcton_index7[i+1]-1] / balance_arr[correcton_index7[i+0]-1]),8);
      crr            = NormalizeDouble(crr * correcton7[i],8);
   }
   correcton         = NormalizeDouble(correcton * crr,8);

При i = 6 correcton_index7[i+2] (i+2=8) ну никак не может выйти за пределы массива. Тем более что аналогичный предыдущий цикл не ругается. Чего я не вижу?