I. Вызов функции. Последовательность набор текста. Шаг 1. SomeFunction(); Шаг 2. SomeFunction(param1, param2, param3, ...); II. Написание if блока. Последовательность набор текста. Шаг 1. if () { } Шаг 2. if (a < b) { } Шаг 3. if (a < b) { // comment c = b - a; }Т.е. всегда ставятся ограничивающие скобки, а затем "кишки" внутри них. Тогда проблем со скобками практически не бывает, если не удалить часть текста.
Правда, в некоторых средах разработки, если встать курсором на одну из скобок, то парные скобки очеркиваются цветом:
![](https://c.mql5.com/mql4/forum/2006/11/vs2005.png)
В коде:
if (a1 < b1) { // code c1 = a1 - b1; } if (a2 < b2) { // code c2 = a2 - b2; } if (a3 < b3) { // code c3 = a3 - b3; }Пропустим первую правую фигурную скобку (выделена цветом). По идее только мы знаем (точнее, думаем), что она должна быть здесь.
Но ведь компилятор, который обнаружит это в конце кода, мог подумать и иначе:
if (a1 < b1) { // code c1 = a1 - b1; if (a2 < b2) { // code c2 = a2 - b2; } if (a3 < b3) { // code c3 = a3 - b3; } }А как это можно узнать наверняка, какой должен быть код?
ОК, с фигурными скобками понятно. Но я говорил о круглой скобке, парную к которой компилятор не нашел. Пардон, что не
указал это в первом посте.
Ставим вопрос иначе: возможен ли в MQL4 синтаксически правильный код, в котором фигурная
скобка находится между парными круглыми?
Я в этом сильно сомневаюсь. Если так, то закрывающую круглую
компилятор должен легко обнаруживать не в конце программы,
как сейчас, а как минимум сразу же после функции, в которой она
должна быть.
Насчет приема разработчиков со стажем: я тоже так же и делаю
- сразу ставлю парные (в том числе и круглые). Но, как назло, пришлось
подредактировать саму формулу, и я случайно пропустил закрывающую
круглую. Думаю, такая ситуация встречается не только у новичков.
..
Наверное, это место можно указать раньше, чем в конце программы. Просто до этого не дошла потребность и необходимость в редакторе у команды разработчиков.
А подсветку парных скобок IDE среда Visual Studio 2005 делает и для круглых скобок, и для квадратных. Возможно, в будущих версиях MT4 редактора появится и это.
![](https://c.mql5.com/mql4/forum/2006/11/vs2005_1.png)
Кроме того, фигурные скобки, помимо блока, обрамляют также объявление массива-константы. См., например, хелп к ArrayMaximum().
Аналогичная ошибка.
Информация неполна. Нужен полный код. Мало ли что Вы там вне этого куска наворотили.
И еще: Вы так всегда свой код оформляете? Он же практически нечитаем из-за отсутствия отступов...
мне нужно, что бы советник открывал сделку по пересечению МА, код есть тут: http://amadey-mf.livejournal.com/84565.html
но там и выход идет по обратному пересечению МА, а нужно по стопу, тейку, тралу
вторую часть кода взял тут: http://www.profiforex.org/pages/Learning/prog
сложил это вместе, следует сделать оговорку, я впервые работаю с кодом
вот полный код:
//+------------------------------------------------------------------+ //| MACD Sample.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ extern double TakeProfit = 500; extern double Lots = 0.1; extern double Stoploss = 30; extern double TrailingStop = 30; // Это переменные, которые будут // отображаться во время // соединения эксперта с графиком //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { double a; int b; int total, ticket, cnt; // Просто переменные для использования в программе if(Bars<100) { Print("bars less than 100"); return(0); } // Это условие проверяет, есть ли в истории графиков более 100 свечей и если нет, // выдает ошибку. Требуется для того, чтобы обратить ваше внимание на проблему // недостатка информации if(TakeProfit<10) { Print("TakeProfit less than 10"); return(0); } // Это условие проверяет уровень Тейк-профита (одной из внешних переменных, // которая управляет уровнем фиксации прибыли. Нужен для того, чтобы проверить, не // выставили ли вы уровни фиксации прибыли на неразрешенном для вашего ДЦ // уровне. Нужен лишь для того, чтобы при НЕсрабатывании советника, вы четко знали // в чем здесь ошибка. Очень советую ставить. total=OrdersTotal(); if(total<1) // Эта проверка нужна для того, чтобы не открывать сразу нескольких одинаковых позиций. Если ее не будет, то, скажем, если ваш эксперт срабатывает, когда стохастик находится в зоне перекупленности, то он будет совершать сделку на каждом тике, пока не истратит всю маржу. // Поэтому, чтобы ограничить количество открываемых позиций, ставят данный // ограничитель. Если он стоит, то советник не будет открывать более определенного // количества позиций <х { // no opened orders identified if(AccountFreeMargin()<(1000*Lots)) { Print("We have no money. Free Margin = ", AccountFreeMargin()); return(0); } // Еще один вспомогательный кусок кода. Если средств на счете недостаточно, он // выдаст ошибку. Данный кусок полностью бесполезен, если советник работает // в реальном времени, но очень полезен при тестинге на истории. // кусок кода Амадея, параметры мув bool SellOp=false; bool BuyOp=false; double MAFast2=NormalizeDouble(iMA(NULL,0,MODE_SMA,PRICE_CLOSE,2),Digits); // быстрая прошлого бара double MAFast3=NormalizeDouble(iMA(NULL,0,MODE_SMA,PRICE_CLOSE,0),Digits); // быстрая текущего бара double MASlow2=NormalizeDouble(iMA(NULL,0,MODE_SMA,PRICE_CLOSE,2),Digits); // медленная прошлого бара double MASlow3=NormalizeDouble(iMA(NULL,0,MODE_SMA,PRICE_CLOSE,0),Digits); // медленная текущего бара if ( // проверка условий на покупку (MAFast2<=MASlow2)&& (MAFast3>MASlow3)) { BuyOp=true; } // Наконец, мы добрались до самого интересного. Вместо этих иксов, надо вставить // условие, при котором происходит покупка. { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-Stoploss*Point, Ask+TakeProfit*Point ,"comment",16384,0,Green); // Это условия покупки. В принципе, менять здесь ничего не надо, но для расширения // кругозора, я расшифрую что здесь написано. Здесь сказано, что надо купить // (OP_BUY) текущий символ (пара валют, к графику которого прикреплен советник), // размер сделки Lots (переменная заданная в начале). Цена по рынку, с // проскальзыванием 3, и со стоп-лосом и тейк-профитом, выставленными в // начале, сделка будет с комментарием "comment", с определяющим числом 0, и на // месте покупки, на графике, будет зелененькая срелочка с определяющим кодом // 16384 if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice()); } else Print("Error opening BUY order : ",GetLastError()); return(0); } // Этот блок нужен только для того, чтобы записать в журнале, все ли прошло гладко. // Или, в противном случае, записать ошибку, из-за которой что-то не получилось. // Теперь тоже самое со ставкой на продажу. Вместо YYYYYYYY - условия if ( // проверка условий на продажу (MAFast2>=MASlow2)&& (MAFast3<MASlow3)) { SellOp=true; } { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+Stoploss*Point,Bid-TakeProfit*Point,"macd sample",16384,0,Red); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice()); } else Print("Error opening SELL order : ",GetLastError()); return(0); } return(0); } // Теперь о выходе. Тут также ничего не изменилось, просто RRRRRRR - условие // закрытия сделки по BUY, ZZZZZZZZ - по SELL for(cnt=0;cnt //с помощью for'a перебираются все открытые пощиции { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()<=OP_SELL && // check for opened position OrderSymbol()==Symbol()) // check for symbol { if(OrderType()==OP_BUY) // long position is opened { // should it be closed? if (BuyOp) // если условия на покупку выполняются (вставка кода тест МА) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position return(0); // exit } // check for trailing stop if(TrailingStop>0) { if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss() { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green); return(0); } } } } else // Тоже самое с короткой позицией { // should it be closed? if (SellOp) // если условия на продажу выполняются (вставка кода тест МА) { OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position return(0); // exit } // check for trailing stop if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red); return(0); } } } } } } } return(0); }
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Вопрос разработчикам: это действительно очень трудно - отловить эту ошибку именно после той функции, в которой она встретилась, а не после окончания кода? Ведь понятно, что если после незакрытой скобки встречается объявление функции, то это уже нарушение синтаксиса... Если я чешу лабуду - приведите опровергающий пример, и я с этим смирюсь.