Please check my code, I am starting to learn MQL

 

Hello,

I started learning MQL,

I have written following code.

I started off from a code from web, but because it was too complicated, I tried to distill it down to small IF and FOR conditions, which I understand a bit.

It is very simple because right now these are the only chapters I have finished.

I will not understand if you try to tell me something complicated which I have not yet finished.

My another problem is that I am not finding any good BOOK FOR DUMMIES like me for MQL .. the documentation and help file in MQL is not a very newbie friendly text .. any help?

Also, could someone please check this code to see if its live worthy?

Will be testing it on demo of course, but because I am new, I would be glad if someone wants to help me test this.

Code is intended for following:-

If TWO OR MORE orders are running and if SUM TOTAL of those is above X, Expert should close all open orders.. its that simple..

Please go through it and guide me if there are any errors..

Currently on my MT4 625 it compliled without errors and warnings.

extern double My_Money_Profit_Target=100;     //The amount of money profit at which you want to close ALL open trades.
extern string Profit_Target= "Enter above To Close all OPEN trades when amount of profit is Reached in Account and not per OPEN trade! ";
                                          
int Slippage=5;
int i;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function... this is the code that I changed         |
//+------------------------------------------------------------------+


int start()
{ 
 if (OrdersTotal()>=2)

 {
   if (AccountProfit()>= My_Money_Profit_Target)
   {
    for(i=OrdersTotal()-1;i>=0;i--)
       {
       bool x = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
               
       bool result = false;
       
       if(x)
       {       
         if(OrderType()==OP_BUY)
          {
           result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Pink);
          }
          else if(OrderType()==OP_SELL)
          {
            result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage,Pink);
                          
          }
        }
          
       }
      Print ("Account Profit Reached. All Open Trades Have Been Closed");
      return(0);
   }  
   
   Comment("Balance: ",AccountBalance(),", Account Equity: ",AccountEquity(),", Account Profit: ",AccountProfit(),
           "\nMy Account Profit Target: ",My_Money_Profit_Target);
   
  
   }
   return(0);   
 }

tx so much.

 
You need to use OrderProfit instead of AccountProfit. you will need to go thru the for loop looking at the OrderProfit of open orders and adding them together.. when they are greater than your target then you close them all....
 
Jimdandy:
You need to use OrderProfit instead of AccountProfit. you will need to go thru the for loop looking at the OrderProfit of open orders and adding them together.. when they are greater than your target then you close them all....


AccountProfit is ok to use. It's the total profit that you see under the profit column in the trade tab

The documentattion suggests otherwise though :(

 
Jimdandy:
You need to use OrderProfit instead of AccountProfit. you will need to go thru the for loop looking at the OrderProfit of open orders and adding them together.. when they are greater than your target then you close them all....


Right now it calculates the AccountProfit() .. this is direct value of total account profit from start point to 'start point + X' .. where X is defined as total AMOUNT of Profit in ACCOUNT rather than per trade

This is because I ONLY have MAX 2 orders running at any given time and both need to exit when total profit on the ACCOUNT is X pips .. Could you please tell me WHY its necessary to use OrderProfit when its achieving same numerical results at the end?

Right now, EA does close out the order at X pip.. this I confirmed on demo, BUT, the problem is that it will close the order even if there is an untriggered pending order on other pair .. a pain..

Also, my other problem which I have not yet been able to solve successfully is to code a custom function to count only OPEN orders .. built in function OrdersTotal() counts ALL .. open as well as pending..

A coder thrdel here did give me following code to count only OPEN orders, but right now I do not have the ability to attach it to above code. [ all thanks go to him for below code]

That the next step for me .. to understand the code below and insert it properly in place of that 'OrdersTotal()>=2' ...

double CountMyOrders()
  {
   myOrders=0;
   for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)==false)
         Print("Failed to select order, error : "+ErrorDescription(GetLastError()));
      //skip orders placed by other EA's
      if(OrderMagicNumber()>0)continue;
      if(OrderType()==OP_BUY || OrderType()==OP_SELL)
        {
         myOrders++;
        }
     }
   return(myOrders);
  }
 
GumRai:


AccountProfit is ok to use. It's the total profit that you see under the profit column in the trade tab

The documentattion suggests otherwise though :(


Thanks a loads.. I am with you on that one.. AccountProfit() currently works for me .. it calculates the total profit properly considering spread and such .. so that doesnt need to change based on dont change it if its not broken.

Could you help me add the custom function to above code? thanks.

 
tatyawinchu:


Thanks a loads.. I am with you on that one.. AccountProfit() currently works for me .. it calculates the total profit properly considering spread and such .. so that doesnt need to change based on dont change it if its not broken.

Could you help me add the custom function to above code? thanks.


Do you understand how this code is written ??

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "https://www.mql4.com"
#property description "Moving Average sample expert advisor"

#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =12;
input int    MovingShift   =6;
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//--- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Error in history!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
            continue;
         //---
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//--- sell conditions
   if(Open[1]>ma && Close[1]<ma)
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(Open[1]<ma && Close[1]>ma)
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//--- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma)
            OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+

if you do, you know how to implement a function, like you have from thrdel, inside your code

 
deVries:


Do you understand how this code is written ??

if you do, you know how to implement a function, like you have from thrdel, inside your code



Roger, reading the chapter on functions.. should take two days.

Also, my friend trades with two brokers, his one broker allows EAs and another one doesnt .. [ both are MT4 600 above ]

What I am curious to find out is if EA is not allowed by broker, does such directly extend to scripts too? Would it reject all orders sent via script? [ non EA] ? Or at server end it does not differentiate between the two?

 
Script or EA always have its characteristics/patterns that broker can identify. You have to change magic number, how its opening trades and so on, so that broker would not be able to catch the patterns.
 
tatyawinchu:



Hi tatyawinchu,

A function is a piece of code that is executed every time you mention the function name.

Here, every time you mention in your code : " CountMyOrders(); " (without the quotes ) the program jumps to the location of that code, executes the code and, if not void type function, will return a value.

If it makes more sense, you can even rename the function to CountOpenOrders() or CountManualOpenOrders(), whatever is easier for you.

Here is how to attach a custom function to your code :

Step 1, copy the code to the end of your EA :

Step 2, call the function to execute the code.

 CountMyOrders();

The function will return the number of open orders and store it in myOrders variable.

So instead of

int start()
{ 
 if (OrdersTotal()>=2)

you will have

if(CountMyOrders()>=2) // if the value returned by this function >= 2 .....
   {
   // your code here

So your code can look like this :

#include stdlib.mql      // this will help give you a description of the error if there are any errors,  so it has to be included
extern double My_Money_Profit_Target=100;     //The amount of money profit at which you want to close ALL open trades.
extern string Profit_Target= "Enter above To Close all OPEN trades when amount of profit is Reached in Account and not per OPEN trade! ";
                                          
int Slippage=5;
int i;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function... this is the code that I changed         |
//+------------------------------------------------------------------+


int start()
{ 
 if (CountMyOrders()>=2) // this is the call to count open orders only

 {
   if (AccountProfit()>= My_Money_Profit_Target)
   {
    for(i=OrdersTotal()-1;i>=0;i--)
       {
       bool x = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
               
       bool result = false;
       
       if(x)
       {       
         if(OrderType()==OP_BUY)
          {
           result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Pink);
          }
          else if(OrderType()==OP_SELL)
          {
            result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage,Pink);
                          
          }
        }
          
       }
      Print ("Account Profit Reached. All Open Trades Have Been Closed");
      return(0);
   }  
   
   Comment("Balance: ",AccountBalance(),", Account Equity: ",AccountEquity(),", Account Profit: ",AccountProfit(),
           "\nMy Account Profit Target: ",My_Money_Profit_Target);
   
  
   }
   return(0);   
 }
//==================================================================================================================
double CountMyOrders()
  {
   int myOrders=0;
   for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
     {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)==false)
         {
         Print("Failed to select order, error : "+ErrorDescription(GetLastError()));
         continue;
         }
      //skip orders placed by other EA's
      if(OrderMagicNumber()>0)continue; 
      if(OrderType()==OP_BUY || OrderType()==OP_SELL) myOrders++;
     }
   return(myOrders);
  }
 

Now the other problem, you can have with this code

Might be it is not always happening,

but if closing happens and one trade fails to close you keep that trade

 
thrdel:


Hi tatyawinchu,

A function is a piece of code that is executed every time you mention the function name.

Here, every time you mention in your code : " CountMyOrders(); " (without the quotes ) the program jumps to the location of that code, executes the code and, if not void type function, will return a value.

If it makes more sense, you can even rename the function to CountOpenOrders() or CountManualOpenOrders(), whatever is easier for you.

Here is how to attach a custom function to your code :

Step 1, copy the code to the end of your EA :

Step 2, call the function to execute the code.

The function will return the number of open orders and store it in myOrders variable.

So instead of

you will have

So your code can look like this :

thrdel:


Hi tatyawinchu,

A function is a piece of code that is executed every time you mention the function name.

Here, every time you mention in your code : " CountMyOrders(); " (without the quotes ) the program jumps to the location of that code, executes the code and, if not void type function, will return a value.

If it makes more sense, you can even rename the function to CountOpenOrders() or CountManualOpenOrders(), whatever is easier for you.

Here is how to attach a custom function to your code :

Step 1, copy the code to the end of your EA :

Step 2, call the function to execute the code.

The function will return the number of open orders and store it in myOrders variable.

So instead of

you will have

So your code can look like this :



FANTASTIC .. and pretty nicely explained .. Functions are fantastic .. they open up such a beautiful world .. =D .. Plus my friend just gave me a book called "Spirit of C" .. LOVING it.. do you know of it?
Reason: