MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 122

 

前の質問に追加することにした。

1)

仮にシグナルがあったとして、(ニュースで)スプレッドが急激に拡大したとき

現在の取引をすべて終了する

しかし、注文はニュースの間だけ閉じたり開いたりするわけではありません。

したがって、例えばOrderCloseというコマンドをループに入れ+Sleep(3000)して、閉じるまで実行すると

2)

ボタンに内部変数をバインドして、押された値/閉じられた値を注文の開始可能性に代入すれば、リアルタイムに動作するのでしょうか?

 
trader781:

前の質問に追加することにした。

1)

仮にシグナルがあったとして、(ニュースで)スプレッドが急激に拡大したとき

現在の取引をすべて終了する

しかし、注文はニュースの間だけ閉じたり開いたりするわけではありません。

したがって、例えばOrderCloseというコマンドをループに入れ+Sleep(3000)して、閉じるまで実行すると

2)

ボタンに内部変数をバインドして、押された値/閉じられた値を注文の開始可能性に代入すれば、リアルタイムに動作するのでしょうか?

1)Sleep(3000)ではなく、エラー処理で解決します。
 

はじめましてチャート上に注文履歴を描画するインジケータを作成して います。

//+------------------------------------------------------------------+
//|                                                      history.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

extern int        MagicNumber                = 1110;
extern datetime   HistoryOrdersFromDateTime  = 0;
extern color      SellColor                  = clrRed;
extern color      BuyColor                   = clrBlue;
extern color      ProfitColor                = clrWhite;
extern bool       DeleteHistoryOrders        = false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

void start()
{
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
      {
         if(HistoryOrdersFromDateTime<OrderCloseTime())
         {
            if((TimeCurrent()-OrderCloseTime())>60)
               HistoryOrders();
         }
      }
   }
}

void HistoryOrders()
{
   double b=OrderOpenPrice(), d=OrderClosePrice(), lots=OrderLots(), Profit=0;
   datetime a=OrderOpenTime(), c=OrderCloseTime(), close_time;
   string Ticket=(string)OrderTicket(), type="Sell", symbol=OrderSymbol(), comment=OrderComment(), Background;
   color col=SellColor;
   if(OrderType()==0) {col=BuyColor; type="Buy";}

   if(DeleteHistoryOrders==false)
   {
      //Начальная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJ_ARROW,0,a,b);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_ARROWCODE,1);
      
      //Линия  
      ObjectCreate("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJ_TREND,0,a,b,c,d);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_WIDTH,1);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_STYLE,STYLE_DOT);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_RAY,0);
  
      //Конечная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJ_ARROW,0,c,d);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_ARROWCODE,3);

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
      
      //Размер фона  
      for(int i=2; i<StringLen(DoubleToString(Profit,2)); i++)
         StringAdd(Background,"g");
      
      //Фон профита
      ObjectCreate("#"+Ticket+" Background",OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Background",Background,10,"Webdings",col);
      ObjectSet("#"+Ticket+" Background",OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_TIME1,c+Period());
  
      //Профит
      ObjectCreate("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Profit: "+DoubleToString(Profit,2),DoubleToString(Profit,2),10,"Arial",ProfitColor);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_TIME1,c+Period());
   } else ObjectsDeleteAll(0, "#"+Ticket+" ");  
}

void OnDeinit(const int reason)
{  
   //Удалаение истории ордеров
   for(int i=0; i<OrdersHistoryTotal(); i++)
   {
      DeleteHistoryOrders=true;
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         HistoryOrders();
   }
}

このインジケータは単一取引を正しく描画しますが(line>background>profit)、決済済み注文セットの表示には小さな「バグ」があり(スクリーンショットを添付)、ラインが背景と利益の上に重なっています(line(1)>background>profit>line(2)>line(3)>line(4) ... ....).

次のようになります。(行(1)>行(2)>行(3)>行(4) ... ....>フォン>プロフィット)。様々な改ざんがうまくいっていない、改修にご協力ください。

ファイル:
 
ilnur17021992:

はじめまして注文履歴をチャート上に表示するインジケータを作成して います。


このインジケータは単一の取引を正しくレンダリングしますが(line>background>profit)、クローズドオーダーのセットの表示では小さな「シューッ」という音がして(スクリーンショットを添付します)、ライン(line(1)>background>profit>line(2) > line(3)>line(4) ... ... )と背景および利益が重なります。).

次のようになります。(行(1)>行(2)>行(3)>行(4) ... ....>フォン>プロフィット)。様々な改ざんがうまくいっていない、改修にご協力ください。

OBJPROP_BACK プロパティにラインやアイコンをバックグラウンドで割り当ててみて ください。
ObjectSetInteger - Графические объекты - Справочник MQL4
ObjectSetInteger - Графические объекты - Справочник MQL4
  • docs.mql4.com
ObjectSetInteger - Графические объекты - Справочник MQL4
 
Alexey Viktorov:
背景の ラインやアイコンにOBJPROP_BACK プロパティを割り当ててみてください。
ローソク足の上に描画されるはずのラインが、背景(ローソク足の後ろ)に描画されます:ローソク足>ライン>利益背景>利益
ファイル:
 
ilnur17021992:
オプションではないので、ラインはバックグラウンド(ローソク足の後ろ)にあり、描画はローソク足の上にあるべきです:ローソク足>ライン>利益>利益バックグラウンド
そして、チャートへの描画の順序のみ。あるいは、背景や利益を描画する際に、時間軸でこれらのオブジェクトの存在を確認し、OBJ_TEXTオブジェクトの 利益値を読み込んで、現在の注文の利益に加算しておく。そして、背景とプロフィットを削除して、再度描画する必要があります。
ちなみに、これによって利益計算のための追加サイクルがなくなります。

こんなことができます
      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
他のすべての注文パラメータと一緒に、最初に利益を定義します。

ps お願いします。このボタンで写真を配置する
 
Alexey Viktorov:
そして、チャートへの描画の順序のみ。あるいは、背景や利益を描画する際に、時間によってこれらのオブジェクトの有無を確認し、OBJ_TEXTオブジェクトの 利益の値を読み取って、現在の注文の利益に加算しておく。そして、背景とプロフィットを削除して、再度描画する必要があります。
ちなみに、これによって利益計算のための追加サイクルが不要になります。
他のすべての注文パラメータと一緒に、最初に利益を定義します。

この描画順序、例えば最初にすべての点とそれを結ぶ線を描き、次に背景と利益を描くようにするには、どのように設定すればよいのでしょうか。

 
ilnur17021992:

この描画の順序、例えば、最初にすべての点とそれを結ぶ線を描き、次に背景と利益を描くように進めるには、どのように設定すればよいのでしょうか。

まあ、最初の仮定で言えば、そうなんですけどね。と、すぐに即興で思いつき、最初の文章は削除しませんでしたが、2番目の文章の方が好きです。

このバリエーションを検討したほうがいい。

ObjectFind() で、 オブジェクトが見つかったらObjectGetString() でテキストから数値に変換し、得られた値に最後のオーダーの利益を加え、古くなった OBJ_TEXT を削除して新しいものを描画 します。
このバーで決済された最初の注文または唯一の注文であれば,単に
OBJ_TEXTを 描画して終了する。
より簡単にするために、チケットの代わりにバーの開店
時間を指定する必要があります。それとも、今後の作業のためにチケットが必要なのでしょうか?

 
Alexey Viktorov:
まあ、最初の推測で言えば、そうなんですけどね。と、すぐに思いつき、最初の文章は消さなかったのですが、2番目の文章の方が好きです。

このバリエーションを検討したほうがいい。

ObjectFind() で、 オブジェクトが見つかったらObjectGetString() でテキストから数値に変換し、得られた値に最後のオーダーの利益を加え、古くなった OBJ_TEXT を削除して新しいものを描画 します。
このバーで決済された最初の注文または唯一の注文であれば,単に
OBJ_TEXTを 描画して終了する。
より簡単にするために、チケットの代わりにバーの開店
時間を指定する必要があります。それとも、今後の作業のためにチケットが必要なのでしょうか?

そうです、チケットは後でストーリーを分析するために必要なのです。再描画のヒントありがとうございました。このチェックと再描画をコードに追加することで、少し楽に問題を解決しました。

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

正しいかどうかはわかりませんが、原理的にはあるべき姿(ライン>フォン>プロフィット)で描画されます。

 
ilnur17021992:

そうですね、チケットは後で履歴を分析するのに必要です。このようなチェックと再描画をコードに追加することで、少し簡単に問題を解決することができました。

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

基本的には正しく描画されます(線>背景>利益)。

まあ、それはいいとして、嬉しいですね。