初心者の方からの質問 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";
   }
}

以下は私のコードです。初期化では、テーブルに1つのレコードが作成されます。同じPRIMARY KEYを持つレコードを追加しようとすると、すぐにベースが閉じてしまうので、OnTickボディではすぐにエラーを返す必要があります。しかし同時に、少なくともその最初のレコードは開いたときに見えるはずなのですが、テスターで実行するとそれがないのです。さらにテーブルも作成されない。ターミナルで開くだけなら、すべて正常です。最初の記録はそこにある。

 
Dmitri Custurov:

以下は私のコードです。初期化では、テーブルに1つのレコードが作成されます。同じPRIMARY KEYを持つレコードを追加しようとすると、すぐにベースが閉じてしまうので、OnTickボディではすぐにエラーを返す必要があります。しかし同時に、少なくともその最初のレコードは開いたときに見えるはずなのですが、テスターで実行するとそれがないのです。さらにテーブルも作成されない。ターミナルで開くだけなら、すべて正常です。最初の記録はそこにある。

テスターと端末は別物だと改めて確信しました...。

 
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() に1日分を追加することは以前から推奨されています。ただ、今、あなたのコードが正確でないことに反応して、端末があなたにアドバイスを与えているのです。

理由: