Скачать MetaTrader 5

открытие ордера на новом баре

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
maks
118
maks  

Всем привет.

Вот уже который день мучаюсь над проблемой - как сделать так чтоб при существовании открытых ордеров новый ордер может открыться только на "чистом" баре (проще говоря на одном баре может быть открыт только один ордер).

Подкиньте, пожалуйста идейку как это можно прописать. Или, быть может, у кого-то есть подобная пользовательская ф-я.

Буду признателен за любую помощь.

Спасибо!

Рита
438
Рита  

Воспользуйтесь ф-ями И.Кима (скопируйте их в ваш код и расположите вне функции СТАРТ)

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru/                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара открытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarOpenLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }}}}}}
  return(iBarShift(sy, tf, t, True));}
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru/                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }}}}}}
  return(iBarShift(sy, tf, t, True));}

Ну а теперь проще.

Задаете условие:

if ( NumberOfBarOpenLastPos(NULL,0,OP_BUY, Magic)!=0  )
    {
// запрет установки  - если на нулевом баре уже была открыта позиция бай
// то новае открытие запрещено     

Аналогично, для селл позиции...

Можно вот так тоже: 

if ( NumberOfBarOpenLastPos(NULL,0,OP_SELL, Magic)>0 ||
     NumberOfBarOpenLastPos(NULL,0,OP_SELL, Magic)==-1  )
         {//открываем:

 

Удачи! 

maks
118
maks  
Rita:

Воспользуйтесь ф-ями И.Кима (скопируйте их в ваш код и расположите вне функции СТАРТ)

Ну а теперь проще.

Задаете условие:

Аналогично, для селл позиции...

Удачи!


Большое спасибо.

Буду пробовать

Роман
7939
Роман  
Maks:

Всем привет.

Вот уже который день мучаюсь над проблемой - как сделать так чтоб при существовании открытых ордеров новый ордер может открыться только на "чистом" баре (проще говоря на одном баре может быть открыт только один ордер).

Подкиньте, пожалуйста идейку как это можно прописать. Или, быть может, у кого-то есть подобная пользовательская ф-я.

Буду признателен за любую помощь.

Спасибо!


Пропишите явно в коде работу советника только по открытию нового бара:

в переменные:

static datetime prevtime = 0;       // по ценам открытия

сразу после ф-ии старт:

int start()                            // Спец. функция start
  {
   //PlaySound("tick.wav");              // На каждом тике
 //-----------------------for price-open---------------------  
   if(Time[0] == prevtime)   return(0);  //ждем нового бара
   prevtime = Time[0];                   //если появился новый бар , включаемся
 //----------------------------------------------------------  
..............
..............
..............

Один бар - один ордер, кроме этого также можете тестировать в модели "по ценам открытия,... только для советников с явным контролем открытия баров", что значительно сокращает время теста.

Олег Кобенко
30
Олег Кобенко  

а почему у меня при таком коде не открываются ордера в реал терминале при запуске советника

//+------------------------------------------------------------------+
//|                                                        test1.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
extern    int ooo = 3;
extern    int Magic       = -1;
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
static datetime t;       // по ценам открытия
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
if(Time[0] == t)   return(0);  //ждем нового бара
   t = Time[0]; 
      //PlaySound("tick.wav");              // На каждом тике

   return(INIT_SUCCEEDED);
  }
int func()
{ 
   
   //t = 0//TimeCurrent();
/*   if(OrdersTotal() >= OrdersLimit)
   {
      return 0;
   }*/
   int ticket = 0;
   if ( NumberOfBarOpenLastPos(NULL,0,OP_SELL, Magic)>0 ||
        NumberOfBarOpenLastPos(NULL,0,OP_SELL, Magic)==-1 )

   {
   
      ticket = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 0, 0, 0, "", Magic, 0, Red);
      if(ticket < 0)Print("Ошибка");
      else Print("Успех");
   }
    return (0);
}
void OnDeinit(const int reason)
  {
//---
   
  }
void OnTick()
  {
func();
  }
int NumberOfBarOpenLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) 
{
  //datetime t;//= TimeCurrent();
  int      i, k=OrdersTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=-1; i<k; i++) 
  {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
    {
      if (OrderSymbol()==sy) 
      {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) 
        {
          if (op<0 || OrderType()==op) 
          {
            if (mn<0 || OrderMagicNumber()==mn) 
            {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) 
{
  ///datetime t;//=TimeCurrent();
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=-1; i<k; i++) 
  {
      if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) 
      {
         if (OrderSymbol()==sy) 
         {
            if (OrderType()==OP_BUY || OrderType()==OP_SELL)
            {
               if (op<0 || OrderType()==op) 
               {
                  if (mn<0 || OrderMagicNumber()==mn)
                  {
                     if (t<OrderCloseTime()) t=OrderCloseTime();
                  }
               }
            }
         }
      }
  }
  return(iBarShift(sy, tf, t, True));
}
Vitalie Postolache
12397
Vitalie Postolache  
ixtorio:

а почему у меня при таком коде не открываются ордера в реал терминале при запуске советника

 Потому, что так цикл пересчёта ордеров не строят:

 for (i=-1; i<k; i++) 

Линейкой по рукам надо за такой код ))) Мозг надо свой иметь, а не на "авторитет" равняться. Ну и если код правите, то шапку авторскую оставлять не надо, а то можно подумать, Ким так написал...

Ещё, в коде:

static datetime t;       // по ценам открытия

int OnInit()
  {
//---
if(Time[0] == t)   return(0);  //ждем нового бара
   t = Time[0]; 
      //PlaySound("tick.wav");              // На каждом тике
 //-----------------------for price-open---------------------  
                  //если появился новый бар , включаемся
 //----------------------------------------------------------  
   
//---
   return(INIT_SUCCEEDED);
  }

 Какое значение у t при запуске, учитывая обьяву static datetime t;? Сработает ли условие в ините?

Олег Кобенко
30
Олег Кобенко  

я вообще непонимаю смысл этой проверки со временем и что туда подсунуть как инициализировать ее

 пробовал вот так

static datetime t=TimeCurrent(); 

но непомогло 

Vitalie Postolache
12397
Vitalie Postolache  
ixtorio:

я вообще непонимаю смысл этой проверки со временем и что туда подсунуть как инициализировать ее

 пробовал вот так

static datetime t=TimeCurrent(); 

но непомогло 

И как, компилятор не ругался? Выше написали, как этим пользоваться, а если по форуму поискать, или в гугле, то и готовая функция определения нового бара есть.
Олег Кобенко
30
Олег Кобенко  
bool fNewBar()
{
   static datetime NewTime=0;
      if(NewTime!=Time[0])
      {
            if(NewTime==0)
            {
               NewTime=Time[0];
               return(false);
            }      
         NewTime=Time[0];
         return(true);
      }
   return(false);     
}
вот нашел но тогда получается предыдущий код вообще ненужен
Олег Кобенко
30
Олег Кобенко  
extern int  OrdersLimit = 3;
int OnInit()
{
   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
   if(fNewBar()==true)func();
}
int func()
{ 
   int ticket = 0;
   if(OrdersTotal() >= OrdersLimit)
   {
      return 0;
   }
   ticket = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 0, 0, 0, "", 12345, 0, Red);
   if(ticket < 0)Print("Ошибка");
   else Print("Успех");
   
   return (0);
}
bool fNewBar()
{
   static datetime NewTime=0;
   if(NewTime!=Time[0])
   {
      if(NewTime==0)
      {
         NewTime=Time[0];
         return(false);
      }      
      NewTime=Time[0];
      return(true);
   }
   return(false);     
}
не срабатывает всеравно...попробовал сменить с труе на фолс и в тестере сработало но в реал терминале нехочет
простите но я видимо чтото не так делаю.....у меня даже это не срабатывает на демо счету.....
int OnInit()
  {
//---
int ticket = 0;
      ticket = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 0, 0, 0, "", 12345, 0, Red);
//---
   return(INIT_SUCCEEDED);
  }
хотя торговлю советнику разрешаю
Олег Кобенко
30
Олег Кобенко  
все всем спасибо понял вроде в чем была проблема.....надо было включить авто торговлю
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий