Один советник на нескольких инструментах. Не работет условие.

 

В теле советника был примерно такой код:

if (OrdersTotal()==0)
 {
  if (buy ()) OrderSend(Symbol(),OP_BUY, lot,Ask,3,Bid-sl*Point,Ask+tp*Point);
  if (sell()) OrderSend(Symbol(),OP_SELL,lot,Bid,3,Ask+sl*Point,Bid-tp*Point);
 }

При попытке запустить советника на нескольких инструментах, открывалось сразу несколько позиций (условие  if (OrdersTotal()==0) не срабатывало).

Хотел разнести по времени таким образом:

extern double prioritet=0.0;                                            //0,0 - высший (ожидание в долях секунды (для различных инструментов))
.
.
.
int start()
{
int zzz=prioritet*1000;
Sleep(zzz);
.
.
.
Это сработало, но не так. Экспериментальным путем вычислил, что разносить таким образом срабатывание нужно секунд на 20 (от 3 на втором инструменте до 20 на шестом). А это для той стратегии много.

 

Потом придумал такой выход : 

int start()
{
if (OrdersTotal()==0) GlobalVariableSet("GTF", 0.0);                                                            //устанавливаем "флажок" на ноль
if (GlobalVariableGet("GTF")>0.0) return(0);
.
.
.
if (GlobalVariableGet("GTF")==0.0)

  if (buy ()) {GlobalVariableSet("GTF", 0.1); OrderSend(Symbol(),OP_BUY, lot,Ask,3,Bid-sl*Point,Ask+tp*Point);} //первая копия советника, которая добирается до GTF...
  if (sell()) {GlobalVariableSet("GTF", 0.1); OrderSend(Symbol(),OP_SELL,lot,Bid,3,Ask+sl*Point,Bid-tp*Point);} //... меняет его значение
.
.
.

 Это тоже не сработало.

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

 
А что именно требуется?
 
grell:
А что именно требуется?


Чтобы открывалась только одна позиция.

Т.е. если советник работает, например, на графиках EURUSD, USDCHF, GBPUSD, USDCAD и одновременно на всех инструментах появляется условие на открытие позиции, нужно, чтобы открылась ТОЛЬКО одна.

 
Dobr:


Чтобы открывалась только одна позиция.

Т.е. если советник работает, например, на графиках EURUSD, USDCHF, GBPUSD, USDCAD и одновременно на всех инструментах появляется условие на открытие позиции, нужно, чтобы открылась ТОЛЬКО одна.

Вы говорите о сигналах по одному инструменту или это разные сигналы? То есть на каком раньше сигнал появился тот и открывать остальные сигналы игнорировать?
Мультивалютный советник Вам в помощь.
 
grell:
Вы говорите о сигналах по одному инструменту или это разные сигналы? То есть на каком раньше сигнал появился тот и открывать остальные сигналы игнорировать?
Мультивалютный советник Вам в помощь.

Да все проще. Сделать контроль ордера с определенным магиком. Если данный ордер есть в системе, остальные советники игнорируют.

Только вчера выкладывал:

if (!ExistOrders("", OP_SELL, Magic) ticket=OrderSend(...);


//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal(), ty; 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) return(True);
          }}}}  return(False);}
 
grell:
Вы говорите о сигналах по одному инструменту или это разные сигналы? То есть на каком раньше сигнал появился тот и открывать остальные сигналы игнорировать?
Мультивалютный советник Вам в помощь.

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

Dima.A.:

Да все проще. Сделать контроль ордера с определенным магиком. Если данный ордер есть в системе, остальные советники игнорируют.

Только вчера выкладывал:

  Попробовал реализовать, результат тот же.

Вот для примера:

int start()
  {
//----
if (OrdersTotal()!=0) return(0);
if (Open[1]>Close[1])   OrderSend(Symbol(),OP_BUY, 0.1,Ask,3,Bid-100*Point,Ask+100*Point,0,mag,0);
if (Open[1]<Close[1])   OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+100*Point,Bid-100*Point,0,mag,0);
//----
   return(0);
  }

Если перекинуть созданный советник на несколько графиков и запустить кнопкой "Советники" в терминале, то получим следующее:

 

 21.57.55 Открыты несколько ордеров несмотря на условие  if (OrdersTotal()!=0) return(0);

Вот меня и интересует этот момент. Как сделать так, чтобы открылся ТОЛЬКО один ордер. Любой. Кто первее.

Dima.A.:

Сделал так:

int start()
  {
//----
if (OrdersTotal()!=0) return(0);
if (Open[1]>Close[1] && !ExistOrders("", -1, mag))   OrderSend(Symbol(),OP_BUY, 0.1,Ask,3,Bid-100*Point,Ask+100*Point,0,mag,0);
if (Open[1]<Close[1] && !ExistOrders("", -1, mag))   OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+100*Point,Bid-100*Point,0,mag,0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1) {
  int i, k=OrdersTotal(), ty; 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) return(True);
          }}}}  return(False);}

 Не работает.

 
Dobr:

 Не работает.


Угу, если добавить запись в глобальные переменные, и сделать задержку перед открытием ордера в 1 сек, тоже не поможет ?

У меня была ситуация, через глобальные переменные долго обмен инфой шел.. А сейчас добавили одновременно 8 потоков на открытие ордеров, вот они и делают одновременные запросы.

 
static string sy[28]={"AUDCAD","AUDCHF","EURAUD","GBPAUD","AUDJPY","AUDNZD","AUDUSD",
                      "CADCHF","EURCAD","GBPCAD","CADJPY","NZDCAD","USDCAD","EURCHF",
                      "GBPCHF","CHFJPY","NZDCHF","USDCHF","EURGBP","EURJPY","EURNZD",
                      "EURUSD","GBPJPY","GBPNZD","GBPUSD","NZDJPY","USDJPY","NZDUSD"};
int init()
  {
  return(0);
  }
int deinit()
  {
  return(0);
  }
int start()
  {
  if(!synchronize())Alert("Данные не синхронизированы, торговля запрещена");
  if(synchronize())
    {
    for(int i=0;i<28;i++)
      {
      if(!ExistPositions(sy[i], -1, mag)  &&  signal(i)==2) OpenPosition(sy[i],OP_BUY, Lot,0,0,mag);
      if(!ExistPositions(sy[i], -1, mag)  && signal(i)==-2) OpenPosition(sy[i],OP_SELL,Lot,0,0,mag);
      if(ExistPositions(sy[i], -1, mag)  &&  signal(i)==0)  ClosePositions(sy[i],-1,mag);
      if(ExistPositions(sy[i], OP_BUY, mag)  && signal(i)<0)  ClosePositions(sy[i],-1,mag);
      if(ExistPositions(sy[i], OP_SELL, mag) &&  signal(i)>0)  ClosePositions(sy[i],-1,mag);
      }
    }
  return(0);
  }
bool synchronize()
  {
  datetime p1=iTime("AUDCAD",tf,1);
  datetime p2=iTime("AUDCHF",tf,1);
  datetime p3=iTime("EURAUD",tf,1);
  datetime p4=iTime("GBPAUD",tf,1);
  datetime p5=iTime("AUDJPY",tf,1);
  datetime p6=iTime("AUDNZD",tf,1);
  datetime p7=iTime("AUDUSD",tf,1);
  datetime p8=iTime("CADCHF",tf,1);
  datetime p9=iTime("EURCAD",tf,1);
  datetime p10=iTime("GBPCAD",tf,1);
  datetime p11=iTime("CADJPY",tf,1);
  datetime p12=iTime("NZDCAD",tf,1);
  datetime p13=iTime("USDCAD",tf,1);
  datetime p14=iTime("EURCHF",tf,1);
  datetime p15=iTime("GBPCHF",tf,1);
  datetime p16=iTime("CHFJPY",tf,1);
  datetime p17=iTime("NZDCHF",tf,1);
  datetime p18=iTime("USDCHF",tf,1);
  datetime p19=iTime("EURGBP",tf,1);
  datetime p20=iTime("EURJPY",tf,1);
  datetime p21=iTime("EURNZD",tf,1);
  datetime p22=iTime("EURUSD",tf,1);
  datetime p23=iTime("GBPJPY",tf,1);
  datetime p24=iTime("GBPNZD",tf,1);
  datetime p25=iTime("GBPUSD",tf,1);
  datetime p26=iTime("NZDJPY",tf,1);
  datetime p27=iTime("USDJPY",tf,1);
  datetime p28=iTime("NZDUSD",tf,1);
  if(p1==p2&&p2==p3&&
  p3==p4&&p4==p5&&
  p5==p6&&p6==p7&&
  p7==p8&&p8==p9&&
  p9==p10&&p10==p11&&
  p11==p12&&p12==p13&&
  p13==p14&&p14==p15&&
  p15==p16&&p16==p17&&
  p17==p18&&p18==p19&&
  p19==p20&&p20==p21&&
  p21==p22&&p22==p23&&
  p23==p24&&p24==p25&&
  p25==p26&&p26==p27&&
  p27==p28&&p28==p1)return(true);
  return(false);
  }
 
grell:


а p1-p28 нельзя было в массив загнать ?

и так же, в цикле в одно действие проверить соответствие времени бара.. ))


   datetime p[28];
   for (i=0; i< StringLen(p)-1; i++) p[i] = iTime(sy[i],tf,1);

  bool res=true;
   for (i=1; i< StringLen(p)-1; i++) if (p[0] != p[i]) res = false;
 
 

Dima.A.:


Угу, если добавить запись в глобальные переменные, и сделать задержку перед открытием ордера в 1 сек, тоже не поможет ?

У меня была ситуация, через глобальные переменные долго обмен инфой шел.. А сейчас добавили одновременно 8 потоков на открытие ордеров, вот они и делают одновременные запросы.

Вот в таком варианте одновременно открывается три позиции:

int start()
  {
if (OrdersTotal()==0) GlobalVariableSet("GTF", 0.0);

if (GlobalVariableGet("GTF")==0.0)
{
if (Open[1]>Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_BUY, 0.1,Ask,3,Bid-100*Point,Ask+100*Point,0,mag,0);}
if (Open[1]<Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+100*Point,Bid-100*Point,0,mag,0);}
}
//----
   return(0);
  }
Мне очень интересно почему. Ведь обращение к глобальным переменным происходит не как к OrdersTotal (я так понимаю через сервер), а на уровне софта. Должно быть все четко и почти моментально.

Более того. Вот код с задержкой:

extern double prioritet=0.0;
//...
int start()
  {
int zzz=prioritet*1000;
if (OrdersTotal()==0) GlobalVariableSet("GTF", 0.0);
if (GlobalVariableGet("GTF")==0.0)
{
Sleep(zzz);

if (Open[1]>Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_BUY, 0.1,Ask,3,Bid-100*Point,Ask+100*Point,0,mag,0);}
if (Open[1]<Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+100*Point,Bid-100*Point,0,mag,0);}
}
//----
   return(0);
  }
Задержка 0,5 сек (разброс задержки от 0,1 до 0,5 на разных инструментах). И ЧЕТЫРЕ (!!!) открытые позиции. Объясните, пожалуйста. Я сам не врублюсь.
 
Dobr:

Вот в таком варианте одновременно открывается три позиции:

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

Более того. Вот код с задержкой:

Задержка 0,5 сек (разброс задержки от 0,1 до 0,5 на разных инструментах). И ЧЕТЫРЕ (!!!) открытые позиции. Объясните, пожалуйста. Я сам не врублюсь.


extern double prioritet=0.0;
//...
int start()
  {
int zzz=prioritet*1000;
if (OrdersTotal()==0) GlobalVariableSet("GTF", 0.0);
Sleep(zzz);// ТУТ!!!
if (GlobalVariableGet("GTF")==0.0)
{


if (Open[1]>Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_BUY, 0.1,Ask,3,Bid-100*Point,Ask+100*Point,0,mag,0);}
if (Open[1]<Close[1] )   {GlobalVariableSet("GTF",0.1);
                          OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+100*Point,Bid-100*Point,0,mag,0);}
}
//----
   return(0);
  }

задержку поставил перед проверкой, попробуйте так, а еще лучше в глобальной переменной указать hwnd окна, которое начнет работу с ордером hwnd=WindowHandle(Symbol(), Period());


и разрешать работу с ордерами только этому окну..

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