Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2549

 
Alexey Viktorov #:

Ещё бывает полезна проверка на мин/мах лот.

double NormaliseVolume(string symb, double volume)
  {
   double volume_step = SymbolInfoDouble(symb, SYMBOL_VOLUME_STEP);
   int ratio = (int)MathRound(volume / volume_step * 10) / 10;
   volume = MathMax(MathMin(ratio * volume_step, SymbolInfoDouble(symb, SYMBOL_VOLUME_MAX)), SymbolInfoDouble(symb, SYMBOL_VOLUME_MIN));
   return(volume);
  }
 
Aleksandr Slavskii #:

Ещё бывает полезна проверка на мин/мах лот.

MathRound() округляет по правилам математики. Но задача стоит округлить до меньшего игнорируя правила округления.

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

Да и в моей версии написано не совсем правильно.

Вот такой вариант будет лучше

double NormalizePrice(double price, string symbol = _Symbol)
 {
  double p = price;
  double tickStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
  p = floor(price/tickStep)*tickStep;
  return(p);
 }/******************************************************************/

Но это было написано много лет взад и править не особо есть желание.

Можно ещё добавить и две функции в одну. Нормализацию цены и нормализацию лота. В общем фантазия безгранична…

 
Aleksandr Slavskii #:

Возможно, но она не соответствует поставленному изначально вопросу.

Задача получить меньшее

0.0151 = 0.01

0.0192 = 0.01

0.0201 = 0.02

0.0349 = 0.03

Мой ответ, отвечает на этот вопрос. Ваш нет)))

Возможно не правильно поставил вопрос, или неправильно прочитан

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

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам

Vitaly Muzichenko, 2025.02.20 08:25

Как округлить число к ближайшему лоту?

Задача получить меньшее

0.0151 = 0.01

0.0192 = 0.01

0.0201 = 0.02

0.0349 = 0.03

Так не получается

  double lotStep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
  double lots = NormalizeDouble(0.0151/lotStep,0)*lotStep; // Print = 0.02

Срезать лишнее после сотых?

Задача:

На каждые 5000 депозита при лоте 0.01, повышать лот на 0.01

Сейчас при росте баланса до 7501, лот получается 0.02, а нужен 0.01, пока баланс не станет 10000

P.S. Наверное как решение, подойдёт

nLot = int(AccountInfoDouble(ACCOUNT_BALANCE)/5000)*0.01
lots = int(9999/5000)*0.01; // 0.01

lots = int(10001/5000)*0.01; // 0.02

Это работает.

В чём вопрос собственно, так это в тестировании ТС

Имеем баланс 100, при тесте баланс растёт до 1500, но весь тест постоянный лот 0.01

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

При наборе баланса она этот участок проходит, потому что баланс больше 100.

Решил использовать увеличения лота на каждые N-единиц баланса. Выход так себе - не совсем, потому как при наборе баланса со 100 до 190, лот будет также 0.01 - и участок будет пройден.

Есть замечательная функция для тестера, снимаю ней лишнее при 5% роста

TesterWithdrawal(_now_pr); // Снимаем

ПРОБЛЕМА:

Оптимизация проходит до конца, оптимизатор выдаёт отличный результат прибыльности, НО, когда запускаешь на этих данных, то где-то по середине стратегия слилась, но до этого успела снять.

Нужно как-то ограничить, если тест до конца не пройден, выдавать результат как "неудачный", хоть и заработано от начального депозита 500%

 
Vitaly Muzichenko #:

Возможно не правильно поставил вопрос, или неправильно прочитан

Это работает.

В чём вопрос собственно, так это в тестировании ТС

Имеем баланс 100, при тесте баланс растёт до 1500, но весь тест постоянный лот 0.01

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

При наборе баланса она этот участок проходит, потому что баланс больше 100.

Решил использовать увеличения лота на каждые N-единиц баланса. Выход так себе - не совсем, потому как при наборе баланса со 100 до 190, лот будет также 0.01 - и участок будет пройден.

Есть замечательная функция для тестера, снимаю ней лишнее при 5% роста

ПРОБЛЕМА:

Оптимизация проходит до конца, оптимизатор выдаёт отличный результат прибыльности, НО, когда запускаешь на этих данных, то где-то по середине стратегия слилась, но до этого успела снять.

Нужно как-то ограничить, если тест до конца не пройден, выдавать результат как "неудачный", хоть и заработано от начального депозита 500%

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

Была у меня такая функция, но потерялась когда сдох SSD. Восстановить не сложно, но неохота…

В общем, делишь депозит на размер минимального… Если запланировал 0.01 на каждые 150 зелёных. Вот и делишь на 150. Потом умножаешь 0.01 на полученное значение. 

Допустим баланс уже составляет 299 зелёных рублей. (int)299/150 = 1

А 399/150 будет 2… И даже 449/150 тоже будет 2

Как-то так.

 
Vitaly Muzichenko #:

Также не тот результат, выдал 0.02

Я ошибся, надо так

NormalizeDouble((0.0151-StepLt/2)/StepLt,0)*StepLt;
 

Это есть причина всей задачи:

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

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам

Vitaly Muzichenko, 2025.02.20 16:42

В чём вопрос собственно, так это в тестировании ТС

Имеем баланс 100, при тесте баланс растёт до 1500, но весь тест постоянный лот 0.01

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

При наборе баланса она этот участок проходит, потому что баланс больше 100.

Решил использовать увеличения лота на каждые N-единиц баланса. Выход так себе - не совсем, потому как при наборе баланса со 100 до 190, лот будет также 0.01 - и участок будет пройден.

Есть замечательная функция для тестера, снимаю ней лишнее при 5% роста

TesterWithdrawal(_now_pr); // Снимаем

ПРОБЛЕМА:

Оптимизация проходит до конца, оптимизатор выдаёт отличный результат прибыльности, НО, когда запускаешь на этих данных, то где-то по середине стратегия слилась, но до этого успела наснимать.

Нужно как-то ограничить, если тест до конца не пройден, выдавать результат как "неудачный", хоть и заработано/снято от начального депозита 500%


 
Vitaly Muzichenko #:

Это есть причина всей задачи:

Можно использовать OnTester() и оптимизировать по пользовательскому критерию.

В OnTester определяете, был слив или нет, если был, то возвращаете отрицательный результат, если не было возвращаете  TesterStatistics(STAT_PROFIT)

 
Aleksandr Slavskii #:
TesterStatistics

Как прервать проход, если если значение баланса упало на 80% от начального депозита? Это должно ускорить оптимизацию

 
Vitaly Muzichenko #:

Как прервать проход, если если значение баланса упало на 80% от начального депозита? Это должно ускорить оптимизацию

У меня как то так сделано

// --- Если просадка больше начального депозита, то выходим - для ускорения оптимизации     
   if(BalansStart<AccountInfoDouble(ACCOUNT_BALANCE)-AccountInfoDouble(ACCOUNT_EQUITY))
   {
      if(CountMarketOrder_OB>0)ClosePositions(BUY);
      if(CountMarketOrder_OS>0)ClosePositions(SELL);
      TesterWithdrawal(AccountInfoDouble(ACCOUNT_EQUITY));
      TesterStop();
   }
 
Aleksey Vyazmikin #:

У меня как то так сделано

Проверю, спасибо