// Читаем отсортированный массив с лотами // 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] );
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の 場合
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の 場合
ループインデックス i は必要なオーダーだけでなく、任意のオーダーを参照するので、関数内で配列サイズを担当する変数(例えば n=0;)を宣言しておく必要があります。チェックを通過した後,ループ内でこの変数の値を増加させ,この変数の値だけ配列サイズを増加させ,インデックスn-1で構造体フィールドを埋めます: orders[n-1].xxx=XXX;
例えばこちら https://docs.mql4.com/ru/basis/preprosessor/compilation
今回の例では、限界を超えないように、任意のロットで無限に注文 できるようにしたい。
もちろん、限界はわかっているのですが、こうしたい
括弧で要素を指定すると、それが最後の要素になることから進めています
だから、こんなくだりがあったんだ。順番に期待していたのですが・・・。ロットではなく、結果(ロット)を注文に加えたい。
と、そこからのデータ取得の問題
私が見たところ、次のような結果を得たいのです。
MyArray[0][0.01]です。
MyArray[1][0.01]です。
MyArray[2][0.02]です。
など...
では、実際のところはどうなのでしょうか?
ロットで配列を書き、ロットサイズでソートすると、次のポジションがより大きなロットで開くので、オープニング番号でソートされます。
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つ以下なら配列にアクセスせず、それ以上なら配列を読み込んでデータを取得します。
配列の出力は書き込む瞬間ではなく、読み込む瞬間になります。
配列の出力は書き込み時ではなく、読み出し時に発生します。
いや、そうではない。存在しない配列のインデックスに アクセスした瞬間。
で、何を書いたかというと
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ではうまくいきません。
という関数から、何らかの方法でストリームに抽出します。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ではうまくいきません
構造物があなたを助ける必要なフィールドを持つ構造体を作り、その配列を宣言 し、ループ内のオーダーデータをオープンタイムで埋めていき、その中で必要なものを全て検索する。構造体のフィールドをインデックスで確認し、必要な値と比較する。インデックスにはオーダー番号とその開始時刻が表示され、そのオーダーに関する必要なデータはすべて構造体のフィールドに記載されます。
こんなクソゲーがあったのか
{
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と比較したいのですが
始値を加算し、ポジション数で割る
このような場合、コマンド入力そのものが必要です。
こんなのあったんだ
{
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になるのか?
ループインデックス i は必要なオーダーだけでなく、任意のオーダーを参照するので、関数内で配列サイズを担当する変数(例えば n=0;)を宣言しておく必要があります。チェックを通過した後,ループ内でこの変数の値を増加させ,この変数の値だけ配列サイズを増加させ,インデックスn-1で構造体フィールドを埋めます: orders[n-1].xxx=XXX;