Search code examples
mql4metatrader4mt4

Where do I place external variables in MQL4 language?


I am quite new at programming and can't figure out why the code is not compiling and how to make it compile.

It's a simple EA in MetaTrader Terminal 4.

I think the problem is the position, where I declared and initialised variables, I tried placing them under different functions ( indicated with comments in the code ), but still the code wouldn't compile, the code is attached. Any help will be highly appreciated.

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern double ema_red    = iMA( NULL, 0,  6, 0, MODE_EMA, PRICE_CLOSE, 0 );
extern double ema_purple = iMA( NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0 );
extern double ema_blue   = iMA( NULL, 0,  8, 1, MODE_EMA, PRICE_CLOSE, 0 );

// int point;
/*
void start()
{
  double ema_red    = iMA( NULL, 0,  6, 0, MODE_EMA, PRICE_CLOSE, 0 );
  double ema_purple = iMA( NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0 );
  double ema_blue   = iMA( NULL, 0,  8, 1, MODE_EMA, PRICE_CLOSE, 0 );
  return;
 }
*/
void OnTick()
{
 // double ema_red    = iMA( NULL, 0,  6, 0, MODE_EMA, PRICE_CLOSE, 0 );
 // double ema_purple = iMA( NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0 );
 // double ema_blue   = iMA( NULL, 0,  8, 1, MODE_EMA, PRICE_CLOSE, 0 );
 if (OrdersTotal()<=21)
   {   
      if (ema_red == ema_purple)&&(ema_red > ema_blue) // check when the ea's cross/meet
        Buy_Order();
      if (ema_red == ema_purple)&&(ema_red < ema_blue) // check when the ea's cross/meet
        Sell_Order();                                
   }
  }
void Buy_Order()
{ 
         double TP = Ask +(PipsToPointFactor()*15);
         double SL = (MarketInfo(Symbol(),MODE_TICKVALUE)) - (PipsToPointFactor()*5);
         OrderSend(Symbol(),OP_BUY,0.6,Ask,(3*PipsToPointFactor()),SL,TP,"",0,0,Green);  
  }
void Sell_Order()
{  
         double TP = (Bid - (15*PipsToPointFactor()));
         double SL = ((MarketInfo(Symbol(),MODE_TICKVALUE)) + (PipsToPointFactor()*5 );
         OrderSend(Symbol(),OP_SELL,0.6,Bid,(3*PipsToPointFactor()),SL,TP,"",0,0,Red); 
  }
int OnInit()
{
    return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
{  
  }
int PipsToPointFactor()              // NOT MY OWN FUNCTION, takes care of pips to points issue
{
   int point;
   if(Digits==5 || Digits==3)        // Check whether it's a 5 digit broker ( 3 digits for Yen )
   point=10;                         // 1 pip to 10 point if 5 digit
   else if(Digits==4 || Digits==2)
   point=1;                          // 1 pip to 1 point if 4 digit
   return(point);
  }

Solution

  • You declare some variables as "extern":

    extern double ema_red    = iMA(NULL, 0,  6, 0, MODE_EMA, PRICE_CLOSE, 0);
    extern double ema_purple = iMA(NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0);
    extern double ema_blue   = iMA(NULL, 0,  8, 1, MODE_EMA, PRICE_CLOSE, 0);
    

    You are using them inside functions, inside more than one function, if you count the function start(). So, they need to be defined at least on a file scope. It seems that you define them nowhere.

    Define them, in addition to declaring them or just define them:

    /* extern */ double ema_red =    iMA(NULL, 0,  6, 0, MODE_EMA, PRICE_CLOSE, 0);
    /* extern */ double ema_purple = iMA(NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0);
    /* extern */ double ema_blue =   iMA(NULL, 0,  8, 1, MODE_EMA, PRICE_CLOSE, 0);
    

    All code files ( those which contain functions which access these variables ) need to "see" the declaration, i.e. the lines with "extern". If you have more than one such code file, that declaration should be in a header.
    Exactly one code file then has to do the definition, i.e. the lines without "extern". That is called "global variables".

    If you only have one such code file but several others and want to make sure that the variables are not accessible from anywhere else ( a feature for clean coding and for "safety" ), then you do not use a header and restrict the visibility to the one code file doing the definition. You do that by using the keyword "static", exactly where you now have "extern". That is sometimes called "file scope variables".

    As another answer said, initialising at definition can only use static values. If you want to reinitialise at runtime, maybe with usecase specific values, your function "start()" happens to be the way to do it. You just have to change the definition lines to normal write accesses. The function then needs to be called for changing use cases.

    Note:
    This answer is referring only to C and is older than the edits to the question, which made the MT4-scope more prominent and deleted the C tag.
    So be careful if your needs are heavily MT4 related.
    Since somebody, including OP, considered the answer useful, I wont delete until a good MT4 answer is available.