在 MQL4 MetaTrader4 [Expert Advisor] 中根据 Symbol() 定义一个数组

Defining an array, depending on Symbol(), in MQL4 MetaTrader4 [Expert Advisor]

我有一个交易突破的 EA。我 运行 这对多对。当具有高相关性的两对交易方向相同(或相反,如果负相关)时,问题就出现了。那会使我的风险加倍。因此,我在我的 EA 中添加了一个代码片段,如果已经有一个与当前交易品种高度相关的交易品种的未平仓头寸,它会阻止开启新交易。

(这是我试过的):

string       strSymbol;
string       HighCorrelationPairs[];

int OnInit() {
   strSymbol = Symbol();
   if (  strSymbol == "EURAUD" ) {
         ArrayResize( HighCorrelationPairs, 1 );
         string HighCorrelationPairs[1] = { "EURJPY" };
   }
   else if (  strSymbol == "EURJPY" ) {
              ArrayResize( HighCorrelationPairs, 2 );
              string HighCorrelationPairs[2] = { "EURAUD", "EURUSD" };
        }
        else if (  strSymbol == "EURUSD" ) {
                   ArrayResize( HighCorrelationPairs, 2 );
                   string HighCorrelationPairs[2] = { "EURJPY", "USDCHF" };
             }
             else if (  strSymbol == "GBPJPY" ) {
                        ArrayResize( HighCorrelationPairs, 1 );
                        string HighCorrelationPairs[1] = { "GBPUSD" };
                  }
                  else if (  strSymbol == "GBPUSD" ) {
                             ArrayResize( HighCorrelationPairs, 1 );
                             string HighCorrelationPairs[1] = { "GBPJPY" };
                       }
                       else if (  strSymbol == "USDCHF" ) {
                                  ArrayResize( HighCorrelationPairs, 1 );
                                  string HighCorrelationPairs[1] = { "EURUSD" };
                            }
                            else if (  strSymbol == "USDJPY" ) {
                                       ArrayResize( HighCorrelationPairs, 1 );
                                       string HighCorrelationPairs[1] = {};
                                 }
                                 else {
                                        ArrayResize( HighCorrelationPairs, 1 );
                                        string HighCorrelationPairs[1] = {};
                                 }
}

void OnTick() {          //--- Check Correlation and Number of Trades
   for ( k = OrdersTotal() - 1; k >= 0; k-- ) {
         if (  OrderSelect( k, SELECT_BY_POS, MODE_TRADES ) ) {
               if (  OrderType() == OP_BUY
                  || OrderType() == OP_SELL
                     ) {
                     if (  OrderSymbol()      == Symbol()
                        && OrderMagicNumber() == MagicNumber
                           ) {
                           return;
                     }
                     if (  TimeCurrent() - OrderOpenTime() <= 18000 ) {
                           for ( int i = 0;i <  ArraySize( HighCorrelationPairs ); i++ ) {
                                 if (  OrderSymbol() == HighCorrelationPairs[i] ) { return; }
                           }
                     }
               }
         }
   }
}

编译后得到的warning/s

变量 'HighCorrelationPairs' 未使用
'HighCorrelationPairs' 的声明隐藏了第 120 行的全局声明

这只是警告,不是错误。

这个警告真的很重要,就像大多数警告一样。 它表示如下:您在 OnInit() 内声明了 HighCorrelationPairs[],现在您使用这个新声明的数组执行所有操作,并且该数组仅在 OnInit() 函数内可见。当您尝试从 OnTick() 函数调用该数组时,它会调用一个已声明但从未在第 120 行(在 OnInit() 之外,在全局变量中)启动的数组。

怎么办?尝试填充您的数组但不要创建新数组!

string HighCorrelationPairs[];
int OnInit(){
   string strSymbol = Symbol();
   if(strSymbol == "EURAUD") {
      ArrayResize(HighCorrelationPairs,1);
      HighCorrelationPairs[0] = "EURJPY";
   }else if(strSymbol == "EURJPY") {
      ArrayResize(HighCorrelationPairs,2); 
      HighCorrelationPairs[0] = "EURAUD";
      HighCorrelationPairs[1] = "EURUSD";
   }
   //also you may print all elements of the array here if you wish
   return (INIT_SUCCEEDED);
}

首要问题是调用一个变量"scope-of-declaration"

给定一个代码指示编译器这样做:

if (  strSymbol == "EURAUD" ) {
         ArrayResize( HighCorrelationPairs, 1 );
         string HighCorrelationPairs[1] = { "EURJPY" };
   }

if 主体 的词法范围内的最后一行 -- if(){...} 正文部分,即 {...} -- 是唯一的临时区域,新 "locally" 创建的静态预大小对象将在其中分配一个值 string HighCorrelationPairs[1] = ... ; 是 立即丢失
一旦 "scope-of-declaration" 将被越过(即在创建/赋值之后立即)

接下来是变量名掩码:

接下来在创建一个新的 "local" string HighCorrelationPairs[] 之后,编译器必须至少通知您,任何冲突的对象名称,定义在任何其他级别(已访问的更高级别) hierarchy ) 同时变得不可用,从而使最近声明的对象名称有效地屏蔽所有先前定义的对象,并带有词法 "same" 名称。所以,你已经被警告了。

优化您的代码,以避免变量名被屏蔽并遵守变量词法"scope-of-declaration".

switch( _Symbol ){
     case "EURAUD" : {  ArrayResize( HighCorrelationPairs, 1 );
                                     HighCorrelationPairs[0] = "EURJPY";
                        break;
                        }
     case "EURUSD" : {  ArrayResize( HighCorrelationPairs, 2 );
                                     HighCorrelationPairs[0] = "EURJPY";
                                     HighCorrelationPairs[1] = "USDCHF";
                        break;
                        }
     ...
}

嗯,对,MQL4 文档在这方面并不清楚。规范规定 switch( selector ) 必须将 selector 部分作为表达式(已满足)。

Switch Operator
Compares the expression value with constants in all the case variants and passes control to the operator that corresponds to the expression value. Each variant of case can be marked with an integer constant, a literal constant or a constant expression.

然而,编译器拒绝除 int 类型之外的任何其他类型在此语法构造函数中提供服务。

所以,最好使用一些简单的 HASH 函数来获得 int:

int   Symbol2HASH( const string aSymbol = "EURUSD" ) {
// -----------------------------------
// NAIVE, BUT WORKING:
// ------------------UUID--------------
#define DEF_EURUSD      0
#define DEF_EURJPY      1
#define DEF_EURAUD      2
#define DEF_EURCHF      3
//          ...       ...
// ------------------UUID--------------
// MAINTAIN HERE ALL UUID #s PLUS aSymbol MAPPINGS:
// --------vvvvvvv----------------------vvvvvvvvvv
      if ( aSymbol == "EURUSD" ) return DEF_EURUSD;
      if ( aSymbol == "EURJPY" ) return DEF_EURJPY;
      if ( aSymbol == "EURAUD" ) return DEF_EURAUD;
      if ( aSymbol == "EURCHF" ) return DEF_EURCHF;

      return EMPTY;
  }

switch( Symbol2HASH( _Symbol ) ) {
       case DEF_EURAUD: {  ArrayResize( HighCorrelationPairs, 1 );
                                        HighCorrelationPairs[0] = "EURJPY";
                           break;
                           }
       case DEF_EURUSD: {  ArrayResize( HighCorrelationPairs, 2 );
                                        HighCorrelationPairs[0] = "EURJPY";
                                        HighCorrelationPairs[1] = "USDCHF";
                           break;
                           }
       case EMPTY: {       PrintFormat( "Symbol()==[%s] not included inside Symbol2HASH() function. Edit source.", _Symbol );
                           ExpertRemove();
                           }
       default:    {       PrintFormat( "Symbol()==[%s] code [%d] was not served inside switch(){ case-s }. Edit source.", _Symbol, Symbol2HASH( _Symbol ) );
                           ExpertRemove();
                           }
  }