+ Ответить в теме
Страница 1 из 4 1 2 3 4 ПоследняяПоследняя
Показано с 1 по 10 из 33

Тема: Как получить объемы из индикатора Премиум в свой робот.

  1. #1
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях

    Как получить объемы из индикатора Премиум в свой робот.

    Коллеги,

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

    Учитывая, что индикатор Премиум работает в асинхронном режиме, то использование iCustom не приводит к успеху. Я сделал небольшой набросок того, как Вы можете получать объемы в робот.
    Вам нужно перенести эту часть кода в свой советник

    (Eng: there are too many questions regarding to how to get volumes to the expert from Premium indicators. Premium use asynchronous calls so using iCustom may be failed. Here small example how you can get volumes for your expert. You should implement to your expert)


    Код:
    #property strict
    
    //+------------------------INCLUDE-----------------------------------+
    #include <stdlib.mqh>
    
    //+--------------- CLUSTERDELTA VOLUMEN DATA --------------------------+
    #import "premium_mt4_v4x1.dll"
    int InitDLL(int &);
    string Receive_Information(int &, string);
    int Send_Query(int &, string, string, int, string, string, string, string, string, string, int, string, string, string,int);
    #import
    
    datetime TIME_Array[]; // Array for TIME
    double VOLUME_Array[]; // Array of Volumes, indexes of array are corelated to TIME_ARRAY
    double DELTA_Array[]; // Array of Deltas, indexes of array are corelated to TIME_ARRAY
    datetime last_loaded=0;
    string indicator_client;
    bool ReverseChart_SET=false; // not used in expert
    int Seconds_Interval_To_Update_Volumes=10;
    
    bool VOLUMES_INIT=false;
    
    //+------------------------------------------------------------------+
    //| Expert initialization function                                   |
    //+------------------------------------------------------------------+
    int OnInit()
      {
    //---
    
       int INIT_DLL_result;
       InitDLL(INIT_DLL_result); // in the next version you dont have use this function
       if(INIT_DLL_result==-1) { Print("Error during load Volumes DLL") ; return INIT_FAILED; }
    
       // DO NOT CHANGE THIS CODE & DATA
       do
       {
         indicator_client = "CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+""+DoubleToStr(MathAbs((MathRand()+3)%10),0);     
       } while (GlobalVariableCheck(indicator_client));
       GlobalVariableTemp(indicator_client);
       // =====================
       
       EventSetTimer(1);
       return(INIT_SUCCEEDED);
      }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function                                 |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
      {
    //---
       GlobalVariableDel(indicator_client);
      }
    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    
    }
    //+------------------------------------------------------------------+
    
    //+------------------------------------------------------------------+
    //| Expert time function                                             |
    //+------------------------------------------------------------------+
    void OnTimer()
    {
       // DO NOT FORGET TO USE EventSetTimer(1); in Init
       // IF YOU DO NOT LIKE USE onTimer() YUO SHOULD MOVE THIS CODE TO onTick()
    
       static int Load_Frequency=0;
       // do not update faster than one time per 5 seconds
       if(Seconds_Interval_To_Update_Volumes<5) { Seconds_Interval_To_Update_Volumes=5; } 
       
       VOLUMES_GetData();
       if (Load_Frequency % Seconds_Interval_To_Update_Volumes == 0) 
       { 
          Load_Frequency=0;
          VOLUMES_SetData();
       }
       Load_Frequency++;
       if (VOLUMES_INIT) { Print (Time[0]," ",VOLUME_by_index(0));  } // <-- for testing purposes
      // VOLUMES_INIT is a signal that we have first package of volumes
    } 
    
        
    int ArrayBsearchCorrect(datetime &array[], double value, 
                            int count = WHOLE_ARRAY, int start = 0, 
                            int direction = MODE_ASCEND)
    {
       if(ArraySize(array)==0) return(-1);   
       int i = ArrayBsearch(array, (datetime)value, count, start, direction);
       if (value != array[i])
       {
          i = -1;
       }
       return (i);
    }
    
    void SortDictionary(datetime &keys[], double &values[], double &values2[], 
                        int sortDirection = MODE_ASCEND)
    {
       datetime keyCopy[];
       double valueCopy[];
       double valueCopy2[];   
       ArrayCopy(keyCopy, keys);
       ArrayCopy(valueCopy, values);
       ArrayCopy(valueCopy2, values2);   
       ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);
       for (int i = 0; i < MathMin(ArraySize(keys), ArraySize(values)); i++)
       {
          values[ArrayBsearch(keys, keyCopy[i])] = valueCopy[i];
          values2[ArrayBsearch(keys, keyCopy[i])] = valueCopy2[i];      
       }
    }
    
        
    int VOLUMES_SetData()
    {
    
      int k=0,i;
      
      string ExtraData="AUTO";
      string MetaTrader_GMT="AUTO";
      string ver="4.0";
      int Days_in_History=1;
      datetime Custom_Start_time=D'2017.01.01 00:00';
      datetime Custom_End_time=D'2017.01.01 00:00';
      
      i = Send_Query(k,indicator_client, Symbol(), Period(), TimeToStr(TimeCurrent()), TimeToStr(Time[0]), ExtraData, TimeToStr(last_loaded),MetaTrader_GMT,ver,Days_in_History,TimeToStr(Custom_Start_time),TimeToStr(Custom_End_time),AccountCompany(),AccountNumber());
    
      if (i < 0) { Alert ("Error during query registration"); return -1; }
      return 1;
    }  
    
    int VOLUMES_GetData()
    {
    
       string response="";
       int length=0;
       int valid=0;   
       int len=0,td_index;
       int i=0;
       double index;   
       int iBase=0;
       double ask_value=0, bid_value=0;
       string result[];
       string bardata[];
       string MessageFromServer;
       
       // get query from dLL
       response = Receive_Information(length, indicator_client);
       if (length==0) { return 0; }
    
        if(StringLen(response)>1) 
        {
          len=StringSplit(response,StringGetCharacter("\n",0),result);                
          if(!len) { return 0; }
          MessageFromServer=result[0];
          
          for(i=1;i<len;i++)
          {
            if(StringLen(result[i])==0) continue;
            StringSplit(result[i],StringGetCharacter(";",0),bardata);                
            td_index=ArraySize(TIME_Array);
            index = (double)StrToTime(bardata[0]);
            ask_value= StringToDouble(bardata[1]);
            bid_value= StringToDouble(bardata[2])*(ReverseChart_SET?-1:1);        
    
            
            if(index==0) continue;
            iBase = ArrayBsearchCorrect(TIME_Array, index ); 
            if (iBase >= 0) { td_index=iBase; } 
            if(td_index>=ArraySize(TIME_Array))
            {
               ArrayResize(TIME_Array, td_index+1);
               ArrayResize(VOLUME_Array, td_index+1);
               ArrayResize(DELTA_Array, td_index+1);           
            } 
            else { if((VOLUME_Array[td_index])>(ask_value) && td_index>=ArraySize(TIME_Array)-2) { ask_value=VOLUME_Array[td_index]; bid_value=DELTA_Array[td_index];}  }
        
            TIME_Array[td_index] = (datetime)index;
            VOLUME_Array[td_index] = ask_value;
            DELTA_Array[td_index] = bid_value;        
          
          }
          valid=ArraySize(TIME_Array);
          
          if (valid>0)
          {
           SortDictionary(TIME_Array,VOLUME_Array,DELTA_Array);
           int lastindex = ArraySize(TIME_Array);
           last_loaded=TIME_Array[lastindex-1];  
           if(last_loaded>Time[0])last_loaded=Time[0];        
           VOLUMES_INIT=true;
          } 
    
        }
        return (1);
    }
    
    
    int VOLUME_by_index(int ix, bool BrokehHour=true)
    {
          if(ArraySize(TIME_Array)<2) return 0;
          if(ArraySize(Time)<=ix) return 0;
          
          int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] ); 
    
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour      
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour            
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour                  
          if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour      
          if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES      
          if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES      
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES            
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES            
          if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES      
          
          
          if (iBase >= 0)
          {
             return (int)VOLUME_Array[iBase];
          }
             
          return 0;
    }

  2. #2
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях
    Фактически за получение объемов отвечает этот кусок кода:
    Код:
    void OnTimer()
    {
       static int Load_Frequency=0;
       if(Seconds_Interval_To_Update_Volumes<5) { Seconds_Interval_To_Update_Volumes=5; } 
       
       VOLUMES_GetData();
       if (Load_Frequency % Seconds_Interval_To_Update_Volumes == 0) 
       { 
          Load_Frequency=0;
          VOLUMES_SetData();
       }
       Load_Frequency++;
    }
    Функция Volumes_SetData() через каждый интервал, заданный в параметре Seconds_Interval_To_Update_Volumes в секундах дает запрос на DLL на получение данных по текущему инструменту.

    Volume_GetData постоянно опрашивает DLL на предмет того, были ли уже получены данные по прошлому запросу. Пока данные не получены, все последующие запросы будут игнорироваться внутри DLL.
    После получения первого набора данных переменная VOLUMES_INIT становится true

    Если Вам нужно протестировать только историю, то достаточно сделать SetData и периодически вызывать GetData пока, VOLUMES_INIT не станет true.
    Лучше всего это делать где-то в onTick(),

    if(!VOLUMES_INIT) { VOLUMES_GetData(); }
    else
    {
    анализ объемов

    }

    я сразу хочу отметить, что конструкция while(!VOLUMES_INIT) { VOLUMES_GetData(); } - может привести терминал в неизвестное состояние. Надо тестировать.

  3. #3
    Пользователь
    Регистрация
    06.06.2017
    Сообщений
    2
    Сказал(а) спасибо
    0
    Поблагодарили 1 раз в 1 сообщении
    Подскажите таким образом данные объема можно получить только из индикатора Премиум? Или аналогичным образом объемы можно получить из индикатора Стандарт?

  4. #4
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях
    Цитата Сообщение от Rusmag Посмотреть сообщение
    Подскажите таким образом данные объема можно получить только из индикатора Премиум? Или аналогичным образом объемы можно получить из индикатора Стандарт?
    Я скоро добавлю для индикатора Стандарт индикаторы с подключением DLL

    Для индикаторов стандарт можно пользоваться базовым iCustom

  5. #5
    daolien@mail.ru
    Гость
    Подскажите, можно ли получить исторические данные по конкретному бару с ClusterDelta Premium Delta 4.1 через скрипт подобным методом?

  6. #6
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях
    Цитата Сообщение от daolien@mail.ru Посмотреть сообщение
    Подскажите, можно ли получить исторические данные по конкретному бару с ClusterDelta Premium Delta 4.1 через скрипт подобным методом?
    Да, добавьте функцию:

    Код:
    int DELTA_by_index(int ix, bool BrokehHour=true)
    {
          if(ArraySize(TIME_Array)<2) return 0;
          if(ArraySize(Time)<=ix) return 0;
          
          int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] ); 
    
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour      
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour            
          if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour                  
          if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour      
          if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES      
          if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES      
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES            
          if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES            
          if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES      
          
          
          if (iBase >= 0)
          {
             return (int)DELTA_Array[iBase];
          }
             
          return 0;
    }

  7. #7
    daolien@mail.ru
    Гость
    У меня проблема в том, что в скрипте нельзя реализовать потиковые функции, какие используются в советниках и индикаторах. Поэтому функция для получения данных, которая должна исполняться потиково у меня просто void, исполняется 1 раз при работе скрипта и выглядит просто вот так:
    void CheckVOLUMES ()
    {
    VOLUMES_SetData();
    VOLUMES_GetData();
    if (VOLUMES_INIT) {Alert(Time[3]," ",DELTA_by_index(3));} // <-- for testing purposes
    // VOLUMES_INIT is a signal that we have first package of volumes
    }
    Конструкции while, for для получения данных входят в бесконечную петлю или вызывают краш (зависит от задержки в 5 сек). VOLUMES_INIT всегда возвращает false. Вопросы: как должна выглядеть функция получения данных для скрипта, если нельзя использовать в нем потиковые функции? Где прописывать параметр под поиск конкретного бара в истории? Я предположил, что это указывается в массиве Time[], и во всех функциях описанных Вами меняю Time[0] на нужное мне число, для эксперимента Time[3].

  8. #8
    daolien@mail.ru
    Гость
    Также вызов функции инициализации dll, которая должна быть в OnInit (у меня это другая функция) открывает окно настроек индикатора при работе скрипта, в котором нужно выставить галочку на использование функций с dll, что не совсем удобно.

  9. #9
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях
    Цитата Сообщение от daolien@mail.ru Посмотреть сообщение
    Также вызов функции инициализации dll, которая должна быть в OnInit (у меня это другая функция) открывает окно настроек индикатора при работе скрипта, в котором нужно выставить галочку на использование функций с dll, что не совсем удобно.
    Настройки терминала - закладка "советники", - поставьте там галочку чтобы не ставить ее каждый раз.

  10. #10
    ClusterDelta.com Team
    Регистрация
    27.10.2011
    Сообщений
    4,258
    Сказал(а) спасибо
    473
    Поблагодарили 2,158 раз(а) в 1,129 сообщениях
    Цитата Сообщение от daolien@mail.ru Посмотреть сообщение
    У меня проблема в том, что в скрипте нельзя реализовать потиковые функции, какие используются в советниках и индикаторах. Поэтому функция для получения данных, которая должна исполняться потиково у меня просто void, исполняется 1 раз при работе скрипта и выглядит просто вот так:
    void CheckVOLUMES ()
    {
    VOLUMES_SetData();
    VOLUMES_GetData();
    if (VOLUMES_INIT) {Alert(Time[3]," ",DELTA_by_index(3));} // <-- for testing purposes
    // VOLUMES_INIT is a signal that we have first package of volumes
    }
    Конструкции while, for для получения данных входят в бесконечную петлю или вызывают краш (зависит от задержки в 5 сек). VOLUMES_INIT всегда возвращает false. Вопросы: как должна выглядеть функция получения данных для скрипта, если нельзя использовать в нем потиковые функции? Где прописывать параметр под поиск конкретного бара в истории? Я предположил, что это указывается в массиве Time[], и во всех функциях описанных Вами меняю Time[0] на нужное мне число, для эксперимента Time[3].
    Volumes_SetData - дает задачу для DLL скачать данные для данного индикатора

    Volumes_GetData - опрашивает DLL на предмет того, скачаны ли данные из предыдущего запроса, и если скачаны установит volumes_init в значение True. Volumes_GetData действует асинхронно, то есть после _SetData надо опрашивать DLL каждые 100-200 милисекунд на предмет получения данных. Сами данные в индикатор не появятся, - только через функцию опроса DLL (Volumes_GetData). Формально Вы можете это делать потиково.

    Делать потиково SetData не нужно.

    p.s. для отсылки и опроса данных Вы должны обязательно установить indicator_client

    indicator_client - состоит из букв CDPA и четыре цифры которые дают уникальный идентификатор индикатора. Теоретически, при известном идентификаторе, можно SetData делать в одном индикаторарое, а получать данные в другом.

    // DO NOT CHANGE THIS CODE & DATA
    do
    {
    indicator_client = "CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+"" +DoubleToStr(MathAbs((MathRand()+3)%10),0);
    } while (GlobalVariableCheck(indicator_client));
    GlobalVariableTemp(indicator_client);

+ Ответить в теме
Страница 1 из 4 1 2 3 4 ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
           

 


(C) 2009-2023 ClusterDelta.com.