初学者的问题 MQL5 MT5 MetaTrader 5 - 页 1219

 
Vladimir Karputov:

看起来终端不断地抽出历史记录 - 所以指标不断地重新计算。或者另一种变体:你在终端中设置了非常多的条形图显示,而你的电脑在图表上有非常多的条形图。

谢谢你的帮助!

当你选择一个不同的日期时,计算会立即进行。在第一次测试中,价格有差距,可能遗漏了一些价格--这很可能是问题所在。

 

你好!有一个MT5指标 "Grid Builder",它以价格增量画出水平线你可以选择如100p、200p等。而且它以给定的步幅上下构建了一个水平网格。但它有一个问题,例如,当我在时间框架H4上绘制水平线时(我把水平线从绘图工具中放在终端),并切换到任何其他时间框架,我的所有线条都被删除。只剩下水平指标水平。我怎样才能纠正代码中的这个错误?为了确保我的水平层永远不会被删除。以下是指标代码(我在另一个主题中写了这个问题,但还没有答案)。

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

你好!有一个MT5指标 "Grid Builder",它以价格增量画出水平线你可以选择如100p、200p等。而且它以给定的步幅上下构建了一个水平网格。但它有一个问题,例如,当我在时间框架H4上绘制水平线时(我把水平线从绘图工具中放在终端),并切换到任何其他时间框架,我的所有线条都被删除。只剩下水平指标水平。我怎样才能纠正代码中的这个错误?为了确保我的水平层永远不会被删除。这是指标的代码(我在另一个主题中写了这个问题,但没有答案)。

请注意这个代码。

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

特别是,请阅读ObjectsDeleteAll()--那里有纠正的原因和答案。

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

请注意这个代码。

特别是阅读ObjectsDeleteAll()--那里有原因和如何调整它的答案。

谢谢你!!!。解决了这个问题,现在不用删除也能工作了。

 
SQLite数据库 的操作是否可以从测试者那里得到?我是指添加和改变数据。
 
Dmitri Custurov:
测试人员是否可以进行SQLite数据库操作?我是指添加和改变数据。

可用。只要注意基地的位置。它们的创建方式与文件的创建方式相同。

 
Alexey Viktorov:

可用。只要注意基地的位置。它们就像文件一样被创建。

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

以下是我的代码。在初始化过程中,它在表中创建了一条记录。在OnTick主体中,它应该立即返回一个错误,因为我试图添加一个具有相同PRIMARY KEY的记录,之后基地立即关闭。但与此同时,当我打开它时,我至少应该看到第一条记录,但当我在测试器中运行它时,它却不在那里。甚至连表也没有创建。如果我只是在终端打开它,一切都很正常。第一个记录在那里。

 
Dmitri Custurov:

以下是我的代码。在初始化过程中,它在表中创建了一条记录。在OnTick主体中,它应该立即返回一个错误,因为我试图添加一个具有相同PRIMARY KEY的记录,之后基地立即关闭。但与此同时,当我打开它时,我至少应该看到第一条记录,但当我在测试器中运行它时,它却不在那里。甚至连表也没有创建。如果我只是在终端打开它,一切都很正常。第一个记录在那里。

我再一次确信,测试器和终端本身是不同的假象......。

 
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:

长期以来,人们一直建议在TimeCurrent() 中增加一天。只是现在,作为对你不太正确的代码的回应,终端正在给你建议。