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

 
Alexey Viktorov:
例えばこちら https://docs.mql4.com/ru/basis/preprosessor/compilation
ありがとうございました。
 
trader781:

今回の例では、限界を超えないように、任意のロットで無限に注文 できるようにしたい。

もちろん、限界はわかっているのですが、こうしたい

括弧で要素を指定すると、それが最後の要素になることから進めています

だから、こんなくだりがあったんだ。順番に期待していたのですが・・・。ロットではなく、結果(ロット)を注文に加えたい。

と、そこからのデータ取得の問題

私が見たところ、次のような結果を得たいのです。

MyArray[0][0.01]です。

MyArray[1][0.01]です。

MyArray[2][0.02]です。

など...

では、実際のところはどうなのでしょうか?

ロットで配列を書き、ロットサイズでソートすると、次のポジションがより大きなロットで開くので、オープニング番号でソートされます。

double BPosMass[];
double SPosMass[];

void OnTick()
{
// Заполняем массивы
int b=-1,s=-1; // Объявим переменные с минусом
  for(int i=0; i<OrdersTotal(); i++) {
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
    if(OrderSymbol()==Symbol() && (OrderMagicNumber()==Magic || Magic<0)) {
     if(OrderType()==OP_BUY) {
      b++;
       ArrayResize(BPosMass,b+1);
       BPosMass[b]= OrderLot();
     }
     if(OrderType()==OP_SELL) {
      s++;
       ArrayResize(SPosMass,s+1);
       SPosMass[s]= OrderLot();
     }
  }}} // конец записи массив

// Читаем отсортированный массив с лотами
// Buy
  if(b>0) { // Если он не пустой и больше двух элементов - [0], иначе будет ошибка: "Выход за пределы массива"
    ArraySort(BPosMass, WHOLE_ARRAY, 0, MODE_ASCEND); // Отсортируем по размеру лота
    // Работа с полученными данными
    Comment("Самый старый Buy лот: ",    BPosMass[0],
            "\nПоследний Buy лот: ",     BPosMass[b],
            "\nПредпоследний Buy лот: ", BPosMass[b-1]
           );

  } // end Buy

// Sell
  if(s>0) { // Если он не пустой и больше двух элементов - [0], иначе будет ошибка: "Выход за пределы массива"
    ArraySort(SPosMass, WHOLE_ARRAY, 0, MODE_ASCEND); // Отсортируем по размеру лота
    // Работа с полученными данными
    Comment("Самый старый Sell лот: ",    SPosMass[0],
            "\nПоследний Sell лот: ",     SPosMass[s],
            "\nПредпоследний Sell лот: ", SPosMass[s-1]
           );

  } // end Sell
  
// Конец функции OnTick()
}


そして、次のように適用します。ポジションの総数を数え、3つ以下なら配列にアクセスせず、それ以上なら配列を読み込んでデータを取得します。

配列の出力は書き込む瞬間ではなく、読み込む瞬間になります。

 
Vitaly Muzichenko:


配列の出力は書き込み時ではなく、読み出し時に発生します。

いや、存在しない配列のインデックスに アクセスした瞬間に。
 
Vitalie Postolache:
いや、そうではない。存在しない配列のインデックスに アクセスした瞬間。
で、何を書いたかというと
 
Vitaly Muzichenko:
で、何を書いたかというと

2017.01.1312:51:14.3722017.01.0516:30:00 martin GBPUSD,M5: MyArray[CountOrders][0]0.02の 場合
2017.01.1312:51:14.3722017.01.0516:25:00 martin GBPUSD,M5: MyArray[CountOrders][0]0.01の 場合

CountOrders一定でロット変更。こんなはずではなかった、でも他に方法がない

理想は、MyArray[CountOrders][OrderLots()] という項目です。

ということで、出力はMyArray[0][0.01]MyArray[1][0.01] となります。

が、µlではうまくいきません。

という関数から、何らかの方法でストリームに抽出します。
 
trader781:

2017.01.1312:51:14.3722017.01.0516:30:00 martin GBPUSD,M5: MyArray[CountOrders][0]0.02の 場合
2017.01.1312:51:14.3722017.01.0516:25:00 martin GBPUSD,M5: MyArray[CountOrders][0]0.01の 場合

CountOrders一定でロット変更。こんなはずではなかった、でも他に方法がない

理想は、MyArray[CountOrders][OrderLots()] という項目です。

ということで、出力はMyArray[0][0.01]MyArray[1][0.01] となります。

しかし、それはµlではうまくいきません

構造物があなたを助ける必要なフィールドを持つ構造体を作り、その配列を宣言 し、ループ内のオーダーデータをオープンタイムで埋めていき、その中から必要なものを探していくのである。構造体のフィールドをインデックスで確認し、必要な値と比較する。インデックスには開始時間ごとにオーダー番号が表示され、そのオーダーに関する必要なデータはすべて構造体のフィールドに表示されます。
 
Artyom Trishkin:
構造物があなたを助ける必要なフィールドを持つ構造体を作り、その配列を宣言 し、ループ内のオーダーデータをオープンタイムで埋めていき、その中で必要なものを全て検索する。構造体のフィールドをインデックスで確認し、必要な値と比較する。インデックスにはオーダー番号とその開始時刻が表示され、そのオーダーに関する必要なデータはすべて構造体のフィールドに記載されます。

こんなクソゲーがあったのか

struct myorder
{
int    Ticket;
double orderopenprice;
int   ordertype;
double profit;
double stoploss;
double  lot;
};

myorder orders[];

int i;
void CalcOrders()
{
for(i=OrdersTotal()-1; i>=0; i--)
     {
      if((OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) && (OrderSymbol()==Symbol())
         && (OrderMagicNumber()==Magic) && (OrderType()<2))
         orders[i].Ticket=OrderTicket();
         orders[i].lot=OrderLots();
         orders[i].orderopenprice=OrderOpenPrice();
         orders[i].ordertype=OrderType();
         orders[i].profit=OrderProfit();
         orders[i].stoploss=OrderStopLoss();
     }
}    


例えば注文のロット5を取り出して、ロット3と比較したいのですが

始値を加算し、ポジション数で割る

このような場合、コマンド入力そのものが必要です。

 
trader781:

こんなのあったんだ

struct myorder
{
int    Ticket;
double orderopenprice;
int   ordertype;
double profit;
double stoploss;
double  lot;
};

myorder orders[];

int i;
void CalcOrders()
{
for(i=OrdersTotal()-1; i>=0; i--)
     {
      if((OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) && (OrderSymbol()==Symbol())
         && (OrderMagicNumber()==Magic) && (OrderType()<2))
         orders[i].Ticket=OrderTicket();
         orders[i].lot=OrderLots();
         orders[i].orderopenprice=OrderOpenPrice();
         orders[i].ordertype=OrderType();
         orders[i].profit=OrderProfit();
         orders[i].stoploss=OrderStopLoss();
     }
}    


例えば、注文のロット5を取り出して、ロット3と比較したい。

始値を加算し、ポジション数で割る

こういう時のために、コマンド形式のエントリーそのものが必要です

ループインデックスiは必要な順番だけでなく、任意の順番を参照するので、配列の大きさを 担当する変数(例えばn=0;)を関数内で宣言しておくとよいでしょう。チェックを通過した後,ループ内でこの変数の値を増加させ,この変数の値だけ配列サイズを増加させ,インデックスn-1に従って構造体フィールドを埋める: orders[n-1].xxx=XXX;

 

OrdersTotal()関数で 注文を検索すると-1と表示されるのはなぜか教えてください。

例:for (i=OrdersTotal()-1 ;i>=0; i--)

なぜOrdersTotal()でないのか?

この関数での注文のカウントは0から始まるのでしょうか、それとも1から始まるのでしょうか?つまり、注文が1件の場合、OrdersTotal()は0になるのか1になるのか?

 
Artyom Trishkin:

ループインデックス i は必要なオーダーだけでなく、任意のオーダーを参照するので、関数内で配列サイズを担当する変数(例えば n=0;)を宣言しておく必要があります。チェックを通過した後,ループ内でこの変数の値を増加させ,この変数の値だけ配列サイズを増加させ,インデックスn-1で構造体フィールドを埋めます: orders[n-1].xxx=XXX;

オーダーのパックがあるのだから、正しいオーダーを引き出せばいいのでは?(必要なもの)を使って、やりたいことをやるか? 例:注文(i-4)
理由: