Изучаем язык программирования MQL4

BorisSedov

Активный участник
Следующая задача.
Напишите скрипт, который закрывает все открытые ордера на счете.
(перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
 

BorisSedov

Активный участник
Функция OrderSelect​
bool OrderSelect(
int index, // индекс или тикет ордера
int select, // флаг способа выбора
int pool=MODE_TRADES // источник данных для выбора
);
Выбирает ордер для дальнейшей работы с ним.

Функция OrderClose​
bool OrderClose(
int ticket, // номер ордера
double lots, // количество лотов
double price, // цена закрытия
int slippage, // максимальное проскальзывание
color arrow_color // цвет
);
Осуществляет закрытие ордера.
(более подробное описание любой функции, можно всегда найти в Справочнике MQL4)
 
Последнее редактирование:

Ugar

Гуру форума
На будущее, когда научитесь минимуму, стоит задуматься о том что торговые операции выполняются не в своём компьютере. Мы только отправляем приказ, а исполняет и отвечает сервер. А между линия связи, в которой может быть что угодно.
 

DomovenokBrest

♔♕♖♗♘♙
Следующая задача.
Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете, и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта, на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно.
Я сделал так:

C++:
#property strict

input int       Magic           = 72493;    // Magic Number:
input double    lot             = 0.1;      // Volume:
input int       Slippage        = 3;        // Slippage:


//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете,
// и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта,
// на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно
{


//--- получим минимальное значение Stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- вычисленные значения цен SL и TP должны быть нормализованы
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
double minlot = MarketInfo(Symbol(),MODE_MINLOT); // узнаем каков минимальный размер лота
double maxlot = MarketInfo(Symbol(),MODE_MAXLOT); // узнаем каков максимальный размер лота
if (lot >= minlot && lot <= maxlot )
  {

//--- размещаем рыночный ордер на покупку 1 лота
if (OrdersTotal()<1)
{
   int ticket=OrderSend(Symbol(),OP_BUY,lot,price,Slippage,stoploss,takeprofit,"My order BUY",Magic,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend завершилась с ошибкой #",GetLastError());
     }
   else
      Print("Функция OrderSend успешно выполнена");
      }
  }
else {return;}
}

Но во вкладке эксперты выдало ошибку 136 (нет цены) - вполне вероятно, сделал и запустил скрипт сейчас.
А в журнале выдало запись:
2019.06.28 23:39:15.988 '122577': order buy 0.10 GBPUSD.e opening at 1.26935 sl: 1.26914 tp: 1.26914 failed [Off quotes]
 

Вложения

  • Снимок.JPG
    Снимок.JPG
    22,7 КБ · Просмотры: 10
  • Снимок1.JPG
    Снимок1.JPG
    19,8 КБ · Просмотры: 9
Последнее редактирование:

BorisSedov

Активный участник
Я сделал так:
Но во вкладке эксперты выдало ошибку 136 (нет цены) - вполне вероятно, сделал и запустил скрипт сейчас.
А в журнале выдало запись:
2019.06.28 23:39:15.988 '122577': order buy 0.10 GBPUSD.e opening at 1.26935 sl: 1.26914 tp: 1.26914 failed [Off quotes]
Отлично! (y)
 

DomovenokBrest

♔♕♖♗♘♙
Следующая задача.
Напишите скрипт, который закрывает все открытые ордера на счете.
(перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
Как то так...

C++:
#property strict


int slipp;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который закрывает все открытые ордера на счете.
// (перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
{
bool   resalt;
int    OT, Ticket, i;
for(i = OrdersTotal()-1; i >= 0; i--) // Переменной i присваиваем значение OrdersTotal()-1. После этого проверено условие что i>=0,
      {                               // если это так, то выполняется один раз все, что написано внутри тела цикла
        if(OrderSelect(i, SELECT_BY_POS))
          {
          OT = OrderType();           //Переменной OT присваиваем значение OrderType()
          Ticket = OrderTicket();     //Переменной Ticket присваиваем значение OrderTicket()
          if(OT == OP_BUY)            // Если тип операций для функции OrderType() выбран OP_BUY (покупка), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELL)           // Если тип операций для функции OrderType() выбран OP_SELL (продажа), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          }
          else {return;}
      }
}
}
 

gravity

Местный знаток
Я сделал так:

C++:
#property strict

input int       Magic           = 72493;    // Magic Number:
input double    lot             = 0.1;      // Volume:
input int       Slippage        = 3;        // Slippage:


//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Нужно написать скрипт, который сначала проверяет наличие открытых ордеров на счете,
// и если открытых ордеров нет – открывает один ордер Buy. Если в момент запуска скрипта,
// на счете уже есть открытый ордер/ордера, то новый открываться не должен. Уровни СтопЛосс и ТейкПрофит устанавливать не нужно
{


//--- получим минимальное значение Stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- вычисленные значения цен SL и TP должны быть нормализованы
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
double minlot = MarketInfo(Symbol(),MODE_MINLOT); // узнаем каков минимальный размер лота
double maxlot = MarketInfo(Symbol(),MODE_MAXLOT); // узнаем каков максимальный размер лота
if (lot >= minlot && lot <= maxlot )
  {

//--- размещаем рыночный ордер на покупку 1 лота
if (OrdersTotal()<1)
{
   int ticket=OrderSend(Symbol(),OP_BUY,lot,price,Slippage,stoploss,takeprofit,"My order BUY",Magic,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend завершилась с ошибкой #",GetLastError());
     }
   else
      Print("Функция OrderSend успешно выполнена");
      }
  }
else {return;}
}
Небольшая ошибка.
Если у нас уже есть 1 открытый ордер, то при работе скрипта у нас, все равно, откроется еще один ордер, т.к. 1 не < 1, 1=1.

if (OrdersTotal()<1)

Поэтому (OrdersTotal()<=1) или (OrdersTotal()>0)
 

DomovenokBrest

♔♕♖♗♘♙
Небольшая ошибка.
Если у нас уже есть 1 открытый ордер, то при работе скрипта у нас, все равно, откроется еще один ордер, т.к. 1 не < 1, 1=1.

if (OrdersTotal()<1)

Поэтому (OrdersTotal()<=1) или (OrdersTotal()>0)
Не соглашусь.
У нас есть условие:
Код:
if (OrdersTotal()<1)
, которое читается так: функция OrdersTotal() возвращает общее количество открытых и отложенных ордеров. Если условие выполняется - открываем ордер Buy. Если нет - возвращает ноль.
Код:
else {return;}
. Т.к. условие у нас задано: OrdersTotal()<1, т то правильным будет решение - открытие ордера только тогда, когда открытых ордеров <1, т.е. 0.
 

gravity

Местный знаток
Не соглашусь.
У нас есть условие:
Код:
if (OrdersTotal()<1)
, которое читается так: функция OrdersTotal() возвращает общее количество открытых и отложенных ордеров. Если условие выполняется - открываем ордер Buy. Если нет - возвращает ноль.
Код:
else {return;}
. Т.к. условие у нас задано: OrdersTotal()<1, т то правильным будет решение - открытие ордера только тогда, когда открытых ордеров <1, т.е. 0.
С 51 минуты. Кажется у нас так же получится. Фигово, что сейчас в терминале не проверить.
 

Ugar

Гуру форума
Как то так...

C++:
#property strict


int slipp;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который закрывает все открытые ордера на счете.
// (перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
{
bool   resalt;
int    OT, Ticket, i;
for(i = OrdersTotal()-1; i >= 0; i--) // Переменной i присваиваем значение OrdersTotal()-1. После этого проверено условие что i>=0,
      {                               // если это так, то выполняется один раз все, что написано внутри тела цикла
        if(OrderSelect(i, SELECT_BY_POS))
          {
          OT = OrderType();           //Переменной OT присваиваем значение OrderType()
          Ticket = OrderTicket();     //Переменной Ticket присваиваем значение OrderTicket()
          if(OT == OP_BUY)            // Если тип операций для функции OrderType() выбран OP_BUY (покупка), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELL)           // Если тип операций для функции OrderType() выбран OP_SELL (продажа), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          }
          else {return;}
      }
}
}
else {return;} не надо. Ну допустим открыто 10 ордеров, на третьем не удалось выбрать ордер, это не значит что завершать работу скрипта. Можно же закрыть все остальные.
До кучи можно было добавить удаление отложенных ордеров.
 
Последнее редактирование:

DomovenokBrest

♔♕♖♗♘♙
else {return;} не надо. Ну допустим открыто 10 ордеров, на третьем не удалось выбрать ордер, это не значит что завершать работу скрипта. Можно же закрыть все остальные.
До кучи можно было добавить удаление отложенных ордеров.

Добавил, правда выглядит коряво. Скорее всего было бы красивее написать функцию возвращающую тип позиции...

C++:
#property strict


int slipp;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который закрывает все открытые ордера на счете.
// (перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
{
bool   resalt;
int    OT, Ticket, i;
for(i = OrdersTotal()-1; i >= 0; i--) // Переменной i присваиваем значение OrdersTotal()-1. После этого проверено условие что i>=0,
      {                               // если это так, то выполняется один раз все, что написано внутри тела цикла
        if(OrderSelect(i, SELECT_BY_POS))
          {
          OT = OrderType();           //Переменной OT присваиваем значение OrderType()
          Ticket = OrderTicket();     //Переменной Ticket присваиваем значение OrderTicket()
          if(OT == OP_BUY)            // Если тип операций для функции OrderType() выбран OP_BUY (покупка), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELL)           // Если тип операций для функции OrderType() выбран OP_SELL (продажа), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_BUYLIMIT)       // Если тип операций для функции OrderType() выбран OP_BUYLIMIT , то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELLLIMIT)      // Если тип операций для функции OrderType() выбран SELLLIMIT, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_BUYSTOP)        // Если тип операций для функции OrderType() выбран OP_OP_BUYSTOP, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELLSTOP)       // Если тип операций для функции OrderType() выбран OP_SELLSTOP, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          }

Ещё стоит подумать куда примостить RefreshRates(), если конечно программа пишется не для тестера.

Я об этом думал, сделать через перебор ошибок исполнения, как то так, но до конца не додумал...

C++:
switch(error)
{      
      case ERR_INVALID_PRICE:        // Неправильная цена (129)
      case ERR_PRICE_CHANGED:        // Цена изменилась (135)
      case ERR_OFF_QUOTES:           // Нет цен (136)
      case ERR_REQUOTE:              // Новые цены - Реквот (138)
      case ERR_ORDER_LOCKED:         // Ордер заблокирован и уже обрабатывается (139)
         RefreshRates();
         continue;
               }
 

BorisSedov

Активный участник
Следующая задача.
Нужно написать советник, который подсчитывает и выводит (через Comment) количество открытых ордеров соответствующих инструменту своего графика. Пример: советник запущен на графике EURUSD, подсчитываем только ордера EURUSD, а другие игнорируем. Если открытых ордеров нет, то советник открывает один ордер. Направление открытия (buy/sell) советник определяет следующим образом: если Close[1] > Close[3]+N*Point, то открывается ордер Buy, а если Close[1] < Close[3]-N*Point, то открывается ордер Sell. Значение переменной N (в пунктах), а также MagicNumber, StopLoss и TakeProfit нужно вывести во входные параметры (input).
Советник нужно протестировать в тестере стратегий.

Для создания советника можно использовать следующий шаблон.
C++:
#property strict

//input int MagicNumber = 555;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//Comment(MagicNumber);

}
//+------------------------------------------------------------------+
 

Ugar

Гуру форума
Добавил, правда выглядит коряво. Скорее всего было бы красивее написать функцию возвращающую тип позиции...

C++:
#property strict


int slipp;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который закрывает все открытые ордера на счете.
// (перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
{
bool   resalt;
int    OT, Ticket, i;
for(i = OrdersTotal()-1; i >= 0; i--) // Переменной i присваиваем значение OrdersTotal()-1. После этого проверено условие что i>=0,
      {                               // если это так, то выполняется один раз все, что написано внутри тела цикла
        if(OrderSelect(i, SELECT_BY_POS))
          {
          OT = OrderType();           //Переменной OT присваиваем значение OrderType()
          Ticket = OrderTicket();     //Переменной Ticket присваиваем значение OrderTicket()
          if(OT == OP_BUY)            // Если тип операций для функции OrderType() выбран OP_BUY (покупка), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELL)           // Если тип операций для функции OrderType() выбран OP_SELL (продажа), то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_BUYLIMIT)       // Если тип операций для функции OrderType() выбран OP_BUYLIMIT , то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELLLIMIT)      // Если тип операций для функции OrderType() выбран SELLLIMIT, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_BUYSTOP)        // Если тип операций для функции OrderType() выбран OP_OP_BUYSTOP, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          if(OT == OP_SELLSTOP)       // Если тип операций для функции OrderType() выбран OP_SELLSTOP, то
              {                       // выбранный тип закрывается
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);
              }
          }



Я об этом думал, сделать через перебор ошибок исполнения, как то так, но до конца не додумал...

C++:
switch(error)
{     
      case ERR_INVALID_PRICE:        // Неправильная цена (129)
      case ERR_PRICE_CHANGED:        // Цена изменилась (135)
      case ERR_OFF_QUOTES:           // Нет цен (136)
      case ERR_REQUOTE:              // Новые цены - Реквот (138)
      case ERR_ORDER_LOCKED:         // Ордер заблокирован и уже обрабатывается (139)
         RefreshRates();
         continue;
               }
1. RefreshRates(); нужна для обновления текущих цен. А где в коде нужна цена? В OrderClose(), значит перед неи надо поставить обновление цен, что бы OrderClose() получала самую свежую.
2, Отложенные ордера не закрываются, они ведь ещё не открыты, их открытие отложено. Они удаляются. А значит OrderClose() не подходит. Надо OrderDelete(). Посмотрите в справочнике как её использовать.
 

DomovenokBrest

♔♕♖♗♘♙
1. RefreshRates(); нужна для обновления текущих цен. А где в коде нужна цена? В OrderClose(), значит перед неи надо поставить обновление цен, что бы OrderClose() получала самую свежую.
2, Отложенные ордера не закрываются, они ведь ещё не открыты, их открытие отложено. Они удаляются. А значит OrderClose() не подходит. Надо OrderDelete(). Посмотрите в справочнике как её использовать.
Спасибо. Поправил. Если не сложно - проверьте.

C++:
#property strict


int slipp;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который закрывает все открытые ордера на счете.
// (перед запуском скрипта, желательно открыть несколько ордеров Бай и Селл)
{
bool   resalt;
int    OT, Ticket, i;
for(i = OrdersTotal()-1; i >= 0; i--) // Переменной i присваиваем значение OrdersTotal()-1. После этого проверено условие что i>=0,
      {                               // если это так, то выполняется один раз все, что написано внутри тела цикла
        if(OrderSelect(i, SELECT_BY_POS))
          {
          OT = OrderType();           //Переменной OT присваиваем значение OrderType()
          Ticket = OrderTicket();     //Переменной Ticket присваиваем значение OrderTicket()
          if(OT == OP_BUY)            // Если тип операций для функции OrderType() выбран OP_BUY (покупка), то
              {
               RefreshRates();        // обновляем цену
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE);// выбранный тип закрывается
              }
          if(OT == OP_SELL)           // Если тип операций для функции OrderType() выбран OP_SELL (продажа), то
              {                       
               RefreshRates();        // обновляем цену
               resalt = OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),slipp,clrNONE); // выбранный тип закрывается
              }
          if(OT == OP_BUYLIMIT)       // Если тип операций для функции OrderType() выбран OP_BUYLIMIT, то
              {                       // выбранный тип закрывается
               resalt = OrderDelete(Ticket,CLR_NONE); return;
              }
          if(OT == OP_SELLLIMIT)      // Если тип операций для функции OrderType() выбран OP_SELLLIMIT, то
              {                       // выбранный тип удаляется
               resalt = OrderDelete(Ticket,CLR_NONE); return;              }
          if(OT == OP_BUYSTOP)        // Если тип операций для функции OrderType() выбран OP_BUYSTOP, то
              {                       // выбранный тип удаляется
               resalt = OrderDelete(Ticket,CLR_NONE); return;
              }
          if(OT == OP_SELLSTOP)       // Если тип операций для функции OrderType() выбран OP_SELLSTOP, то
              {                       // выбранный тип удаляется
               resalt = OrderDelete(Ticket,CLR_NONE); return;
              }
          }
      }
}
 

DomovenokBrest

♔♕♖♗♘♙
Следующая задача.
Нужно написать советник, который подсчитывает и выводит (через Comment) количество открытых ордеров соответствующих инструменту своего графика. Пример: советник запущен на графике EURUSD, подсчитываем только ордера EURUSD, а другие игнорируем. Если открытых ордеров нет, то советник открывает один ордер. Направление открытия (buy/sell) советник определяет следующим образом: если Close[1] > Close[3]+N*Point, то открывается ордер Buy, а если Close[1] < Close[3]-N*Point, то открывается ордер Sell. Значение переменной N (в пунктах), а также MagicNumber, StopLoss и TakeProfit нужно вывести во входные параметры (input).
Советник нужно протестировать в тестере стратегий.

Для создания советника можно использовать следующий шаблон.
C++:
#property strict

//input int MagicNumber = 555;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//Comment(MagicNumber);

}
//+------------------------------------------------------------------+
Я попробовал. Проверьте пожалуйста. Но Comment не выдает...

C++:
#property strict

// Следующая задача.
// Нужно написать советник, который подсчитывает и выводит (через Comment)
// количество открытых ордеров соответствующих инструменту своего графика.
// Пример: советник запущен на графике EURUSD, подсчитываем только ордера EURUSD,
// а другие игнорируем. Если открытых ордеров нет, то советник открывает один ордер.
// Направление открытия (buy/sell) советник определяет следующим образом:
// если Close[1] > Close[3]+N*Point, то открывается ордер Buy, а если Close[1] < Close[3]-N*Point,
// то открывается ордер Sell. Значение переменной N (в пунктах), а также MagicNumber, StopLoss и TakeProfit
// нужно вывести во входные параметры (input).
// Советник нужно протестировать в тестере стратегий.

//+------------------------------------------------------------------+
input double Lots            = 0.01;     // Lots:
input int    Delta_N         = 25;       // Delta:
input int    TakeProfit      = 300;      // Take Profit:
input int    StopLoss        = 100;      // Stop Loss:
input int    Magic           = 12345;    // Magic Number:
input int    Slippage        = 3;        // Slippage:
//+------------------------------------------------------------------+
int    slipp, del;
double point, lot;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//----Определение пяти значного брокера 
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * point;
       slipp = Slippage * 10;
       }
//---
    lot          = Lots;
    del          = Delta_N;   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- получим минимальное значение Stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
//--- вычисленные значения цен SL и TP должны быть нормализованы
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
   double minlot = MarketInfo(Symbol(),MODE_MINLOT); // узнаем каков минимальный размер лота
   double maxlot = MarketInfo(Symbol(),MODE_MAXLOT); // узнаем каков максимальный размер лота 
//---
if (OrdersCount(0,Magic)>=0) Comment (OrdersCount(0,Magic));
else
if (OrdersCount(0,Magic)<1)
 {
     if (lot >= minlot && lot <= maxlot )
  {

//--- размещаем рыночный ордер на покупку 1 лота
if (OrdersTotal()<1 && Close[1] > Close[3]+Delta_N*Point)
     {
   int ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage,StopLoss,TakeProfit,"My order BUY",Magic,0,clrGreen);
   if(ticket<0)
       {
      Print("OrderSend завершилась с ошибкой #",GetLastError());
       }
   else
      Print("Функция OrderSend успешно выполнена");
     }
//--- размещаем рыночный ордер на продажу 1 лота
if (OrdersTotal()<1 && Close[1] < Close[3]-Delta_N*Point)
     {
   int ticket=OrderSend(Symbol(),OP_SELL,lot,Bid,Slippage,StopLoss,TakeProfit,"My order BUY",Magic,0,clrGreen);
   if(ticket<0)
       {
      Print("OrderSend завершилась с ошибкой #",GetLastError());
       }
   else
      Print("Функция OrderSend успешно выполнена");
     }
 
else {return;}
    }
   }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                    Подсчет ордеров по символу                    |
//+------------------------------------------------------------------+
int OrdersCount(int type, int MagicNum)
 {
  int orders = 0;
   for(int i = OrdersTotal()-1; i >= 0; i--)
      {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
        if(OrderSymbol() == _Symbol && OrderMagicNumber() == MagicNum)
          {
          if(OrderType() == type)orders++;
           }
       }
   }
  return orders;
 }
 

eevviill2

Местный знаток

Вложения

  • Close_all (scr).mq4
    2,2 КБ · Просмотры: 14
Верх