Проблема перевода с МТ4 на МТ5. Или, точнее, невозможность без'ошибочного исполнения некоторых алгоритмов в МТ5. - страница 9

 
Vict:

Да, с исключениями код много проще и чище, постоянная проверка ошибок превращает его в портянку. Но в мкл и без исключений проблем валом. Не потянули разработчики кресты.

А на мой взгляд, разницы никакой нет.

С кодами возврата - тебе надо писать макрос типа RETURN_IF_BAD_RESULT() и тыкать его во все функции, возвращающие результат.

C исключениями - тебе надо писать секции TRY-CACTH. Плюс - помнить, какие функции бросают исключение, какие не бросают, добавлять в код комментарии // exception

Что то - портянка, что то... 

 
Vict:

Да, с исключениями код много проще и чище, постоянная проверка ошибок превращает его в портянку. Но в мкл и без исключений проблем валом. Не потянули разработчики кресты.

не, про исключения я даже не заикаюсь...как вариант найдется "злобный буратино" , который будет все вылеты за предел массива в исключения оборачивать )))

имхо,нужна просто возможность разорвать все return с выходом в ОС...ну пусть это будет некий Exit() , Вы правильно поняли идею, не хочу бесконечные портянки кода плодить - смысла нет постоянно все вызовы функций оборачивать в 

void OnStart()
{
if(!MyFuncReadOHLC_1()) return;
if(!MyFuncReadOHLC_2()) return;
....
}
 
Georgiy Merts:

А на мой взгляд, разницы никакой нет.

С кодами возврата - тебе надо писать макрос типа RETURN_IF_BAD_RESULT() и тыкать его во все функции, возвращающие результат.

C исключениями - тебе надо писать секции TRY-CACTH. Плюс - помнить, какие функции бросают исключение, какие не бросают, добавлять в код комментарии // exception

Что то - портянка, что то... 

С исключениями мне не надо ничего помнить, часто даже TRY-CACTH не нужен (просто завершится программа аварийно), это ИСКЛЮЧИТЕЛЬНАЯ ситуация и в норме не случается, не надо превращать их в if-else блоки. Например - вот писал я для себя подобие vector (жалкое подобие), вместо выброса исключения при неудачных аллокациях пришлось вкрутить operator! и дёргать его при каждой вставке (хотя я забиваю на это), сомнительная выгода.

 
Igor Makanu:

имхо,нужна просто возможность разорвать все return с выходом в ОС...

Да, тоже ничего, странно, что этого нет ...

 
Vict:

Да, тоже ничего, странно, что этого нет ...

мне просто не удобно короткие программы с читаемым кодом превращать в некого монстра, вот типовой шаблон под MQL4 - проверили "новый бар", проверили индикаторы - работаем или не работаем с ордерами:

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   ENUM_CMD CMD1,CMD2,CMD3;
   CMD1 = ind1();
   CMD2 = ind2();
   CMD3 = ind3();
   if(NewBar())
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }
//+------------------------------------------------------------------+

в этом примере индикаторы "дергаю каждый тик", т.к. по разным ТФ работают... в общем не важно

я использую данные OHLC в ind1(),ind2(),ind3() и в NewBar() 

если я получил ошибку доступа к таймсерией в одном вызове функции, какой смысл дальше продолжать выполнение этого кода? - нужно выйти в ОС и ждать новый тик, т.е. в любом  ind1(),ind2(),ind3() и в NewBar()  я проверяю GetLastError() и получив ошибку сразу Exit() в ОС с записью в лог эксперта

 
Vict:

С исключениями мне не надо ничего помнить, часто даже TRY-CACTH не нужен (просто завершится программа аварийно), это ИСКЛЮЧИТЕЛЬНАЯ ситуация и в норме не случается, не надо превращать их в if-else блоки. Например - вот писал я для себя подобие vector (жалкое подобие), вместо выброса исключения при неудачных аллокациях пришлось вкрутить operator! и дёргать его при каждой вставке (хотя я забиваю на это), сомнительная выгода.

