Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 1219

 
Vladimir Karputov:

Parece que o terminal continua a bombear o histórico - por isso o indicador continua a recalcular. Ou outra variante: tem um MUITO grande número de barras definidas no terminal para exibição no gráfico, e o seu computador tem um MUITO grande número de barras no gráfico.

Obrigado pela ajuda!

Quando se selecciona uma data diferente, o cálculo tem lugar imediatamente. No primeiro teste houve uma lacuna no preço, possivelmente faltando alguns preços - este é muito provavelmente o problema.

 

Olá! existe um indicador MT5 "Grid Builder" que desenhalinhas horizontais em incrementos de preços. Pode seleccionar, por exemplo, 100p, 200p, etc. E constrói uma grelha horizontal para cima e para baixo com um dado passo. Mas tem um problema, por exemplo, quando desenho níveis horizontais no prazo H4 (coloco linhas horizontais de ferramentas de desenho no terminal) e mudo para qualquer outro prazo, todas as minhas linhas são removidas. Restam apenas os níveis indicadores horizontais. Como posso corrigir este erro no código? Para assegurar que os meus níveis horizontais nunca sejam eliminados. Aqui está o código indicador (escrevi esta pergunta noutra linha, mas ainda não há resposta)

//+------------------------------------------------------------------+
//|                                                  GridBuilder.mq5 |
//|                                              Copyright 2015, AM2 |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, AM2"
#property link      "https://www.forexsystems.biz"
#property version   "1.00"
#property indicator_chart_window

//---- для расчёта и отрисовки индикатора использовано ноль буферов
#property indicator_buffers 0
//---- использовано всего ноль графических построений
#property indicator_plots   0
//--- входные параметры 
input int count = 50;      //количество линий вверх вниз от цены
input int step  = 333;     //шаг линий 
input double pr = 1.4622;  //цена от которой пляшем
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   ObjectsDeleteAll(0,0,OBJ_HLINE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
   ObjectsDeleteAll(0,0,OBJ_HLINE);
  }
//+------------------------------------------------------------------+ 
//| Создает горизонтальную линию                                     | 
//+------------------------------------------------------------------+ 
bool HLine(const string name="HLine",double price=0)
  {
//--- создадим горизонтальную линию 
   if(!ObjectCreate(0,name,OBJ_HLINE,0,0,price))
     {
      Print(__FUNCTION__,
            ": не удалось создать горизонтальную линию! Код ошибки = ",GetLastError());
      return(false);
     }
//--- установим цвет линии 
   ObjectSetInteger(0,name,OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
   return(true);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   double price=pr;
//--- создадим горизонтальную линию 
   for(int i=0;i<=count;i++)
     {
      HLine("HLine"+(string)i,price+step*i*_Point);
      HLine("HLine"+(string)(i+count+1),price-step*i*_Point);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
  • www.mql5.com
При создании графического объекта функцией ObjectCreate() необходимо указать тип создаваемого объекта, который может принимать одно из значений перечисления ENUM_OBJECT. Дальнейшие уточнения свойств созданного объекта возможно с помощью функций по работе с графическими объектами.
 
Александр:

Olá! existe um indicador MT5 "Grid Builder" que desenhalinhas horizontais em incrementos de preços. Pode seleccionar, por exemplo, 100p, 200p, etc. E constrói uma grelha horizontal para cima e para baixo com um dado passo. Mas tem um problema, por exemplo, quando desenho níveis horizontais no prazo H4 (coloco linhas horizontais de ferramentas de desenho no terminal) e mudo para qualquer outro prazo, todas as minhas linhas são removidas. Restam apenas os níveis indicadores horizontais. Como posso corrigir este erro no código? Para assegurar que os meus níveis horizontais nunca sejam eliminados. Aqui está o código de indicador (escrevi esta pergunta noutro tópico, mas não há resposta)

Preste atenção a este código:

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
   ObjectsDeleteAll(0,0,OBJ_HLINE);
  }
//+------------------------------------------------------------------+ 

Em particular, ler sobre ObjectsDeleteAll() - aí a causa e a resposta para a correcção.

Документация по MQL5: Графические объекты / ObjectsDeleteAll
Документация по MQL5: Графические объекты / ObjectsDeleteAll
  • www.mql5.com
[in]  Префикс, по которому будут удалены все объекты, чьи имена начинаются с данного набора символов. Префикс можно указывать как 'name' или 'name*' – оба варианта работают одинаково. Если в качестве префикса указана пустая строка, то будут удалены объекты с любым именем. Функция использует синхронный вызов – это...
 
Artyom Trishkin:

Preste atenção a este código:

Em particular ler sobre ObjectsDeleteAll() - há a razão e a resposta sobre como ajustá-la.

Obrigado!!! Classificou-o, agora funciona sem eliminação.

 
As operações da base de dados SQLite estão disponíveis a partir do testador? Refiro-me à adição e alteração de dados.
 
Dmitri Custurov:
As operações da base de dados SQLite estão disponíveis a partir do testador? Refiro-me à adição e alteração de dados.

Disponível. Basta manter um olho na localização da base. São criados da mesma forma que os ficheiros.

 
Alexey Viktorov:

Disponível. Basta manter um olho na localização da base. São criados tal como os ficheiros.

#define  DB_NAME "OHLC_DB"

int db_handle;
string TableName;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){
   db_handle = DatabaseOpen(DB_NAME, DATABASE_OPEN_READWRITE|DATABASE_OPEN_CREATE); 

   if (db_handle != INVALID_HANDLE){
      Print(StringFormat("Database %s was opened", DB_NAME));
      
      TableName = Symbol() + "_" + enumTimeFrameToString(Period());
      if (DatabaseTableExists(db_handle, TableName)){
         Print(StringFormat("Table %s is exist", TableName));
      }else{
         if (DatabaseExecute(db_handle, "CREATE TABLE " + TableName + "("
                             "TIME TEXT PRIMARY KEY  NOT NULL,"
                             "OPEN              REAL NOT NULL,"
                             "HIGH              REAL NOT NULL,"
                             "LOW               REAL NOT NULL,"
                             "CLOSE             REAL NOT NULL );")){
            Print(StringFormat("Table %s was created", TableName));
            string time = "'" + TimeToString(iTime(Symbol(), PERIOD_CURRENT, 0)) + "'";
            double open = iOpen(Symbol(), PERIOD_CURRENT, 0);
            double high = iHigh(Symbol(), PERIOD_CURRENT, 0);
            double low = iLow(Symbol(), PERIOD_CURRENT, 0);
            double close = iClose(Symbol(), PERIOD_CURRENT, 0);

            if (!DatabaseExecute(db_handle,"INSERT INTO " + TableName + " (TIME,OPEN,HIGH,LOW,CLOSE) "
                                           "VALUES (" + StringFormat("%s,%.5f,%.5f,%.5f,%.5f", time, open, high, low, close) + ");")){
               Print("Table: ", TableName, " insert failed with code ", GetLastError());
               DatabaseClose(db_handle);
               return(INIT_FAILED);
            }else
               Print("New table started:");   
         }else{
            Print(StringFormat("Could not create %s table. Error is: %d", TableName, GetLastError()));
            DatabaseClose(db_handle);
            return(INIT_FAILED); 
         }
      }
      
      return(INIT_SUCCEEDED);
   }else{
      Print("Could not open db. Error is: ", GetLastError());
      return(INIT_FAILED); 
   }     
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   DatabaseClose(db_handle);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
   string time = "'" + TimeToString(iTime(Symbol(), PERIOD_CURRENT, 0)) + "'";
   double open = iOpen(Symbol(), PERIOD_CURRENT, 0);
   double high = iHigh(Symbol(), PERIOD_CURRENT, 0);
   double low = iLow(Symbol(), PERIOD_CURRENT, 0);
   double close = iClose(Symbol(), PERIOD_CURRENT, 0);
   if (!DatabaseExecute(db_handle,"INSERT INTO " + TableName + " (TIME,OPEN,HIGH,LOW,CLOSE) "
                                  "VALUES (" + StringFormat("%s,%.5f,%.5f,%.5f,%.5f", time, open, high, low, close) + ");")){
      Print("Table: ", TableName, " insert failed with code ", GetLastError());
      DatabaseClose(db_handle);
   }   
}
//+------------------------------------------------------------------+
string enumTimeFrameToString(ENUM_TIMEFRAMES frame){
   switch(frame){
      case PERIOD_M1:  return "M1";
      case PERIOD_M2:  return "M2";
      case PERIOD_M3:  return "M3";
      case PERIOD_M4:  return "M4";
      case PERIOD_M5:  return "M5";
      case PERIOD_M6:  return "M6";
      case PERIOD_M10: return "M10";
      case PERIOD_M12: return "M12";
      case PERIOD_M15: return "M15";
      case PERIOD_M20: return "M20";
      case PERIOD_M30: return "M30";
      case PERIOD_H1:  return "H1";
      case PERIOD_H2:  return "H2";
      case PERIOD_H3:  return "H3";
      case PERIOD_H4:  return "H4";
      case PERIOD_H6:  return "H6";
      case PERIOD_H8:  return "H8";
      case PERIOD_D1:  return "D1";
      case PERIOD_W1:  return "W1";
      default:         return "MN1";
   }
}

Aqui está o meu código. Na inicialização, cria um registo na tabela. No corpo do OnTick deve devolver imediatamente um erro, porque tento adicionar um registo com a mesma CHAVE PRIMÁRIA, e depois disso a base fecha imediatamente. Mas ao mesmo tempo devia ver pelo menos o primeiro registo quando o abro, mas quando o corro no provador não está lá. E mesmo a mesa não é criada. Se eu apenas o abrir no terminal, tudo é normal. O primeiro registo está lá.

 
Dmitri Custurov:

Aqui está o meu código. Na inicialização, cria um registo na tabela. No corpo do OnTick deve devolver imediatamente um erro, porque tento adicionar um registo com a mesma CHAVE PRIMÁRIA, e depois disso a base fecha imediatamente. Mas ao mesmo tempo devia ver pelo menos o primeiro registo quando o abro, mas quando o corro no provador não está lá. E mesmo a mesa não é criada. Se eu apenas o abrir no terminal, tudo é normal. O primeiro registo está lá.

Mais uma vez estou convencido de que o testador e o próprio terminal são hipóstases diferentes.

 
HistorySelect(xxx,TimeCurrent()) miss the latest history order / deal sometimes. Now you have to use HistorySelect(xxx,TimeCurrent()+1) To get a more accurate result.

 
tickfenix:

Há muito que se recomenda acrescentar um dia àTimeCurrent(). É que agora, em resposta ao seu código não totalmente correcto, o terminal está a dar-lhe conselhos.

Razão: