Пишу простой советник - нужна помощь

 

Добрый день!

В дебрях кодабазы нашел индикатор один от авторы ssd. Он же описывал стратегию работы по нему - линия индикатора пересекает нолевую линию сверху вниз - продаем и нааоборот, снизу вверх - покупаем. Зарытие позиций происходит по противосигналу от индикатора - обратное пересечение нулево линии. В принципе наверно будет лучше, если противосигнал будет зарывать открытый ордер (buy или sell) и отрывать в противоположную сторону... таким образом будет получаться замкнутый круг ордеров.

Помогите с кодом. Я что-то своял, выдрав отдельные полезные куски из других советников, но что-то не клеится у меня - выдает ошибки, то из-за такой скобки "{", то из-за такой "("

Файлы:
f0t0.mq4  5 kb
cl_fatl.mq4  9 kb
fatl.mq4  4 kb
 
Посмотрите тут
 
ForexTrader2008:
Посмотрите тут

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

Ну, во первых, для чего вам функция CalculateCurrentOrders(string symbol) если она нигде не используется?

Во вторых, строку if(OrderSymbol()==Symbol() && OrderMagicNumber()
нужно как то завершить, например так:

if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicbuy && OrderMagicNumber()==magicsell)

ну, и так далее, проверяйте, где что не закрыто

 

Подправил код и внес изменения небольшие. Компилируется без ошибок. Но что-то не так с закрытием ордеров. В тестере они открываются, но не закрываются. Подскажите как реализовать принудительное закрытие оредров по противосигналу пересечения нулевой линии по параметру close. Выставляю весь код сюда, может опытные глаза заметят какие-еще косяки

extern bool MM=true;
extern double start_lot=0.01;
extern double min_lot=0.01;
extern int magicsell=1111;
extern int magicbuy=2222;
extern int delta=100;
extern int History = 1440;
extern bool close = true; // разрешение принудительного закрывания позиции
double cl_0, cl_1,lot[0];
int res, MinBar, last_error;
string day;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----Иниуиализация переменных
   MinBar = History + 1;  
//---- Заверешение инициализации переменных
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
 {
 ///////////Money Management

if (MM)
   {
   lot[0]=start_lot*MathFloor (AccountBalance()/delta);
   if (lot[0]<start_lot) lot[0]=start_lot;
   if (lot[0]>MarketInfo(Symbol(),MODE_MAXLOT)) lot[0]=MarketInfo(Symbol(),MODE_MAXLOT);
   }
   else lot[0]=start_lot; 
   

////////////////Проверка сигнала на открытие


  {   
 //---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//---- получение данных с индикатора 
   cl_0=iCustom(NULL,0,"CL_FATL",0,0); //на текущем баре
   cl_1=iCustom(NULL,0,"CL_FATL",0,1); // на текущем+1
//---- на продажу
   if(cl_1>0 && cl_1-cl_0 >=0&& cl_0<=0) //ищем пересечение нулевой линии, чтобы продать
     {
      RefreshRates();
      res=OrderSend(Symbol(),OP_SELL,start_lot,Bid,5,0,0,"FZTZ",magicsell,Red); last_error = GetLastError();
      if (res<0)
      {Print("Невозможно открыть из-за #",GetLastError());
        return(0);
       }
      }
//---- покупку
   if(cl_1<0 && cl_0-cl_1<=0 && cl_0>=0) //ищем пересечение нулевой линии, чтобы купить
     {
     RefreshRates();
     res=OrderSend(Symbol(),OP_BUY,start_lot,Ask,5,0,0,"FZTZ",magicbuy,Blue); last_error = GetLastError();
      if (res<0)
      {Print("Невозможно открыть из-за #",GetLastError());
        return(0);
       }
      }
///////// Проверка сигнала на закрытие
  {
   //---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)        break;
      if(OrderMagicNumber()|| OrderSymbol()!=Symbol()) continue;
      //---- check order type 
      if (OrderType()==OP_BUY)
        {
         if(cl_0<=0) 
                    OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         return;
        }
      if (OrderType()==OP_SELL)
         {
         if(cl_0>=0)
                    OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         return;
         }
      }
   }
  }
}
//+------------------------------------------------------------------+
 
evbut:

Подправил код и внес изменения небольшие. Компилируется без ошибок. Но что-то не так с закрытием ордеров. В тестере они открываются, но не закрываются. Подскажите как реализовать принудительное закрытие оредров по противосигналу пересечения нулевой линии по параметру close. Выставляю весь код сюда, может опытные глаза заметят какие-еще косяки



>> extern bool close = true; // разрешение принудительного закрывания позиции

Эту строку лучше изменить - Взять другое имя переменной. Есть массив Close[]. Если переменная будет иметь имя close, то легко запутаться

Код:

res=OrderSend(Symbol(),OP_SELL,start_lot,Bid,5,0,0,"FZTZ",magicsell,Red); last_error = GetLastError();
      if (res<0)
      {Print("Невозможно открыть из-за #",GetLastError());
        return(0);
       }

Лучше заменить на

res=OrderSend(Symbol(),OP_SELL,start_lot,Bid,5,0,0,"FZTZ",magicsell,Red);
if (res<0){
  Print("Невозможно открыть из-за #",GetLastError());
}

Это потому, что после выполнения  last_error = GetLastError(); в случае возникновения ошибки конструкция Print("Невозможно открыть из-за #",GetLastError()); уже не покажет номер ошибки, так как последующий вызов GetLastError() вернет значение 0.

А вот это скажите, что?

if(Volume[0]>1) return;

Если объём на нулевой свече больше 1, то ретурн. Это что? Ну возникла нулевая свеча, ну пришёл с первым тиком объём более 1. Поскольку ретурн, то весь низлежащий код выполняться не будет. И вот ещё что, поскольку этот код исполняетя в функции start(), а эта функция имеет тип int, то ретурн должен возвращать целочисленное значение. Используйте return(0); Это даст знать терминалу, что функция start() была прервана без ошибок.

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

 
drknn:


>> extern bool close = true; // разрешение принудительного закрывания позиции

Эту строку лучше изменить - Взять другое имя переменной. Есть массив Close[]. Если переменная будет иметь имя close, то легко запутаться

Код:

Лучше заменить на

Это потому, что после выполнения last_error = GetLastError(); в случае возникновения ошибки конструкция Print("Невозможно открыть из-за #",GetLastError()); уже не покажет номер ошибки, так как последующий вызов GetLastError() вернет значение 0.

А вот это скажите, что?

Если объём на нулевой свече больше 1, то ретурн. Это что? Ну возникла нулевая свеча, ну пришёл с первым тиком объём более 1. Поскольку ретурн, то весь низлежащий код выполняться не будет. И вот ещё что, поскольку этот код исполняетя в функции start(), а эта функция имеет тип int, то ретурн должен возвращать целочисленное значение. Используйте return(0); Это даст знать терминалу, что функция start() была прервана без ошибок.

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

if(Volume[0]>1) return; - от это избавился, вместо close буду использовать closepos

ткните носом в каком месте я закрываю программу? чот не соображу. вы имеете в виду в этих местах кода?

if (OrderType()==OP_BUY)
        {
         if(cl_0<=0) 
                    OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         return;
        }
 
evbut:

if(Volume[0]>1) return; - от это избавился, вместо close буду использовать closepos

ткните носом в каком месте я закрываю программу? чот не соображу



Существует такая весчь, как подпрограмма. Все подпрограммы делятся на 2 класса - процедуры и функции. Если подпрограмма должна вернуть в основную программу какое-то значение, то такая подпрограмма называется функцией. Если не должна ни чего возвращать, то она называется процедурой.

Функция start() - это подпрограмма, которая вызывается из терминала. Терминал для этой функции является основной программой. Поскольку эта функция целочисленная, то и возвращать она должна целочисленное значение.

Для того, чтоб любую подпрограмму можно было экстренно прервать, существует команда return. Ну так вот, программист изначально задумывает, что именно должна вернуть функция в основную программу, если происходит экстренное завершение. В вашем случае нужно использовать команду return(0).

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

Теперь понятно где Вы прерываете работу функции start()? 

 
Вы хотите закрыть ордера при наступлении некоторых условий. При наступлении же других условий Вы хотите, чтоб ордера не закрывались. Чтоб осуществить задуманное, Вы используете следующую конструкцию: "Если объём на нулевой свече больше единицы, то закрытие ордеров запрещено. Иначе - ордера закрыть!" Теперь ответьте мне на вопрос, какой объём придёт в терминал на первом тике каждой нулевой свечи, если терминал работает в режиме реалтайм?
 
по любому больше единицы
Причина обращения: