Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 412

 
Imminence:

Здравствуйте, у меня проблема новичка...

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

последние 20 баров. Что я делаю не так?


Проверял через Alert и по непонятным мне причинам тестер выдает максимально значение с вычисления с самого последнего тика, но он выдает это значение

столько же раз сколько и тиков по-этому ордер не открывается.


И вторая проблема, как заставить советник ждать до открытия следующего бара (30m period)?  При тесте по контрольным точкам все отлично, а если по тикам,

то советник открывает в том же баре сразу же где и закрылся по стоп-лосу например...


Так же, как можно закрывать сделку не зависимо был тик или нет? например на периоде 30m я хочу закрывать ордер за 5 секунд до конца бара (29.55, 59.55)

основываясь на всех данных в этот момент. На данном этапе проблема в том, что если тик не происходит в течении 5 секунд, следовательно не совершается

никаких логических операций, сигнал не поступает и момент упущен до следующего сигнала :( в теории фигня, а на деле втестере следующий сигнал может

оказаться аж через несколько свечей почему-то.


Заранее спасибо!

1. Насчет последних 20 баров в коде ничего не увидел, давай подробнее.

2. Как определить первый тик нового бара

3. как можно закрывать сделку не зависимо был тик или нет?

Надо уходить от работы с OnTick и работать с OnTimer, таймер устанавливать с интервалом 1 сек и в нем проверять время. Таймер от прихода тиков никак не зависит.

/// Определяет начало нового бара
bool NewBar()
{
    static datetime lastbar = 0;
    datetime curbar = iTime(Symbol(), PERIOD_M30, 0);
    if(lastbar!=curbar)
    {
        lastbar=curbar;
        return (true);
    }
    return(false);
}
 
Leanid Aladzyeu:

О_о спс не знал что еще и терминал тыкает где ошибка, в первый раз на критическую ошибку нарвался.

 на нее плюется. 

Конечно, будет плеваться, обращаетесь к 3-му элементу массива с размерностью 2 - mas [2]++

void Oher(int Mag,string Symb, int &mas[2])
..............
...........

case 1:mas[1]++; mas [2]++;break;// 1 продажа
 

Alexey Volchanskiy:
Так у тебя в комменте стоит управляющий символ "\n " - это символ перевода строки. Если его убрать, многострочия не будет.

Это шутка. Теперь он добавляет комент в конец строки... и текст убегает вправо. ;-)

 

Добрый вечер. Пытаюсь написать простой советник на пересечении тенкана и кинджуна. Вот код:

void OnTick()

void OnTick()

  {

   TradeSignal_20();

  }


int TradeSignal_20()

  {

   int sig=0;


   if(h_ich==INVALID_HANDLE)

   {

      h_ich=iIchimoku(Symbol(),Period(),IKHtenkansen,IKHkijunsen,IKHsenkouspanb);

      return(0);

   }

   else

   {

      if (CopyBuffer(h_ich,0,0,3,ich1_buffer)<2) return(0); // TENKANSEN_LINE

      if (CopyBuffer(h_ich,1,0,3,ich2_buffer)<2) return(0); // KIJUNSEN_LINE

      if (!ArraySetAsSeries(ich1_buffer,true)) return(0);

      if (!ArraySetAsSeries(ich2_buffer,true)) return(0);

   }

   

   //--- проводим проверку условия и устанавливаем значение для sig

   if (ich1_buffer[1]>ich2_buffer[1]) sig=1;

   else if(ich1_buffer[1]<ich2_buffer[1]) sig=-1;

   else sig=0;

   

   if (ich1_buffer[1]>ich2_buffer[1])

      if (ich1_buffer[2]<ich2_buffer[2])

         Alert(Symbol()+": покупка");

   

   if (ich1_buffer[1]<ich2_buffer[1])

      if (ich1_buffer[2]>ich2_buffer[2])

         Alert(Symbol()+": продажа");

   

   

   //--- возвращаем торговый сигнал

   return (sig);

  }

//+------------------------------------------------------------------+

 

Как сделать так, что бы алерт вызывался  только один раз, а не постоянно?

 
Alexey Volchanskiy:

1. Насчет последних 20 баров в коде ничего не увидел, давай подробнее.

2. Как определить первый тик нового бара

3. как можно закрывать сделку не зависимо был тик или нет?

Надо уходить от работы с OnTick и работать с OnTimer, таймер устанавливать с интервалом 1 сек и в нем проверять время. Таймер от прихода тиков никак не зависит.

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

double HIGHEST              = High[iHighest(Symbol(),0,MODE_HIGH,20,0)];


   
  if(Close[0] > SMMA && Close[0] > BB_UP && Close[0] >= HIGHEST)

  {
   TICKET = OrderSend(Symbol(),OP_BUY,LOT,Ask,0,Ask-StopLoss*Point,Ask+TakeProfit*Point,NULL,MAGIC,0,Blue);
   if(TICKET < 0)
      {
         Alert("Order Send failed, error # ", GetLastError() );
      } 
  }
 
first_may:

Добрый вечер. Пытаюсь написать простой советник на пересечении тенкана и кинджуна. Вот код:

void OnTick()

void OnTick()

  {

   TradeSignal_20();

Как сделать так, что бы алерт вызывался  только один раз, а не постоянно?
Нажать на кнопку SRC религия не позволяет?
 
Imminence:
Вот же, как мне сравнить цену закрытия с максимумали последних 20 баров? И если последняя цена ровна или больше максимального значения за 20 баров то идет сигнал на открытие.
Смотрим код
double HIGHEST              = High[iHighest(Symbol(),0,MODE_HIGH,20,0)];

  if(Close[0] > SMMA && Close[0] > BB_UP && Close[0] >= HIGHEST)

  {
***********

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

double HIGHEST              = High[iHighest(Symbol(),0,MODE_HIGH,20,2)];

  if(Close[1] > SMMA && Close[1] > BB_UP && Close[1] >= HIGHEST)

  {
***********

 
Alexey Volchanskiy:
Смотрим код

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

Спасибо, вроде бы помогло :)  хотя готов поклясться, что делал точно так же и не работало...

Вы посоветовали OnTimer() однако почему-то он не хочет со мной сотрудничать. Проштудировав всю справку и не найдя каких либо более внятных объяснений или примеров я встал в тупик.

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

режиме. Хотя этот момент вроде как устранили с выходом mql5. Помогите разобраться :) Спасибо!

int OnInit()
  {
//---
  bool  Timer = EventSetTimer(1);
  if(Timer != TRUE)
  Print(GetLastError()); 
//---
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
  EventKillTimer();   
  }
  
void OnTimer()
{
Print("It works");
}  
  
 

Imminence:

Прогуглив эту программу я столкнулся с тем, что говорят OnTimer() не работает в тестовом режиме. Хотя этот момент вроде как устранили с выходом mql5. Помогите разобраться :) Спасибо!

Верно, в МТ4 в тестере таймер не пашет и это не документировано! Я писал в сервисдеск, они сказали, что в делать это не будут никогда. Я выкрутился через вызов OnTimer в OnTick. У меня таймер настроен на одну секунду.

// Возвращает true, если работает под тестером
bool IsRunOnTester()
{
    if(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_VISUAL_MODE) || MQLInfoInteger(MQL_OPTIMIZATION))
        return true;
    return false;    
}

MqlDateTime     TimeCurrStruct;

void OnTick()
{
    if(IsRunOnTester())
    {
        static datetime dt1 = 0, dt2 = 0;
        static bool tfirst = true;
        if(tfirst)
        {
            tfirst = false;
            dt1 = dt2 = TimeCurrent();
            return;
        }
    
        dt2 = TimeCurrent();
        for(datetime TimeTesterCurrent = dt1+1; TimeTesterCurrent <= dt2; TimeTesterCurrent++)
        {
            TimeToStruct(TimeTesterCurrent, TimeCurrStruct);
            OnTimer();
        }    
        dt1 = dt2;
    }
}

То есть если в тестере тики приходят чаще 1 раз/сек, лишние пропускаются, если реже - генерится серия с временем, кратным 1 сек. Это время лежит в структуре TimeCurrStruct, а мой основной класс в любом режиме берет время только из этой структуры. По моему, это единственный способ победить этот баг. Вот функция, лишнее убрал, только мясо ))

void OnTimer()
{
    string msg;
    if(!IsRunOnTester())
    {
        TimeToStruct(TimeCurrent(), TimeCurrStruct);
        SmartDsp.ReceiveTick(TimeCurrStruct);    // основной метод робота, в него передается структура со временем
    }
    else
    {
        SmartDsp.ReceiveTick(TimeCurrStruct);    
    }
}




 
Alexey Volchanskiy:
Нажать на кнопку SRC религия не позволяет?
Не понятно, что имели ввиду?
Причина обращения: