Need help on errors, thanks!

 
//--- input parameters
input int      StopLoss=30;
input int      TakeProfit=100;
input int      ADX_Period=8;
input int      MA_Period=8;
input int      EA_Magic=12345;    // Ea majic number
input double   Adx_Min=22.0;     // Minimum ADX Value
input double   Lot=0.1;
// other parameters
int adxHandle; // handle for our ADX indicator
int maHandle;  // handle for our Moving Average indicator
double plsDI[],minDI[],adxVal[]; // Dynamic arrays to hold the values of +DI, -DI and ADX values for each bars
double maVal[]; // Dynamic array to hold the values of Moving Average for each bars
double p_close; // Variable to store the close value of a bar
int STP;   // To be used for Stop Loss & Take Profit values
int TKP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- get handle for ADX
   adxHandle=iADX (NULL, 0 , ADX_Period);
//---get handle for Moving average 
   maHandle=iMA(_Symbol,_Period,MA_Period,0,MODE_EMA,PRICE_CLOSE);
//--- What if handle returns Invalid Handle
   if(adxHandle<0 || maHandle<0)
     {
      Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
     }
  
//--- currency pairs with 5 or 3 digit prices
   STP = StopLoss;
   TKP = TakeProfit;
   if(_Digits==5 || _Digits==3)
   {
   STP = STP*10
   TKP = TKP*10 //this is line 46

   } // line 47
    return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) // line 53
  {
//---
   IndicatorRelease (adxHandle) ; 
   IndicatorRelease (maHandle) ; 
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() // line 62
 
  // this is line 64{
// Do we have enough bars to work with
   if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }
// We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the saved one.
// If the bar time isn't equal to the saved time, it indicates that we have a new tick.
   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar==false)
     {
      return;
     }
 
//--- Do we have enough bars to work with
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // if total bars is less than 60 bars
     {
      Alert("We have less than 60 bars, EA will now exit!!");
      return;
     }

//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;     // To be used for getting recent/latest price quotes
   MqlTradeRequest mrequest;  // To be used for sending our trade requests
   MqlTradeResult mresult;    // To be used to get our trade results
   MqlRates mrate[];         // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);     // Initialization of mrequest structure
   
   struct MqlTick
  {
   datetime     time;          // Time of the last prices update
   double       bid;           // Current Bid price
   double       ask;           // Current Ask price
   double       last;          // Price of the last deal (Last)
   ulong        volume;        // Volume for the current Last price
  };
   
   
   struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;       // Trade operation type
   ulong                         magic;        // Expert Advisor ID (magic number)
   ulong                         order;        // Order ticket
   string                        symbol;       // Trade symbol
   double                        volume;       // Requested volume for a deal in lots
   double                        price;        // Price
   double                        stoplimit;    // StopLimit level of the order
   double                        sl;           // Stop Loss level of the order
   double                        tp;           // Take Profit level of the order
   ulong                         deviation;    // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;          // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;  // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;     // Order execution time
   datetime                      expiration;    // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;       // Order comment
  };
   
   struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by the operation description)
  };
  
  struct MqlRates
  {
   datetime time;         // Period start time
   double   open;         // Open price
   double   high;         // The highest price of the period
   double   low;          // The lowest price of the period
   double   close;        // Close price
   long     tick_volume;  // Tick volume
   int      spread;       // Spread
   long     real_volume;  // Trade volume
  };
  
  /*
     Let's make sure our arrays values for the Rates, ADX Values and MA values 
     is store serially similar to the timeseries array
*/
// the rates arrays
   ArraySetAsSeries(mrate,true);
// the ADX DI+values array
   ArraySetAsSeries(plsDI,true);
// the ADX DI-values array
   ArraySetAsSeries(minDI,true);
// the ADX values arrays
   ArraySetAsSeries(adxVal,true);
// the MA-8 values arrays
   ArraySetAsSeries(maVal,true);
  
  //--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }
  
  //--- Get the details of the latest 3 bars
   if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      return;
     }
  
  int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   int       start_pos,            // start position
   int       count,                // amount to copy
   double    buffer[]              // target array to copy
   );
  
  //--- Copy the new values of our indicators to buffers (arrays) using the handle
   if(CopyBuffer(adxHandle,0,0,3,adxVal)<0 || CopyBuffer(adxHandle,1,0,3,plsDI)<0
      || CopyBuffer(adxHandle,2,0,3,minDI)<0)
     {
      Alert("Error copying ADX indicator Buffers - error:",GetLastError(),"!!");
      return;
     }
   if(CopyBuffer(maHandle,0,0,3,maVal)<0)
     {
      Alert("Error copying Moving Average indicator buffer - error:",GetLastError());
      return;
     }
  
  
  //--- we have no errors, so continue
//--- Do we have positions opened already?
    bool Buy_opened=false;  // variable to hold the result of Buy opened position
    bool Sell_opened=false; // variable to hold the result of Sell opened position
    
    if (PositionSelect(_Symbol) ==true)  // we have an opened position
    {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            Buy_opened = true;  //It is a Buy
         }
         else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            Sell_opened = true; // It is a Sell
         }
    }
    
    /*
    1. Check for a long/Buy Setup : MA-8 increasing upwards, 
    previous price close above it, ADX > 22, +DI > -DI
*/
//--- Declare bool type variables to hold our Buy Conditions
   bool Buy_Condition_1 = (maVal[0]>maVal[1]) && (maVal[1]>maVal[2]); // MA-8 Increasing upwards
   bool Buy_Condition_2 = (p_close > maVal[1]);         // previuos price closed above MA-8
   bool Buy_Condition_3 = (adxVal[0]>Adx_Min);          // Current ADX value greater than minimum value (22)
   bool Buy_Condition_4 = (plsDI[0]>minDI[0]);          // +DI greater than -DI

//--- Putting all together   
   if(Buy_Condition_1 && Buy_Condition_2)
     {
      if(Buy_Condition_3 && Buy_Condition_4)
        {
         // any opened Buy position?
         if (Buy_opened) 
         {
            Alert("We already have a Buy Position!!!"); 
            return;    // Don't open a new Buy Position
         }
         mrequest.action = TRADE_ACTION_DEAL;                                // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);          // latest ask price
         mrequest.sl = NormalizeDouble(latest_price.ask - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                         // currency pair
         mrequest.volume = Lot;                                            // number of lots to trade
         mrequest.magic = EA_Magic;                                        // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                     // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                          // Order execution type
         mrequest.deviation=100;                                            // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
  
   // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
  
  /*
    2. Check for a Short/Sell Setup : MA-8 decreasing downwards, 
    previous price close below it, ADX > 22, -DI > +DI
*/
//--- Declare bool type variables to hold our Sell Conditions
   bool Sell_Condition_1 = (maVal[0]<maVal[1]) && (maVal[1]<maVal[2]);  // MA-8 decreasing downwards
   bool Sell_Condition_2 = (p_close <maVal[1]);                         // Previous price closed below MA-8
   bool Sell_Condition_3 = (adxVal[0]>Adx_Min);                         // Current ADX value greater than minimum (22)
   bool Sell_Condition_4 = (plsDI[0]<minDI[0]);                         // -DI greater than +DI
   
 //--- Putting all together
   if(Sell_Condition_1 && Sell_Condition_2)
       {
         if(Sell_Condition_3 && Sell_Condition_4)
           {
            // any opened Sell position?
            if (Sell_opened) 
            {
                Alert("We already have a Sell position!!!"); 
                return;    // Don't open a new Sell Position
            }
            mrequest.action = TRADE_ACTION_DEAL;                                 // immediate order execution
            mrequest.price = NormalizeDouble(latest_price.bid,_Digits);          // latest Bid price
            mrequest.sl = NormalizeDouble(latest_price.bid + STP*_Point,_Digits); // Stop Loss
            mrequest.tp = NormalizeDouble(latest_price.bid - TKP*_Point,_Digits); // Take Profit
            mrequest.symbol = _Symbol;                                         // currency pair
            mrequest.volume = Lot;                                            // number of lots to trade
            mrequest.magic = EA_Magic;                                        // Order Magic Number
            mrequest.type= ORDER_TYPE_SELL;                                     // Sell Order
            mrequest.type_filling = ORDER_FILLING_FOK;                          // Order execution type
            mrequest.deviation=100;                                           // Deviation from current price
            //--- send order
            OrderSend(mrequest,mresult);
            
  
  if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Sell order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Sell order request could not be completed -error:",GetLastError());
            ResetLastError();
            return;
           }
        }
  
  }
  //this is line 332
  }
  
  
  • '}' - unexpected end of program                                                                                  line 332
  • '{' - unbalanced parentheses                                                                                         line 64
  • 'TKP' - some operator expected                                                                                 line 46
  • '}' - semicolon expected                                                                                         line 47
  • expression has no effect                                                                                         line 46
  • 'OnDeinit' - function declarations are allowed on global, namespace or class scope only line 53
  • 'OnTick' - function declarations are allowed on global, namespace or class scope only line 62
  • '{' - unbalanced parentheses                                                                                          line 64

    After a while I got the code down to these errors. I have tried many things but these errors I have no idea. Also a question:  do you have to include the struct properties in the code for every one you use? Please excuse my noviceness. Edit: I commented in the code the lines with errors   

    Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
    Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
    • www.mql5.com
    //| Expert initialization function                                   | //| Expert deinitialization function                                 | //| Expert tick function                                             | //| test1                                                            |...
     
    1. m00nlyte: but these errors I have no idea.
         STP = STP*10
         TKP = TKP*10 //this is line 46

      No terminating semicolons.

    2.    if(Buy_Condition_1 && Buy_Condition_2)
           {
            if(Buy_Condition_3 && Buy_Condition_4)
              {
      
      Two open parentheses without closing equivalents.

    3. Likewise, Sell_Condition…

    4.   int  CopyBuffer(
         int       indicator_handle,     // indicator handle
         int       buffer_num,           // indicator buffer number
         int       start_pos,            // start position
         int       count,                // amount to copy
         double    buffer[]              // target array to copy
         );
      
      Why do you have a function prototype inside a function?

     
    William Roeder:
    1. No terminating semicolons.

    2. Two open parentheses without closing equivalents.

    3. Likewise, Sell_Condition…

    4. Why do you have a function prototype inside a function?

    1: fixed

    2&3: I added semicolons, which prompted the warning "empty controlled statement found"  , I removed the semicolons, and the warnings went away, probably because these don't contain instructions?


    4: oops :) removed

    Code now has 0 errors . 

    If you don't mind I have one more question:

    For  mrequest.sl = NormalizeDouble(latest_price.bid + STP*_Point,_Digits);    is 

    is it necessary to multiply by point? this is for sell side order, the STP already multiplied by 10 to account for 5/3 digit quotes. 


    Many thanks to you! 

    Cheers

     
    m00nlyte:
    For  mrequest.sl = NormalizeDouble(latest_price.bid + STP*_Point,_Digits);    is 
    is it necessary to multiply by point? this is for sell side order, the STP already multiplied by 10 to account for 5/3 digit quotes.

    1. SL is a price; a price ± 100 is not. OOP ± STP × 10 × Point = OOP ± STP × PIP = a price.

      PIP, Point, or Tick are all different in general.
                What is a TICK? - MQL4 programming forum

      Unless you manually adjust your SL/TP for each separate symbol, using Point means code breaks on 4 digit brokers, exotics (e.g. USDZAR where spread is over 500 points,) and metals. Compute what a PIP is and use it, not points.
                How to manage JPY pairs with parameters? - MQL4 programming forum
                Slippage defined in index points - Currency Pairs - Expert Advisors and Automated Trading - MQL5 programming forum

    2. used NormalizeDouble, It's use is usually wrong, as it is in your case.
      1. Floating point has infinite number of decimals, it's your not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
                  Double-precision floating-point format - Wikipedia, the free encyclopedia

        See also The == operand. - MQL4 programming forum

      2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

      3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on metals. (On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum) and abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum

      4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on Metals. So do it right: Trailing Bar Entry EA - MQL4 programming forum or Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum

      5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.

      6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
                  MT4:NormalizeDouble - MQL5 programming forum
                  How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum

      7. Prices you get from the terminal are already normalized.

      8. PIP, Point, or Tick are all different in general.
                  What is a TICK? - MQL4 programming forum