Okay, I've reviewed the provided MQL4 code. Here's a breakdown of its functionality, potential issues, and suggestions for improvement. This is a fairly complex trading script, so I'll try to be thorough.

Overall Functionality

The code appears to be an Expert Advisor (EA) designed to open and close trades based on a combination of indicators:

  • Moving Average: iMA() is used to calculate a moving average. The code checks if the price is above or below this average to determine a potential trade direction.
  • Stochastic Oscillator: iStochastic() is used to calculate the Stochastic Oscillator. The EA uses its values to identify overbought/oversold conditions and potential reversals.
  • Bollinger Bands: iBands() is used to calculate Bollinger Bands. It checks price compared to upper and lower band.
  • Order Management: The EA opens and closes trades using OrderSend() and OrderClose().
  • Trade Logic: The code is divided into logic for both buying ("Tip" 0) and selling ("Tip" 1). It opens orders if no orders are currently open. It closes orders when a specific condition is met.

Key Variables

  • Ticket: The unique ID of an open order.
  • Lot: The trade volume.
  • slb, sls: Stop Loss levels for buy and sell orders.
  • tpb, tps: Take Profit levels for buy and sell orders.
  • dev: The standard deviation multiplier for the Bollinger Bands.
  • opn_b, opn_s: Flags to indicate whether to open a buy or sell order.
  • cls_b, cls_s: Flags to indicate whether to close a buy or sell order.
  • Tip: A variable presumably used to specify whether the EA is in "buy mode" (0) or "sell mode" (1).
  • vrem3: used in MA calculations.
  • Symbol(): retrieves the current symbol.

Code Breakdown and Explanation

  1. Initialization (Not Shown): The OnInit() function (not included in the provided code) would typically initialize indicators, variables, and other settings.

  2. OnTick() Function: This function is called on every tick (price update). The core logic of the EA resides here.

  3. Indicator Calculations:

    • iMA(): Calculates the moving average.
    • iStochastic(): Calculates the Stochastic Oscillator.
    • iBands(): Calculates the Bollinger Bands.
  4. Trade Logic (Buy - Tip 0):

    • Open Buy Order: The EA checks if opn_b is true and no orders are open. It then attempts to open a buy order using OrderSend().
    • Close Buy Order: The EA checks if cls_b is true and attempts to close a buy order using OrderClose(). The closing logic is based on a combination of conditions involving the moving average, stochastic oscillator, and Bollinger Bands.
  5. Trade Logic (Sell - Tip 1):

    • Open Sell Order: Similar to the buy logic, the EA checks if opn_s is true and no orders are open. It then attempts to open a sell order using OrderSend().
    • Close Sell Order: Similar to the buy logic, the EA checks if cls_s is true and attempts to close a sell order using OrderClose(). The closing logic is based on a combination of conditions involving the moving average, stochastic oscillator, and Bollinger Bands.

Potential Issues and Improvements

  • Error Handling: The code has minimal error handling. OrderSend() and OrderClose() can fail for various reasons (e.g., insufficient margin, invalid parameters). You should always check the return value of these functions and handle errors appropriately. This is critical for robustness.

  • Magic Number: The 2 used in OrderSend() and OrderClose() as the magic number should be defined as a constant (e.g., #define MAGIC_NUMBER 2) to improve readability and maintainability.

  • Comment Clarity: While some comments exist, many sections could benefit from more descriptive comments explaining the purpose of the code.

  • Variable Scope: Consider the scope of variables. Declare variables within the smallest possible scope to improve code organization and reduce the risk of unintended side effects.

  • Repetitive Code: The buy and sell logic is very similar. You could refactor the code to reduce duplication by creating a function that handles the common logic and then calling that function with different parameters for buy and sell orders.

  • Stop Loss/Take Profit: The code uses fixed Stop Loss and Take Profit levels. It might be more effective to calculate these levels dynamically based on market volatility (e.g., using ATR) or support/resistance levels.

  • Trade Filtering: The code could benefit from additional trade filtering mechanisms to avoid entering trades in unfavorable market conditions (e.g., during news events or high volatility).

  • Time Filtering: You might want to restrict trading to specific times of the day to take advantage of periods of higher liquidity or volatility.

  • Optimization: The code could be optimized for performance by reducing the number of indicator calculations and using more efficient data structures.

  • Input Parameters: Define input parameters (using extern or input) for key settings like the moving average period, Stochastic Oscillator parameters, Bollinger Bands period and deviation, lot size, Stop Loss, Take Profit, and magic number. This will allow you to easily customize the EA without modifying the code.

Refactoring Suggestions

  1. Create a TradeManager function:
void TradeManager(int tradeType, double& orderPrice, double stopLoss, double takeProfit) {
    if (tradeType == BUY) {
        // ... buy order logic
    } else if (tradeType == SELL) {
        // ... sell order logic
    }
}
  1. Define Constants:
#define BUY 0
#define SELL 1
#define MAGIC_NUMBER 2
  1. Use Input Parameters:
extern int MAPeriod = 20;
extern int StochasticPeriod = 14;
extern int StochasticSmoothing = 3;
extern int BBPeriod = 20;
extern double BBDeviation = 2.0;
extern double LotSize = 0.1;
extern int StopLossPips = 50;
extern int TakeProfitPips = 100;

Example with Error Handling (Partial)

int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, Ask - StopLossPips * Point, Ask + TakeProfitPips * Point, "My EA", MAGIC_NUMBER, 0, Green);

if (ticket < 0) {
    Print("OrderSend failed with error: ", GetLastError());
    // Handle the error (e.g., print a message, log the error, or retry the order)
} else {
    Print("Buy order opened successfully with ticket: ", ticket);
}

Important Considerations

  • Backtesting: Thoroughly backtest the EA on historical data to evaluate its performance and identify potential issues.
  • Demo Account: Test the EA on a demo account before deploying it to a live account.
  • Risk Management: Implement proper risk management techniques to protect your capital.

In conclusion, the provided code is a good starting point for a trading EA. However, it needs significant improvements in terms of error handling, code organization, and risk management. By addressing the issues and suggestions outlined above, you can create a more robust and reliable trading system. Remember to thoroughly test and optimize the EA before deploying it to a live account.

Orders Execution
Checks for the total of open ordersIt Closes Orders by itself It automatically opens orders when conditions are reached
Indicators Used
Stochastic oscillatorMoving average indicatorBollinger bands indicator
6 Views
0 Downloads
0 Favorites
Starter_v2
//+------------------------------------------------------------------+
//|                                           starter.mq4            |
//+------------------------------------------------------------------+
extern double Lot =0.1 ;
extern int TP=0;  
extern int SL=0;  
extern int p_ma=20;
extern int pK=5;            
extern int pD=3;
extern int Slow=3;
int p_bb=20;
int dev=2;
int p;

int init()
  {
//---- 
//----
   return(0);
  }
int deinit()
  {
//----   
//----
   return(0);
  }

int start()
  {
      int Tip=-1;                          
      int Ticket;
      double tpb,tps,slb,sls;
      double  Price,sl ,tp ,lt;
      bool opn_b=false;
      bool cls_b=false;
      bool opn_s=false;
      bool cls_s=false;
      int vrem3;
      p=Period();

    if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
        {
            Ticket=OrderTicket();
            Tip   =OrderType(); 
            Price =OrderOpenPrice();               
            sl    =OrderStopLoss();                
            tp    =OrderTakeProfit();              
            lt    =OrderLots();
            datetime openTime=OrderOpenTime();
        }
                       if(SL!=0)
                           { 
                              slb=Bid-SL*Point;
                              sls=Ask+SL*Point;
                           }
                       else
                           {
                              sls=0;
                              slb=0;
                           }
                       if(TP!=0)
                           {
                              tpb=Bid+TP*Point;
                              tps=Ask-TP*Point;
                           }
                       else
                           {
                              tpb=0;
                              tps=0;   
                           }
         
     int i=0;                           
     int pe,p2,p3;
     pe=Period();
     switch(pe)
     {
         case 1:     p3=15;   p2=5;      break;
         case 5:     p3=30;   p2=15;       break;
         case 15:    p3=60;   p2=30;       break;
         case 30:    p3=240;  p2=60;      break;
         case 60:    p3=1440; p2=240;     break;
         case 240:   p3=10080;p2=1440;    break;     
         case 1440:  p3=43200;p2=10080;  break;     
         case 10080:          p2=43200; break;       
         case 43200:                    break;       
     }
if(OrdersTotal()==0)
{  
   vrem3=0;
}
if(OrdersTotal()!=0)
   {
    if(iTime(NULL,p3,0)>openTime)       
         {
            while(iTime(NULL,p3,i)>openTime)                    
            {
               i++;
            } 
            if(iTime(NULL,p3,i)<=openTime)
            {
               vrem3=i; 
            } 
            i=0;
         }
     if(iTime(NULL,p3,0)<=openTime)
     {
         vrem3=0;
     }
	}
if(p!=10080 && p!=43200)
{

if(OrdersTotal()==0 )
{
   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) && 
      iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<50 && Ask<iMA(NULL,p3,p_ma,0,0,0,0) 
     )
      {      
         if(iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_SIGNAL,0)&&
            iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_MAIN,0)<50 && Bid<iMA(NULL,0,p_ma,0,0,0,0)&&
            iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
            iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_MAIN,0)<50 && Bid<iMA(NULL,p2,p_ma,0,0,0,0) 
           )
           {    
               opn_b=true;
           }
      } 
	if( Bid>iMA(NULL,p3,p_ma,0,0,0,0) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0)>50 && Ask<iBands(NULL,p3,p_bb,dev,0,PRICE_CLOSE,MODE_UPPER,0))
		{    
        opn_b=true;
      }
}   
if(Tip==0 ) 
{
	if(Price<iMA(NULL,p3,p_ma,0,0,0,vrem3))
	{
		   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
			  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1)&&
			  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>50)
		   {
			  cls_b=true;
		   } 
		   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
			  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1)&&
			  Bid>Price)
		   {
			  cls_b=true;
		   } 
	}
	
	if(Price>iMA(NULL,p3,p_ma,0,0,0,vrem3)&& vrem3 !=0)
	{
		if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1))
		{
			cls_b=true;
		}
	}
}   
if(OrdersTotal()==0 )
{
   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
      
      iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>50 && Bid>iMA(NULL,p3,p_ma,0,0,0,0)
     )
   {      
         if(iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_SIGNAL,0)&&
            iStochastic(NULL,0,pK,pD,Slow,0,0,MODE_MAIN,0)>50 && Bid>iMA(NULL,0,p_ma,0,0,0,0)&&
            iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
            iStochastic(NULL,p2,pK,pD,Slow,0,0,MODE_MAIN,0)>50 && Bid>iMA(NULL,p2,p_ma,0,0,0,0)
            
           )
           {    
               opn_s=true;
           }
	
   }
   
   	if( Bid<iMA(NULL,p3,p_ma,0,0,0,0) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1) &&
		iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<50 && Bid>iBands(NULL,p3,p_bb,dev,0,PRICE_CLOSE,MODE_LOWER,0))
		{    
        opn_s=true;
        }     
} 

if(Tip==1 ) 
{
	if(Price>iMA(NULL,p3,p_ma,0,0,0,vrem3))
	{
	   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
		  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1)&&
		  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)<50)
	   {
		  cls_s=true;
	   } 
	   if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,0) &&
		  iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1)<iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_SIGNAL,1)&&
		  Ask<Price)
	   {
		  cls_s=true;
	   } 
	}
	
	if(Price<iMA(NULL,p3,p_ma,0,0,0,vrem3)&& vrem3 !=0)
	{
		if(iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,0)>iStochastic(NULL,p3,pK,pD,Slow,0,0,MODE_MAIN,1))
		{
			cls_s=true;
		}
	}
	
}  

}

     if(Tip==1 && cls_s==true)      
            {
               OrderClose(Ticket,Lot,Ask,2); 
             
            }          
       if(Tip==0 && cls_b==true)
         {
            OrderClose(Ticket,Lot,Bid,2);
            
         }

   if (OrdersTotal()==0)
   {
         if(opn_b==true)
           
            {
               OrderSend(Symbol(),OP_BUY,Lot,Ask,2,slb,tpb,0,0,0); 
             
               if (Ticket > 0)                      
                           {
                          
                            Alert ("Îòêðûò îðäåð Buy ",Ticket);
                            return;                             
                           }
            }
         if(opn_s==true)
               {
                  OrderSend(Symbol(),OP_SELL,Lot,Bid,2,sls,tps,0,0,0); 
                        if (Ticket > 0)                       
                           {
                            Alert ("Îòêðûò îðäåð Sell ",Ticket);
                             
                            return;                           
                           }
               } 
        
    }   
//----
   return(0);
  }
//+------------------------------------------------------------------+


Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---