我需要选择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选入数组?
答案 0 :(得分:1)
MQL4
概念首先要说的是,MQL4阵列仪器并不像第一眼看上去那样微不足道。
数组大小的编译时声明(int xxx
,取决于先验未知的OrdersTotal()
实际结果,在运行时纪内本身也是可变的),应该被解决通过数组的静态预分配,比如int magicsARRAY[10000];
,它允许编译器预先分配内存并在运行时决定正确的数组处理(可以实现一个人自己的堆栈机制不会溢出指向数组后面的单元格 [参考警告下面] )
或
对于编译器阶段,可以仅为int magicsARRAY[];
声明一个数组作为可变大小的数组,并允许运行时使用上下文感知的 {重新分配实际的大小调整按需提供{1}} 功能。
可以说,高性能/低延迟代码中的良好做法应避免&amp;防止每个&amp;在运行期间每次内存重新分配。
ArrayResize(...);
转换为数组如果内存(MagNUM
)重新分配在运行时很昂贵,那么所有ArrayResize()
体操(dbPOOL
+以下所有OP)都越多
请记住,您的 EA交易 代码已输入并执行当且仅当出现市场事件时(价格已经过去)只是感动了),而不是在任何其他情况下。因此,您的代码是被动的(响应价格变动),因此您无法在职责上花费更多的时间,这是可以避免的。
因此,专业代码将静态数组维护为OrderSelect()
- 哈希表,只是为了避免通过 MagNUM
进行盲目重复迭代。如果您经常运行 策略测试程序 ,您必须已经知道,在优化批处理过程中重新迭代dbPOOL
OP的成本是多少以及速度有多快如果你有零{ - 1}} OP,你的优化问题就会运行。
因此,最好的方法是在整个交易周期的整个生命周期中保持MagNUM-s从dbPOOL
实例化开始,并使用数组函数而不是dbPOOL
+ OrderSend()
环路。
如果尝试访问阵列范围之外的单元格,执行子系统将生成严重错误,程序将停止。实时交易引擎永远不会受到影响!
答案 1 :(得分:0)
试试这段代码。它将创建一个数组,遍历History选项卡中的所有订单,检查数组中是否存在订单的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 );
}