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

 
PolarSeaman:

なんというひねくれ者!))

オーダー1(#noから#2へ) -- >オーダー2(#1から#3へ) -- >オーダー3(#2から#noへ)

ここからチェーン全体を見つけることができます。

オープンコメントを見て、from#XXXがあれば、以前部分的にクローズされたことを意味します。コメントからチケットXXXを探し、履歴から探します。コメントからチケットYYYを探し、履歴を検索してください。コメントを見る - from#ZZZZがあれば、先ほども一部閉鎖されていたことを意味します - 検索を繰り返す。from#...がない場合は,全チェーンの先頭となる。

 
Artyom Trishkin:

オーダー1(#noから#2へ) -- > オーダー2(#1から#3へ) -- > オーダー3(#2から#noへ)

ここからチェーン全体を見つけることができます。

オープンコメントを見て、from#XXXがあれば、以前部分的にクローズされたことを意味します。コメントからチケットXXXを探し、履歴から探します。コメントからチケットYYYを探し、履歴を検索してください。コメントを見る - from#ZZZZがあれば、先ほども一部閉鎖されていたことを意味します - 検索を繰り返す。もしfrom#...がなければ、全チェーンの一番最初になります。

ありがとうございます。逆方向の注文もあるかもしれませんので、それも刻んでおきます。混乱するのが怖いんです。もちろん、ポジションを 一部決済すると日付が変わるので、ポジションを建てた 日が分かれば、ある日付のProfit orderを使うのは簡単だと思うのですが......。

 
Artyom Trishkin:

オーダー1(#noから#2へ) -- > オーダー2(#1から#3へ) -- > オーダー3(#2から#noへ)

ここからチェーン全体を見つけることができます。

開いているコメントを見て、もしfrom#XXXがあれば、それは以前に部分的に閉じられたことを意味します - コメントからチケットXXXを探し、履歴を探します。コメントを表示する - from#YYYYがある場合 - つまり、以前も部分的に閉じていた - コメントからチケットYYYを表示し、履歴を探します。コメントを見る - from#ZZZZがあれば、先ほども一部閉鎖されていたことを意味します - 検索を繰り返す。もしfrom#...がなければ、全チェーンの一番最初になります。

アルチョムは、必ずしもそうではないことを知っていますね。そして、端末に3回質問しないようにチェーンをトレースしないために、歴史はすべて同じで、独自の配列と構造で駆動されます。余分なステップを除けば、自分でデータベースを管理するのと何ら変わりはありません

端末とそのAPIは最低レベルです。そして、ロボットの論理を実現するためには、その用語(トレード、チェーン、グループ、トランザクションなど、人によって呼び方が違う)で会計を行うことが論理的です。くしゃみ(ティック/バー)のたびに再構築しようとせず、分けて考えるのが賢明というものです。

 
Maxim Kuznetsov:

アルチョムさん、いつもそうとは限らないでしょ。そのため、チェーンを追跡する際に端末に3回尋ねる必要はありません。ストーリーは、独自の配列と構造体に駆動されたままです。余分なステップを除けば、自分でデータベースを管理するのと何ら変わりはありません

端末とそのAPIは最低レベルです。そして、ロボットロジックを実現するためには、その用語(トレード、チェーン、グループ、トランザクションなど、人によって呼び方が異なる)で勘定することが論理的である。くしゃみ(ティック/バー)のたびに再構築しようとせず、分けて考えるのが賢明というものです。

私は長い間、それをすべて行ってきました。毎回履歴を読むわけではありませんが、常に最新で、必要なものはすべてそこで簡単に、非常に素早く見つけることができます。しかし、誰かに同じことをアドバイスするには、少なくとも2、3の記事が必要です。それで、全体の連鎖を見つけるロジックを書きました。

 
PolarSeaman:

ありがとうございます!逆方向の注文もあるかもしれないので、それもシュレッダーします。混乱するのが怖いんです。もちろん、いつポジションを建てた のかが分かればの話ですが、部分決済では日付が変わってしまうので、ある日付からポジションを 閉じるには、Profit機能を使うのが簡単だと思います。

検索関数にパラメータとしてチケットを渡すと,出力として,チェーン全体の各オーダーの全データを含む,満たされた配列または構造体の配列が得られます.

 
Artyom Trishkin:

チェーン全体の各オーダーの全データを含む、フィルド・アレイまたは構造体のアレイ。

今おっしゃったことが、だいたいわからないんです。

せめて、こうあるべきという例を示してほしい。

 
PolarSeaman:

今おっしゃったことが、だいたいわからないんです。

せめて、こうあるべきという例を教えてください。

私は、次のような方法で問題を解決しています:歴史によって連鎖を探すのです。まあ、履歴が一義的にわかるように、私は2つのバリエーションを使い分けているのですが。

  1. DLLを使用しない場合は、プログラムの説明の24太字 ))) で、アカウント履歴を常に完全に読み込むように指定しています(ターミナルウィンドウのアカウント履歴タブ、コンテキストメニュー- すべての履歴)。
  2. DLL - Expert Advisorでは、ユーザーの操作に関係なく、「アカウント履歴」タブが常に最新の状態に保たれます。

現在のオーダーが主でない場合に、親オーダーを決定するための関数。

int GetSignOfPartialOrCloseByClose()
{
   string comment = OrderComment();
   if (comment == "")
      return 0;
   
   // Ордер образовался вследствии частичного закрытия
   int fromStart = StringFind(comment, "from #");
   if (fromStart >= 0)
      return GetTicketByPartialClose(comment, fromStart, OrderType(), OrderOpenTime());
   
   // Ордер образовался вследствии встречного закрытия
   if (StringFind(comment, "partial close") >= 0)
   {
      datetime openTime = OrderOpenTime();
      int type = OrderType();
      for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
      {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
            continue;
            
         if (OrderOpenTime() != openTime)
            continue;
            
         if (OrderType() != type)
            continue;
            
         if (StringFind(OrderComment(), "partial close") < 0)
            continue;
            
         return OrderTicket();
      }
   }
   
   return 0;
}


int GetTicketByPartialClose(string comment, int fromStart, int orderType, datetime openTime)
{
   string sTicket = StringSubstr(comment, fromStart + 6);
   int iTicket = (int)StringToInteger(sTicket);
   int type = OrderType();
   if (!OrderSelect(iTicket, SELECT_BY_TICKET))
      return 0;
      
   if (OrderType() == type)                                                                        // Дочерний ордер указывает на родителя - уходим
      return iTicket;
      
   // Дочерний ордер указывает на противоположный ордер. Необходимо искать родительский
   for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         continue;
         
      if (OrderType() != orderType || OrderOpenTime() != openTime)
         continue;
         
      int iFind = StringFind(OrderComment(), "close hedge by #");
      if (iFind < 0)
         continue;
         
      sTicket = StringSubstr(OrderComment(), iFind + 16);
      int iNewTicket = (int)StringToInteger(sTicket);
      if (iNewTicket != iTicket)
         continue;
         
      return OrderTicket();
   }
   
   return 0;
}

使い勝手が良い。

   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;

      ....         

      int nFromTicket = GetSignOfPartialOrCloseByClose();                // Обязательно последней строкой в теле цикла, т. к. может измениться текущий выбранный ордер
   }


 
Ihor Herasko:

ここで最も大きなエラーは、OrderDelete()の引数にticketではなく値100を指定したことです。

次のエラーは、それほど荒っぽいものではありませんが、ストップロスの実際の値ではなく、計算された値をチェックしていることに関連しています。

注文の種類もチェックされない。成行注文を選択した場合はどうなりますか?削除する方法は?注文記号が確認されていない。

これらのエラーを考慮し、価格がストップロスに到達した時点で保留中の注文を削除 するコードを取得します。

また、あなたのコードでは、ストップロスは注文が開かれた直後にチェックされます。保留中の注文を開いた後、このコードは実行されなくなるようです。つまり、実行ブランチを分離する必要があるのです。1人はオーダーを決める役割、2人はその伴奏を担当する。

詳細なご回答をありがとうございました

アドバイスに従い、ブランチを分離したところ、すべてうまくいきました。

その後、10-15個の保留注文を同時に開く問題に直面しましたが、あなたのコードの後に追加することでこの問題を解決しました。

if (OrdersTotal ()>0) return;

きっと、もっといい方法があるはずです。

あなたのコードによって、1; i >=0; --i の意味を説明してください。

for (int i = OrdersTotal() - 1; i >= 0; --i)
 

インジケーターの書き方について教えて ください。このようなダミーを描いたのですが、インジケーターがチャートに配置された瞬間から、現在のBidより上のサイズで 描画されるようにするにはどうしたらよいでしょうか。もしかして、この配列を間違った方向にずらしているのがエラーなのでしょうか?

prev_calculatedなどのない "canonical "であることは分かっていますが、次のようなものが必要です。


#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot 
#property indicator_label1  "myInd"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double buff[], Bid;
input int lenght = 50, size = 5;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   ArrayResize(buff, 50);
   ArrayInitialize(buff, 0);
   SetIndexBuffer(0, buff, INDICATOR_DATA);
   //--- установим метку для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"myInd");   
//--- установим имя для показа в отдельном подокне и во всплывающей подсказке
   IndicatorSetString(INDICATOR_SHORTNAME,"myInd");
//--- укажем точность отображения значений индикатора
   IndicatorSetInteger(INDICATOR_DIGITS, _Point);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   for(int i = lenght-1; i>0; i--){
      buff[i] = buff[i-1];
   }
   buff[0] = Bid+size;
   


   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Roman Sharanov:

インジケーターの書き方について教えて ください。このようなダミーを描いたのですが、インジケーターがチャートに配置された瞬間から、現在のBidより上のサイズで 描画されるようにするにはどうしたらよいでしょうか。もしかして、この配列を間違った方向にずらしているのがエラーなのでしょうか?

prev_calculatedとかのない「カノニカル」なんだろうけど。


公式のドキュメントがあるのですが、まさにあなたのような感じです。

1. OnCalculateの内部で使用するすべての配列のシリアライズを設定する必要があります。

2.ループに入る前に、buff[length]=Bid+size; -とすると、ほぼ思い通りの結果が得られます。Bid+sizeで曲線とその先にある "バイザー"

3.配列の境界を見る。もちろん、rates_totalはほとんど<長さではありませんが、間違ってはいません :-)。

4.
buff[i] = buff[i+1]; // если тайм-серия (а вы подразумеваете их) то +