按第二维度对二维数组进行排序

 

我有两个数据需要放入一个数组,然后对其进行排序。

首先我把订单分成两个数组,第一个数组是买入,另一个是卖出。当我这样做时,我正在收集OrderTicket,这样我就可以在以后执行订单。我收集的第二件事是订单的OrderClosePrice值,这样我就可以将它与另一个完全相同的列表进行比较。

所以我设置的第一个数组。

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

AryBuy[1][0]包含门票,AryBuy[1][1]包含价格。

我如何对第二维进行排序,使我们的数组 按价格降序排序

注意:使用ArraySort,你只能对第一维进行排序。 这里有一个可能的想法,我可以创建一个临时数组,让价格成为临时数组的第一个维度,对它进行排序,然后把它送回数组,当我以后需要按票价排序时,再做同样的反向操作。 这是否可行?

 

不幸的是,你不能这样做,但你可以创建第二个数组,将两个维度的数据互换,并按价格(第一维度)对这个新数组进行排序。然后,你可以(如果你还想)把数据复制回原来的数组,再一次交换每个维度的数据。现在你的原始数组包含了原始数据,但它是按照第二维度的值进行排序的。

这很笨拙,但这是唯一实用的方法(我已经想出来了),可以让你的数据按维度>1进行排序。

 

这就是我在笔记中想到的。 我担心的是,第一个维度会被排序,当排序发生时,它是否也会重新排列第二个维度的数据? 我想我可以设置一个测试来试试。

 
LEHayes wrote>>

这就是我在笔记中想到的。我担心的是,第一个维度会被排序,当排序发生时,它是否也会重新排列第二个维度的数据?我想我可以设置一个测试来试试这个。


是的,所有相同基础索引的元素都会随着第一维的排序而移动。 就像对包含多列数据的电子表格进行排序一样,只是在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:

顺便说一下,我更愿意把最后一对大括号命名为 "第一维",因为下一个维度是 "后来 "添加的(尽管位于更左边)。

不管你怎么称呼它,二维数组的第一维是向量arr_name[0,1,...,n][0],所以从技术上讲,第一个大括号表示第一维;这也是将被ArraySort()排序的向量。来自书中。

既然我们在讨论ArraySort()的问题,我就提一下我长期以来发现的两个未记录的特殊性(如果有人确认或纠正我,我将非常高兴......)。

  1. 如果第一个维度中的一些元素是相同的,它们不一定会保留它们的顺序。很明显,如果是 "设计 "的话,这应该被记录下来,否则我认为这是一个 "错误"。
  2. OrderSort()对4D数组不起作用(返回错误4053)。同样,这应该被记录下来,但它没有。
 
cameofx wrote>>

如果我错了,请纠正我,但你对数组的定义和地址似乎不正确。引述自变量参考:

最后一对大括号是数组的第一维......假设数组的未定义大小是第一维。这就是IMO的正确做法。



我以标准的电子表格方式看待数组的索引和尺寸......行-列(记忆法为 "罗马-天主教")。

1D数组。MyArray[RowNumber-1]

二维数组。MyArray[RowNumber-1][ColumnNumber-1]。

三维数组。MyArray[RowNumber-1][ColumnNumber-1][Worksheet-1] 。

最左边的一组括号是第一个维度,你所做的所有涉及到第一维度的数组操作都会用最左边的一组括号的索引来完成。例如,数组大小的调整(只能对第一维度进行调整)只能改变最左边一组括号的值,它不能改变第二、第三或第四维度的索引范围(第二、第三或第四组最右边的括号)。

我在数组中的所有数据行都是由第一组大括号索引的,也就是最左边的一组,这就是数组的 "第一维"。

MyArray[0][ColumnNumber-1] -> 第一行数据

MyArray[1][ColumnNumber-1] -> 第二行数据

MyArray[2][ColumnNumber-1] -> 第三行数据

在MQL中,我只能按第一列数据中包含的数据进行排序...即在MyArray[i][0]中找到的值。在同一行(本例中相同的 "i")但不同列(第二组括号中的值)发现的值不能用于排序/排名。

下面是一个二维数组的例子。

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

第一列被排序后,第二列数据(即所有具有相同第一维索引的数据)随着第一列排序时做的排序/移动而移动。

我不能在MQL中对第二列数据进行排序/移位......也就是说,我不能得到以下结果(无论如何不能直接得到)。

3 5
7 6
1 9

(注意第二列现在是从小到大排序的)

为了得到一个对第二列(或第一列以外的任何一列)进行排序的数组,我必须在各列之间手动交换数据(保持第一维的索引不变,但交换第二维的索引值),然后进行排序,再将数据交换回来。

我的新数组
5 3
9 1
6 7

现在按第一列排序,ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND),结果会是这样的。

5 3
6 7
9 1

然后将这些值复制到我的原始数组中,再一次将第二维的索引移位,同时保持第一维的值不变。

3 5
7 6
1 9

现在我有了我的原始数组,但数据是按第二列排序的。

 

这整个事情变成了一场噩梦,我甚至不记得我是否试图进一步追求它。我的想法是把未平仓的交易列表,把买入和卖出分成两个数组,每个数组的第一列包含票号,第二列包含交易的价格值。一般来说,我们的想法是将所有大价格的买入值与所有大价格的卖出值相匹配,如果最高的买入值超过最高的卖出值,那么就关闭这两笔交易并重复这一过程。

现在,让我考虑放弃这个想法的最后一个诱因是,在我经历了这个过程之后,我想至少留下1笔正面的买入交易和1笔正面的卖出交易,以保持一个对冲交易系统的运行。这基本上是被设计为对冲策略的缩减管理工具。所以我想保持对冲,但把收益从桌面上拿走。我突然想到,使用数组算法可能会提供一个解决方案。

由于我试图将5个策略的发布推到门外,我真的很累,也很疲惫,所以这成了一个小小的好事,而不是一个必要的事。

我愿意和任何能够为我写这个功能的人做个交易。我将给你提供你所选择的产品和多年的许可证,因为你帮助我解决了这个问题,而且我还将给你一份这个对冲策略的个人副本,供你终身免费使用。我只是太忙了,无法做到这一切,我的开发团队在发布已经在我们的盘子里的东西方面负担很重。我想整个团队的平均睡眠值大约是每天4到6小时。

因此,如果你有兴趣进行一次小小的交换和交易,这就是我的提议。

目标。
1.把买的和卖的分开
2.按照从高到低的价格价值进行分类
3.如果买入有最高的正价,卖出有最低的正价,那么我们要用最高的买入交易关闭最低的卖出交易,买入交易必须超过卖出交易的费用。如果卖出有较高的正价,那么我们就反其道而行之,用最高的卖出价格来关闭最低的买入价格。我们的想法是,每一次亏损,我们都以更高的价格赢利来结束它,这样就能以平均的正收益来赢取超过亏损。

例子。
买入 卖出
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

这表明双方的未平仓交易数量是平衡的。注意15美元的买入和12美元的卖出,这些可以关闭,因为正的买入超过了负的卖出。我们也可以关闭5和-6的交易,因为前两笔交易有足够的收益,关闭其中4笔交易的平衡将导致正数。我们可以对1.5和-1做同样的处理,但我们不想关闭1和-.5,因为我们想保持对冲的局面。

大多数情况下,交易不会被平衡为双方都是平等的。这是设计的基础,用更高的手数和额外的交易来抵消最重的一方,有利于获胜的一方,所以有可能你只有1个卖出,在这种情况下,你不会做任何事情。如果它们不平衡,但每边至少有2笔交易,你需要确保你在每边都留有一笔交易。如果1笔正面交易超过了1笔负面交易,你可以将它们全部关闭,除了每边最小的那一笔交易。

它应该被设计成调用一个关闭函数,关闭一个特定的ticketid,所以你不必担心关闭的问题,只需通过ticketid进行调用,让交易关闭。你可能需要重建你的列表,这样你的列表就不会比较已关闭的交易,而是比较在你处理过程中可能发生的任何新交易。

哦,对了,还有一件事...
它不应该太贪婪,你应该提供一个用户外部程序来决定这个功能的启动频率,它可以基于蜡烛计数或以小时或分钟为基础,但不应该每一个刻度或甚至每一个新的蜡烛都启动。 因为它有一个额外的工具,它将被嵌入到其他工具中,首先需要其他工具启动,以便调用这个工具。 因此,其他工具将启动,而你的工具将开始倒计时,以便启动。

 
拉里,我确信这里的CloseBy()的代码->https://book.mql4.com/trading/orderclose(大约在页面的2/3处......)可以扩展到做你想要的事情(不使用任何数组)......只是想让你知道。