MQL4 如何使数组不同?
MQL4 How to make an array distinct?
我需要将 MagicNumbers 挑选到一个数组中,然后使数组不同(有多个订单组,每个订单组都有唯一的 MagicNumbers )。但是有问题。我的代码是:
int xxx = OrdersTotal();
int magics[xxx]; // here is an error:
// invalid index value
for ( int i = OrdersTotal() - 1; i >= 0; i-- ){
if ( OrderSelect( i, SELECT_BY_POS ) ){
magics[i] = OrderMagicNumber(); // choosing magics
ArrayResize( magics,
ArraySize( magics ) + 1,
0
);
}
}
ArraySort( magics ); // making distinct
int sorted[];
int x = 0;
for ( int i = 0; i < OrdersTotal() - 1; i++ ){ // duplicates = 0
if ( magics[i] != magics[i+1] ){
sorted[x] = magics[i];
Print( "Sorted array: " + DoubleToStr( sorted[x] ) );
x = x + 1;
}
}
如何选择不同的 MagicNumbers 到数组中?
MQL4
array-alike 对象和特殊数组函数的概念
首先要说的是,MQL4 数组检测并不像乍看起来那么微不足道。
是什么导致了以上报错?
Compile-time 数组大小的声明(int xxx
,取决于 a-priori 未知的 OrdersTotal()
实际结果,在 run-time epoch too ), 应通过
数组的静态pre-allocation来解决,比如说int magicsARRAY[10000];
,它允许编译器预分配内存并决定在 run-time 中的正确 array-handling (可以实现自己的 stack-mechanics 不溢出指向数组 tail-cell [参考下面的警告] )
或
可以将数组声明为variable-sized数组通过 int magicsARRAY[];
用于编译器阶段,并允许 run-time re-allocate 具有 context-aware ArrayResize(...);
功能的实际大小 on-demand.
公平地说,high-performance / low-latency 代码 中的 良好实践 应避免和防止每一个run-time.
期间的内存 re-allocation
接下来,在管家服务上,将 MagNUM
s 变成一个数组
如果内存(ArrayResize()
)re-allocation在运行时间里很贵,更多的都是dbPOOL
体操 ( OrderSelect()
+ 以下所有 OP).
请记住,您的 Expert Advisor 代码已输入并执行 当且仅当 有一个market-event(价格刚刚变动),在任何其他情况下都没有。所以你的代码是被动的,(响应价格变动)所以你不能在职责上多花一微秒,这是可以避免的。
因此专业代码将静态数组维护为MagNUM
-hash-tables,只是为了避免blind-re-iterations通过dbPOOL
。如果你 运行 Strategy Tester 很多,你一定已经知道, re-iterate dbPOOL
优化过程中的 OPs batch-processing 以及优化问题 运行s 的速度,如果你有零-dbPOOL
OPs。
所以最好的方法是在 OrderSend()
实例化中保持 MagNUM-s,在交易头寸的整个 life-cycle 中,并使用数组函数而不是 OrderSelect()
+ OrderMagicNumber()
循环。
数组在 MQL4 中可能非常有害且危险
如果试图访问数组范围之外的单元格,执行子系统将产生严重错误并且程序将停止。这是 Live-Trading 引擎永远不会遭受的!
试试这个代码。它将创建一个数组,循环遍历“历史”选项卡中的所有订单,检查订单的 MagicNumber 是否存在于数组中。如果不存在,则将其添加到数组中。您将以一组独特的 MagicNumbers 结束。
//+------------------------------------------------------------------+
//| UniqueMagic.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, joseph dot lee at fs dot com dot my"
#property link "https://www.facebook.com/joseph.fhlee"
#property strict
void OnTick() {
int vaiMagicNumbers[]; //Array containing list of MagicNumbers
//Loop through all the Orders (in History tab)
for(int viIndex=OrdersTotal()-1; viIndex>=0; viIndex--) {
if(OrderSelect(viIndex, SELECT_BY_POS, MODE_HISTORY) ){
//Check if the selected Order (in History tab) already exists in the array
if( fniGetElementIndex( vaiMagicNumbers, OrderMagicNumber() ) == -1 ) {
//If not exists, then increase the array by 1, and add the MagicNumber into the array
ArrayResize(vaiMagicNumbers, ArrayRange(vaiMagicNumbers,0)+1);
vaiMagicNumbers[ArrayRange(vaiMagicNumbers,0)-1] = OrderMagicNumber();
}
}
};
Comment( ArrayRange(vaiMagicNumbers,0) ); //Show the number of unique MagicNumbers in the History tab.
}
//Function to return the index (position) of viValue within a given array
int fniGetElementIndex( int &vaiArray[], int viValue ) {
int viElementCount = ArrayRange(vaiArray, 0); //Get the total number of elements within that array.
int viFoundAt = -1; //The element index where viValue is found within the array.
//Loop through every element in vaiArray
for(int viElement=0; viElement<viElementCount; viElement++) {
if( vaiArray[viElement] == viValue ) {
//If the element value is the same as viValue, then FOUND, break the for loop.
viFoundAt = viElement;
break;
}
}
return( viFoundAt );
}
我需要将 MagicNumbers 挑选到一个数组中,然后使数组不同(有多个订单组,每个订单组都有唯一的 MagicNumbers )。但是有问题。我的代码是:
int xxx = OrdersTotal();
int magics[xxx]; // here is an error:
// invalid index value
for ( int i = OrdersTotal() - 1; i >= 0; i-- ){
if ( OrderSelect( i, SELECT_BY_POS ) ){
magics[i] = OrderMagicNumber(); // choosing magics
ArrayResize( magics,
ArraySize( magics ) + 1,
0
);
}
}
ArraySort( magics ); // making distinct
int sorted[];
int x = 0;
for ( int i = 0; i < OrdersTotal() - 1; i++ ){ // duplicates = 0
if ( magics[i] != magics[i+1] ){
sorted[x] = magics[i];
Print( "Sorted array: " + DoubleToStr( sorted[x] ) );
x = x + 1;
}
}
如何选择不同的 MagicNumbers 到数组中?
MQL4
array-alike 对象和特殊数组函数的概念
首先要说的是,MQL4 数组检测并不像乍看起来那么微不足道。
是什么导致了以上报错?
Compile-time 数组大小的声明(int xxx
,取决于 a-priori 未知的 OrdersTotal()
实际结果,在 run-time epoch too ), 应通过
数组的静态pre-allocation来解决,比如说int magicsARRAY[10000];
,它允许编译器预分配内存并决定在 run-time 中的正确 array-handling (可以实现自己的 stack-mechanics 不溢出指向数组 tail-cell [参考下面的警告] )
或
可以将数组声明为variable-sized数组通过 int magicsARRAY[];
用于编译器阶段,并允许 run-time re-allocate 具有 context-aware ArrayResize(...);
功能的实际大小 on-demand.
公平地说,high-performance / low-latency 代码 中的 良好实践 应避免和防止每一个run-time.
期间的内存 re-allocation接下来,在管家服务上,将 MagNUM
s 变成一个数组
如果内存(ArrayResize()
)re-allocation在运行时间里很贵,更多的都是dbPOOL
体操 ( OrderSelect()
+ 以下所有 OP).
请记住,您的 Expert Advisor 代码已输入并执行 当且仅当 有一个market-event(价格刚刚变动),在任何其他情况下都没有。所以你的代码是被动的,(响应价格变动)所以你不能在职责上多花一微秒,这是可以避免的。
因此专业代码将静态数组维护为MagNUM
-hash-tables,只是为了避免blind-re-iterations通过dbPOOL
。如果你 运行 Strategy Tester 很多,你一定已经知道, re-iterate dbPOOL
优化过程中的 OPs batch-processing 以及优化问题 运行s 的速度,如果你有零-dbPOOL
OPs。
所以最好的方法是在 OrderSend()
实例化中保持 MagNUM-s,在交易头寸的整个 life-cycle 中,并使用数组函数而不是 OrderSelect()
+ OrderMagicNumber()
循环。
数组在 MQL4 中可能非常有害且危险
如果试图访问数组范围之外的单元格,执行子系统将产生严重错误并且程序将停止。这是 Live-Trading 引擎永远不会遭受的!
试试这个代码。它将创建一个数组,循环遍历“历史”选项卡中的所有订单,检查订单的 MagicNumber 是否存在于数组中。如果不存在,则将其添加到数组中。您将以一组独特的 MagicNumbers 结束。
//+------------------------------------------------------------------+
//| UniqueMagic.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, joseph dot lee at fs dot com dot my"
#property link "https://www.facebook.com/joseph.fhlee"
#property strict
void OnTick() {
int vaiMagicNumbers[]; //Array containing list of MagicNumbers
//Loop through all the Orders (in History tab)
for(int viIndex=OrdersTotal()-1; viIndex>=0; viIndex--) {
if(OrderSelect(viIndex, SELECT_BY_POS, MODE_HISTORY) ){
//Check if the selected Order (in History tab) already exists in the array
if( fniGetElementIndex( vaiMagicNumbers, OrderMagicNumber() ) == -1 ) {
//If not exists, then increase the array by 1, and add the MagicNumber into the array
ArrayResize(vaiMagicNumbers, ArrayRange(vaiMagicNumbers,0)+1);
vaiMagicNumbers[ArrayRange(vaiMagicNumbers,0)-1] = OrderMagicNumber();
}
}
};
Comment( ArrayRange(vaiMagicNumbers,0) ); //Show the number of unique MagicNumbers in the History tab.
}
//Function to return the index (position) of viValue within a given array
int fniGetElementIndex( int &vaiArray[], int viValue ) {
int viElementCount = ArrayRange(vaiArray, 0); //Get the total number of elements within that array.
int viFoundAt = -1; //The element index where viValue is found within the array.
//Loop through every element in vaiArray
for(int viElement=0; viElement<viElementCount; viElement++) {
if( vaiArray[viElement] == viValue ) {
//If the element value is the same as viValue, then FOUND, break the for loop.
viFoundAt = viElement;
break;
}
}
return( viFoundAt );
}