Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 1219

 
Vladimir Karputov:

Sembra che il terminale continui a pompare la storia - così l'indicatore continua a ricalcolare. O un'altra variante: avete un numero MOLTO grande di barre impostate nel terminale per la visualizzazione sul grafico, e il vostro computer ha un numero MOLTO grande di barre sul grafico.

Grazie per l'aiuto!

Quando si seleziona una data diversa, il calcolo avviene immediatamente. Nel primo test c'era un divario di prezzo, forse mancavano alcuni prezzi - questo è molto probabilmente il problema.

 

C'è un indicatore MT5 "Grid Builder" che disegnalinee orizzontali in incrementi di prezzo. È possibile selezionare ad esempio 100p, 200p ecc. E costruisce una griglia orizzontale su e giù con un determinato passo. Ma ha un problema, per esempio, quando disegno livelli orizzontali sul timeframe H4 (ho messo linee orizzontali da strumenti di disegno nel terminale) e passo a qualsiasi altro timeframe, tutte le mie linee vengono rimosse. Rimangono solo i livelli orizzontali dell'indicatore. Come posso correggere questo errore nel codice? Per garantire che i miei livelli orizzontali non vengano mai cancellati. Ecco il codice dell'indicatore (ho scritto questa domanda in un altro thread, ma non c'è ancora una risposta)

//+------------------------------------------------------------------+
//|                                                  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. Дальнейшие уточнения свойств созданного объекта возможно с помощью функций по работе с графическими объектами.
 
Александр:

C'è un indicatore MT5 "Grid Builder" che disegnalinee orizzontali in incrementi di prezzo. È possibile selezionare ad esempio 100p, 200p ecc. E costruisce una griglia orizzontale su e giù con un determinato passo. Ma ha un problema, per esempio, quando disegno livelli orizzontali sul timeframe H4 (metto linee orizzontali da strumenti di disegno nel terminale) e passo a qualsiasi altro timeframe, tutte le mie linee vengono rimosse. Rimangono solo i livelli orizzontali dell'indicatore. Come posso correggere questo errore nel codice? Per garantire che i miei livelli orizzontali non vengano mai cancellati. Ecco il codice dell'indicatore (ho scritto questa domanda in un altro topic, ma non c'è risposta)

Fate attenzione a questo codice:

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

In particolare, leggete su ObjectsDeleteAll() - lì la causa e la risposta per la correzione.

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

Fate attenzione a questo codice:

In particolare leggete su ObjectsDeleteAll() - c'è la ragione e la risposta su come modificarlo.

Grazie!!! L'ho risolto, ora funziona senza cancellazione.

 
Le operazioni su database SQLite sono disponibili dal tester? Intendo aggiungere e cambiare i dati.
 
Dmitri Custurov:
Le operazioni del database SQLite sono disponibili dal tester? Intendo aggiungere e cambiare i dati.

Disponibile. Basta tenere d'occhio la posizione della base. Sono creati nello stesso modo dei file.

 
Alexey Viktorov:

Disponibile. Basta tenere d'occhio la posizione della base. Sono creati proprio come i file.

#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";
   }
}

Ecco il mio codice. Nell'inizializzazione crea un record nella tabella. Nel corpo di OnTick dovrebbe restituire immediatamente un errore, perché cerco di aggiungere un record con la stessa PRIMARY KEY, e dopo questo la base si chiude immediatamente. Ma allo stesso tempo dovrei vedere almeno il primo record quando lo apro, ma quando lo eseguo nel tester non c'è. E anche la tabella non viene creata. Se lo apro solo nel terminale, tutto è normale. Il primo disco è lì.

 
Dmitri Custurov:

Ecco il mio codice. Nell'inizializzazione crea un record nella tabella. Nel corpo di OnTick dovrebbe restituire immediatamente un errore, perché cerco di aggiungere un record con la stessa PRIMARY KEY, e dopo questo la base si chiude immediatamente. Ma allo stesso tempo dovrei vedere almeno il primo record quando lo apro, ma quando lo eseguo nel tester non c'è. E anche la tabella non viene creata. Se lo apro solo nel terminale, tutto è normale. Il primo disco è lì.

Ancora una volta sono convinto che il tester e il terminale stesso sono ipostasi diverse...

 
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:

È stato a lungo raccomandato di aggiungere un giorno aTimeCurrent(). È solo che ora, in risposta al tuo codice non proprio corretto, il terminale ti sta dando dei consigli.