Ну, даешь, дружище...

Говоришь, "не надо ничего помнить", и ТУТ ЖЕ продолжаешь - ЧАСТО даже TRY-CATCH не нужен.   Вот это же самое "часто" и означает, что где-то блок нужен, а где-то не нужен, и тебе это надо помнить.  Ситуация совершенно такая же, как и с кодами возврата - если запросил какой-то ресурс, а возникло исключение (была возврщена ошибка), от ресурсов надо отказаться. То есть, в любом случае - надо помнить, какая функция бросает исключение, а какая нет.

Да и про "исключительную ситуацию"... Ну как сказать... Отсутствие котировок - вроде как вполне разумный повод для бросания исключения, но разве это "исключительная ситуация" ?

 
Igor Makanu:

мне просто не удобно короткие программы с читаемым кодом превращать в некого монстра, вот типовой шаблон под MQL4 - проверили "новый бар", проверили индикаторы - работаем или не работаем с ордерами:

в этом примере индикаторы "дергаю каждый тик", т.к. по разным ТФ работают... в общем не важно

я использую данные OHLC в ind1(),ind2(),ind3() и в NewBar() 

если я получил ошибку доступа к таймсерией в одном вызове функции, какой смысл дальше продолжать выполнение этого кода? - нужно выйти в ОС и ждать новый тик, т.е. в любом   ind1(),ind2(),ind3() и в NewBar()  я проверяю GetLastError() и получив ошибку сразу Exit() в ОС с записью в лог эксперта

А в чем проблема вызвать return(iErrrCode) ?

 
Georgiy Merts:

А в чем проблема вызвать return(iErrrCode) ?

хм, попробую в коде показать, вот переписал код с выходом если была некорректная обработка данных OHLC, будет примерно так:

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   bool nb;
   ENUM_CMD CMD1,CMD2,CMD3;
   if(!ind1( CMD1 )) return;
   if(!ind2( CMD2 )) return;
   if(!ind3( CMD3 )) return;
   if(!NewBar( nb )) return;
   
   if( nb )
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }

теперь по ссылке получаю значения функций и выхожу если функция была некорректно отработана (в контексте обсуждения - терминал не подготовил исторические данные по ТФ)

 
Georgiy Merts:

Ну, даешь, дружище...

Говоришь, "не надо ничего помнить", и ТУТ ЖЕ продолжаешь - ЧАСТО даже TRY-CATCH не нужен.   Вот это же самое "часто" и означает, что где-то блок нужен, а где-то не нужен, и тебе это надо помнить.  Ситуация совершенно такая же, как и с кодами возврата - если запросил какой-то ресурс, а возникло исключение (была возврщена ошибка), от ресурсов надо отказаться. То есть, в любом случае - надо помнить, какая функция бросает исключение, а какая нет.

Да и про "исключительную ситуацию"... Ну как сказать... Отсутствие котировок - вроде как вполне разумный повод для бросания исключения, но разве это "исключительная ситуация" ?

Вы как-то по своему исключениями пользовались, неправильно, видимо. Вообще не надо заморачиваться по поводу - бросает ли эта функция исключение или нет? Наличие TRY-CATCH - опционально. А для отсутствия проблем с ресурсами, осильте RAII https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%B0_%D0%B5%D1%81%D1%82%D1%8C_%D0%B8%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F, раскручивание стека всё само подчистит.

Да и про "исключительную ситуацию"... Ну как сказать... Отсутствие котировок - вроде как вполне разумный повод для бросания исключения, но разве это "исключительная ситуация" ?
Исключительность - на усмотрение автора кода, но исключение не должны стать аналогом if-else, конечно.
 

Странно, но не додумался раньше сделать:

// Немедленное завершение, деструкторы не вызываются
void abort() {Alert(1/(uint)MathAbs(0));}

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

Причина обращения: