ObjectMove

この関数は、指定されたアンカーポイントまたはオブジェクトの座標を変更します。

bool  ObjectMove(
  long      chart_id,        // チャート識別子
  string    name,            // オブジェクト名
  int      point_index,    // アンカーポイント番号
  datetime  time,            // 時間
  double    price            // 価格
  );

パラメータ

chart_id

[in]  チャート識別子( 0 は現在のチャート)

name

[in]  オブジェクト名

point_index

[in]  アンカーポイントのインデックス。アンカーポイントの数はオブジェクト型によって違います。

time

[in]  選択されたアンカーポイントの時間座標

価格

[in]  選択されたアンカーポイントの価格座標

戻り値

この関数は、指定されたチャートのキューにコマンドが正常に追加された場合はtrueを返し、それ以外の場合はfalseを返します。

注意事項

ObjectMove()では常に非同期呼び出しが使用されます。これが、この関数がチャートキューにコマンドを追加した結果だけを返す理由です。この場合、trueはコマンドが正常にエンキューされたことを意味しますのみで、その実行結果は不明です。

コマンドの実行結果を確認するにはオブジェクトプロパティをレクエストするObjectGetXXXなどのその他の関数を使用できます。ただし、そのような関数はそのチャートのキューの最後に追加され、(同期呼び出しのために)実行結果を待つため、時間がかかる可能性があります。チャート上で多数のオブジェクトを操作する場合は、この特徴を考慮する必要があります。

 

例:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link     "https://www.mql5.com"
#property version   "1.00"
 
#define   OBJ_NAME_ASK     "TestObjectMoveAsk" // Ask価格のグラフィックオブジェクトの名前
#define   OBJ_NAME_BID     "TestObjectMoveBid" // Bid価格のグラフィックオブジェクトの名前
#define   COUNT           100000000           // 歴史を読み込むティックの数
#define   DELAY           1                   // ティック間の遅延(ミリ秒単位)
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                              |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- 現在のチャートID、チャートシンボル、およびシンボルの小数桁数
  long   chart_id= ChartID();
  string symbol  = ChartSymbol(chart_id);
  int   digits  = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
 
//--- チャート上に、Ask価格とBid価格を表示する2つの価格ラベルを作成する
  if(!CreatePriceLabel(chart_id, true) || !CreatePriceLabel(chart_id, false))
    return;
 
//--- ティックを受け取る配列
  MqlTick ticks[]={};
 
//--- チャート上の次の可視バーの番号と、このバーの始値時間(ミリ秒単位)を取得する
  int   first= (int)ChartGetInteger(chart_id, CHART_FIRST_VISIBLE_BAR)-1;
  ulong from = GetTime(symbol, PERIOD_CURRENT, first)*1000;
 
//--- ティック履歴を配列に読み込む
  Print("Started collecting ticks...");
  if(!GetTicksToArray(symbol, ticks))
    return;
     
//--- ティック配列をリセットし、チャート上の可視バー範囲からティックを取得する
  ZeroMemory(ticks);
  if(CopyTicksRange(symbol, ticks, COPY_TICKS_INFO, from)<1)
    {
    PrintFormat("CopyTicksRange() from date %s failed. Error %d", TimeToString(GetTime(symbol, PERIOD_CURRENT, first)), GetLastError());
    return;
    }
 
  Sleep(500);
  PrintFormat("Tick ​​visualization started at %s (%I64u), ticks total: %u", TimeToString(GetTime(symbol, PERIOD_CURRENT, first)), from, ticks.Size());
 
  int count=0;                 // 処理されたティックの数
  int changes=0;               // 処理された値動きの数
  int total=(int)ticks.Size(); // ティック配列サイズ
 
//--- ティック配列のループ
  for(int i=0; i<total && !IsStopped(); i++)
    {
    //--- 配列からティックを取得し、ティックカウンターをインクリメントする
    MqlTick tick=ticks[i];
    count++;
     
    //--- ティックのAskとBidのフラグを確認する
    bool ask_tick=((tick.flags &TICK_FLAG_ASK)==TICK_FLAG_ASK);
    bool bid_tick=((tick.flags &TICK_FLAG_BID)==TICK_FLAG_BID);
    bool done=false;
     
    //--- Ask価格が変わった場合
    if(ask_tick)
       {
        if(Move(chart_id, OBJ_NAME_ASK, tick.time, tick.ask))
          {
          changes++;
          done=true;
          }
       }
    //--- Bid価格が変わった場合
    if(bid_tick)
       {
        if(Move(chart_id, OBJ_NAME_BID, tick.time, tick.bid))
          {
          changes++;
          done=true;
          }
       }
    //--- いずれか(または両方)のグラフィックオブジェクトが移動された場合、チャートを更新する
    if(done)
       {
        ChartRedraw(chart_id);
        Sleep(DELAY);
       }
    }
 
//--- ループ終了時に処理したティック数を操作ログに報告し、
//--- 数秒待機後、作成したオブジェクトを削除してチャートを再描画する
  PrintFormat("Total ticks completed: %u, Total price changes: %d", count, changes);
  Sleep(2000);
  if(ObjectsDeleteAll(chart_id, "TestObjectMove")>0)
    ChartRedraw(chart_id);
  /*
スクリプト実行の結果、チャート上にAskBid価格の動きが表示され、
   チャート左端から過去データの最後まで
   操作ログには以下のデータが表示される
  Started collecting ticks...
  AUDUSD: received 13726794 ticks in 969 ms
  Tick ​​visualization started at 2025.01.31 09:00 (1738314000000), ticks total: 44380
  Total ticks completed: 44380, Total price changes: 68513
  */
 }
//+------------------------------------------------------------------+
//| 価格ラベルオブジェクトを作成する                                           |
//+------------------------------------------------------------------+
bool CreatePriceLabel(const long chart_id, const bool obj_ask)
 {
  string obj_name=(obj_ask ?OBJ_NAME_ASK : OBJ_NAME_BID);
  ResetLastError();
  if(!ObjectCreate(chart_id, obj_name, (obj_ask ?OBJ_ARROW_RIGHT_PRICE : OBJ_ARROW_LEFT_PRICE), 0, 0, 0))
    {
    PrintFormat("%s: ObjectCreate() failed. Error %d",__FUNCTION__, GetLastError());
    return(false);
    }
  return(ObjectSetInteger(chart_id, obj_name, OBJPROP_COLOR, (obj_ask ?clrRed : clrBlue)));
 }
//+------------------------------------------------------------------+
//| 指定された価格/時間座標にグラフィックオブジェクトを移動する |
//+------------------------------------------------------------------+
bool Move(const long chart_id, const string obj_name, const datetime time, const double price)
 {
  ResetLastError();
  if(!ObjectSetInteger(chart_id, obj_name, OBJPROP_TIME, time))
    {
    PrintFormat("%s: ObjectSetInteger() failed. Error %d",__FUNCTION__, GetLastError());
    return(false);
    }
  if(!ObjectSetDouble(chart_id, obj_name, OBJPROP_PRICE, price))
    {
    PrintFormat("%s: ObjectSetDouble() failed. Error %d",__FUNCTION__, GetLastError());
    return(false);
    }
  return(true);
 }
//+------------------------------------------------------------------+
//| ティックを配列に読み込む                                                |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbol, MqlTick &array[])
 {
  int attempts=0;     // ティック履歴を読み込む試みのカウンタ
  bool success =false; // 正常なティックコピーのフラグ
 
//--- ティックの受信を3回試行する
  while(attempts<3)
    {
    //--- ティックを受信する前に開始時間を測定する
    uint start=GetTickCount();
     
    //--- 1970.01.01 00:00.001 以降のティック履歴を要求する (パラメータ from=1 ms)
    ResetLastError();
    int received=CopyTicks(symbol, array, COPY_TICKS_ALL, 1, COUNT);
    if(received!=-1)
       {
        //--- ティック数と経過時間に関するデータを表示する
        PrintFormat("%s: received %d ticks in %d ms", symbol, received, GetTickCount()-start);
        //--- ティック履歴が同期されている場合、エラーコードはゼロになる
        if(GetLastError()==0)
          {
          success=true;
          break;
          }
        else
          PrintFormat("%s: %s ticks are not synchronized yet, %d ticks received for %d ms. Error=%d",
          __FUNCTION__, symbol, received, GetTickCount()-start, GetLastError());
       }
    //--- 試行回数を数える
    attempts++;
    //--- ティック データベースの同期が終了するまで1秒間待機する
    Sleep(1000);
    }
//--- ティック履歴の先頭から要求されたティックの取得が3回の試行で失敗する  
  if(!success)
    {
    PrintFormat("Error!Failed to get ticks for symbol %s after three attempts", symbol);
    return(false);
    }
  return(true);
 }
//+------------------------------------------------------------------+
//| バーインデックスによって時間を返す                                          |
//+------------------------------------------------------------------+
datetime GetTime(const string symbol, const ENUM_TIMEFRAMES timeframe, const int index)
 {
  datetime array[1]={};
  ResetLastError();
  if(CopyTime(symbol, timeframe, index, 1, array)!=1)
    PrintFormat("%s: CopyTime() failed. Error %d",__FUNCTION__, GetLastError());
  return(array[0]);
 }