2次元配列の2次元によるソート

 

2 つのデータを配列に入れ、それをソートする必要があります。

まず、注文を2つの配列に分割します。最初の配列は買い用で、もう1つは売り用です。このとき、OrderTicketを収集し、後で注文を実行できるようにします。もう一つは、注文の OrderClosePrice 値を収集して、全く同じ別のリストと比較できるようにします。

最初の配列は

double AryBuys[][2];
double ArySells[][2]。

AryBuy[1][0]にはチケットが、AryBuy[1][1]には価格が格納されています。

2番目の次元をソートして、価格の降順で配列を並べ 替えるにはどうしたらよいでしょうか。

注:ArraySortでは、1次元目しかソートできません。 ここで考えられるのは、一時的な配列を作成し、価格を一時的な配列の最初の次元にし、それをソートし、それを配列にパイプで戻し、後でチケットでソートする必要があるときに逆に同じことを行うことができます。 これはうまくいくでしょうか?

 

しかし、2つの次元のデータを入れ替えて2番目の配列を作成し、その新しい配列を価格(1番目の次元)でソートすることができます。その後、(それでもよければ)データを元の配列にコピーして、もう一度各次元のデータを入れ替えることができます。これで、元の配列には元のデータが含まれていますが、2 次元の値でソートされた状態になっています。

不器用ですが、1次元以上のデータでソートするための唯一の実用的な方法です。

 

というのが私のメモに書いてあったことです。 心配なのは、1次元目がソートされることで、2次元目のデータもソートされるときに並べ替えが行われるのだろうか? これを試すためにテストをセットアップすればいいのでしょうね。

 
LEHayes wrote>>

というのが私のメモに書いてあったことです。心配なのは、1次元目がソートされることで、2次元目のデータもソートされるときに並べ替えが行われるのでは?これを試すためにテストをセットアップすることができそうです。


はい、同じベース・インデックスのすべての要素は、最初の次元のソートで移動します。 ちょうど、複数の列のデータを含むスプレッドシートをソートするように、MQLでは最初の列によってのみソートすることができます。
 

今のところ、打ち合わせ通りにセットアップしてもらいました。 話が終わる頃にはきっと解決していると思いますが、現在取得中。
2010.04.15 23:51:01,M1:ArraySort関数の 開始位置1が正しくありません。
最初はこのようにやってみました。
ArraySort(AryBuy,WHOLE_ARRAY,0,MODE_DESCEND);
というメッセージが表示され、位置の値が0であったため、何が起こるかわからないと思い、開始(位置の値)を1に変更したところ、上記のようになりました。

この時点で配列にデータが入っているはずです。 この問題が続くかどうか確認するために、テストをリセットしようと思っています。

 
LEHayes:

.....
double AryBuys[][2];
double ArySells[][2]です。

AryBuy[1][0]にはチケット、AryBuy[1][1]には価格が格納されています。....

間違っていたら訂正しますが、配列の定義とアドレスが間違っているようです。変数リファレンスから 引用 :

int    a[50];       // A one-dimensional array of 50 integers.
double m[7][50];    // Two-dimensional array of seven arrays,
                    //each of them consisting of 50 integers

最後の中括弧のペアは配列の最初の次元です...配列の未定義のサイズが最初の次元であると仮定しています。これがIMOの正しいものです。

double AryBuys[2][];
double ArySells[2][];

AryBuy[0][1] contains the ticket, AryBuy[1][1] contains the price. 
 
cameofx:
最後の中括弧のペアは,配列の最初の次元です...配列の未定義のサイズが最初の次元であると仮定しています.これはIMOが正しいです。

本も 参照...
参考までに、次の次元が(より左に位置するが)「後から」追加されるため、最後の中括弧のペアを「最初の次元」と名付ける方がしっくりくる。
IMHO 「柱の大きさ」に関しても、概念的には「くっつく」方が良い。

 
cameofx:

参考までに、次の次元は(より左に位置しているが)「後で」追加されるので、私は最後の中括弧のペアを「最初の次元」と名付ける方が快適である。

どのように呼ぶかはともかく、2 次元配列の最初の次元は arr_name[0,1,...,n][0] というベクトルであり、技術的には最初の括弧が最初の次元を保持することになります; これはまた ArraySort() によってソートされるベクトルでもあります。本から

ArraySort()の話題のついでに、私が見つけた文書化されていない2つの奇妙な点について触れておきます。

  1. 最初の次元の要素の一部が同一である場合、必ずしもその順序が維持されるわけではありません。明らかに、これは「設計上」文書化されるべきで、そうでなければ「バグ」と見なすでしょう。
  2. OrderSort() は 4次元配列では動作しません (エラー 4053 を返します)。これも文書化されているはずですが、されていません。
 
cameofx wrote>>

間違っていたら訂正しますが、配列の定義とアドレスが正しくないようです。変数リファレンスから 引用。

最後の中括弧のペアは、配列の最初の次元です...配列の未定義のサイズが最初の次元であると仮定しています。これがIMOの正しいものです。



私は、配列のインデックスと次元を、標準的なスプレッドシートの方法で見ています...行-列(ニーモニック「ローマン-カトリック」)。

1次元配列。MyArray[RowNumber-1] (行番号-1)

2次元配列。MyArray[行番号-1][列番号-1] とする。

3次元配列。MyArray[行番号-1][列番号-1][ワークシート-1]。

左端の括弧のセットは1次元であり、1次元の配列操作を含むすべての操作は、左端の括弧のセットのインデックスで実行されます。例えば、配列のサイズ変更(1次元に対してのみ可能)は、左端の括弧の値を変更するだけで、2次元、3次元、4次元(右端の括弧の2、3、4)のインデックス範囲を変更することはできないのです。

配列内のすべてのデータ行は、最初の括弧のセット(一番左のセット)でインデックスされ、これが配列の「1次元」です。

MyArray[0][ColumnNumber-1]→データの1行目

MyArray[1][ColumnNumber-1]→2行目のデータ

MyArray[2][ColumnNumber-1]→3行目のデータ

MQLでは、データの最初の列に含まれるデータ...つまり、MyArray[i][0]にある値でしかソートできません。同じ行(この場合は同じ「i」)にありながら異なる列(2つ目の括弧内の値)にある値は、ソートやランキングに使用することはできません。

以下は、2次元配列の例である。

3 5
1 9
7 6

つまり、MyArray[0][0] = 3, MyArray[0][1] = 5, MyArray[2][1] = 6, などとなります。

この配列をソートすることができます。

ArraySort(MyArray,WHOLE_ARRAY,0,MODE_ASCEND) とすると、結果は次のようになります。

1 9
3 5
7 6

最初の列はソートされ、2番目の列のデータ(つまり、同じ1次元目のインデックスを持つすべてのデータ)は、最初の列をランク付けする際に行われたソート/シフトに伴って移動します。

MQLで2列目のデータをソート/ランク付けできない...つまり、以下のように(とにかく直接には)取得できない。

3 5
7 6
1 9

(2番目の列は小さいものから順に並んでいます。)

2列目(または1列目以外の列)をソートした配列にするには、列間でデータを手動で入れ替え(1次元目のインデックスはそのままに、2次元目のインデックスの値を入れ替える)、ソートしてからデータを入れ替える必要があります。

MyNewArray
5 3
9 1
6 7

ここで、1列目でソートすると、ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND)となり、結果は次のようになります。

5 3
6 7
9 1

そして、その値を元の配列にコピーします。このとき、1次元の値はそのままで、2次元のインデックスを入れ替えます。

3 5
7 6
1 9

これで元の配列ができあがりましたが、データは 2 番目の列でソートされています。

 

これは悪夢と化し、これ以上続けようとしたかどうかさえ覚えていません。私が持っていたアイデアは、オープントレードのリストを取り、売りから買いを2つの配列に分離し、各配列は最初の列にチケット#を含み、2番目はトレードの価格値を含んでいました。一般的には、大きな価格の買い値と大きな価格の売り値をすべてマッチングさせ、最も高い買い値が最も高い売り値を上回った場合、その2つの取引を両方ともクローズして処理を繰り返すというアイデアでした。

このプロセスを経た後、ヘッジされた取引システムを維持するために、少なくとも1つのプラスの買い取引と1つのプラスの売り取引をテーブルに残しておきたいと思ったからです。これは基本的に、ヘッジ戦略のためのドローダウン管理ツールとして設計されています。そのため、ヘッジを維持しながらも、利益をテーブルから取り除きたいのです。配列アルゴリズムを使用することで、この解決策を提供できるかもしれないと思いつきました。

私は、5つのストラテジーのリリースをドアから押し出そうとしたために、本当に疲れて消耗しています。

私は、この関数を書いてくれる人と取引をしたいと思います。この関数を書いてくれる人には、数年間のライセンスで好きな製品を選んでもらい、さらに、このヘッジ戦略の個人的なコピーを無料で生涯無制限に使用できるようにします。私はそれをすべて行うにはあまりにも沼にはまり、私の開発チームはすでに私たちのプレートにあるものを解放するために重い負担を負っています。チーム全体の平均睡眠時間は、1日4~6時間だと思います。

そこで、もしあなたがちょっとした物々交換に興味を持っていただけるなら、それが私の申し出です。

目的
1.買い物と売り物を分ける
2. 値段が高いものから低いものへと並べ替える。
3.3. 買いの価格が 最も高く、売りの価格が最も低い場合、最も低い売りの取引を最も高い買いの取引で決済したい。もし、売りの方が高いプラス価格であれば、この動作を逆にし、最も高い売りの価格で最も低い買いの価格を決済します。このように、損失が出るたびに、より高い価格で決済することで、勝利が損失を上回り、平均してプラスの収益を得ることができるのです。


売り買い
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

これは、両者のオープントレードの数が釣り合っていることを示しています。15ドルの買いと12ドルの売りに注目してください。プラスの買いがマイナスの売りを上回っているので、これらは閉じることができます。また、5と-6をクローズすることもできます。なぜなら、最初の2つのクローズで十分な利益があり、そのうちの4つをクローズすると、バランスがプラスになるからです。1.5と-1についても同様にできますが、ヘッジされた状態を維持したいので、1と-.5を決済するのは避けたいところです。

というのも、ヘッジの状態を維持したいからである。これは、重い側を高いロットで相殺し、勝っている側に有利な取引を追加するという設計の基本でしたので、売りが1枚しかないこともあり得ますが、その場合は何もしないことになります。バランスしていないけれども、少なくとも両側に2つの取引がある場合は、それぞれの側の取引を空けておくようにする必要があります。1つのプラス取引が1つのマイナス取引を上回る場合、互いに最も小さい両側の1つの取引を除いて、それらをすべてクローズすることができます。

特定のチケット ID をクローズするクローズ関数を呼び出すように設計する必要があり、クローズについて心配する必要はありません。クローズしたトレードではなく、処理中に発生した新しいトレードを比較するために、リストを再構築しなければならないかもしれません。

そうそう、もう一つ...
この機能がどの程度の頻度で起動されるかを指定するユーザー外部設定を提供する必要があります。それはローソク足数、時間または分単位に基づくことができますが、毎ティック、あるいは新しいローソク足ごとに起動するべきではありません。 そのままでは、この機能が組み込まれた追加のツールがあり、このツールを起動するために、まず他のツールが起動する必要があります。 つまり、他のツールが起動し、あなたのツールが起動するまでのカウントダウンが開始されます。

 
Larryさん、CloseBy()のコードはこちら→https://book.mql4.com/trading/orderclose(ページの2/3くらいにあります...)で、あなたの望むように拡張できると思います(配列を使わずに)...ただ、あなたのために考えてみました。
理由: