Need help on a basic algorithm

 

Hi,

I am trying to write my first MQL4 algorithm but it doesnt work as i expected :)

My basic algoritm will work on CHINA50 and it needs to do;

When price moves above moving average for 30 pips, go short and take profit 12 pips, stop loss 20 pips 

When price moves below moving average for 30 pips , go long and take profit 10 pips , stop loss 20 pips

There should be only 1 position open at a time. And it needs to work in 30seconds time frame

When i try this on Startegy test, it opens an order in February and never closes :)


I will appreciate any help, thanks.


#property copyright "Hysterian"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern double TakeProfit = 120;
extern double Lots = 1;
extern double Stoploss=200;
input int      EMA=30;
input int      sellfark=30;
input int      buyfark=-30;
int i;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int start()

    {
   
   double MaCurrent;
   int ticket, total;
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
   if(Bars<300)
     {
      Print("bars less than 100");
      return(0);  
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return(0);  // check TakeProfit
     }
   MaCurrent=iMA(NULL,0,EMA,0,MODE_EMA,PRICE_CLOSE,0);
   //MaPrevious=iMA(NULL,0,EMA,0,MODE_EMA,PRICE_CLOSE,1);
   total=OrdersTotal();
   if(total<1) 
     {
      // no opened orders identified
      if(AccountFreeMargin()<(4*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
     
      
     if(OrdersTotal()>0){
         for(i=1; i<=OrdersTotal(); i++)          // Checking to make sure there are no open orders. Keep this set to zero unless you want the advisor to open more than one buy at a time or more than one sell at a time.
         {
            if (OrderSelect(i-1,SELECT_BY_POS)==true) // If the next is available
               {
                   if(OrderMagicNumber()==34567) {int halt1=1;}///if this magicnumber has an order open... halt!
                   if(OrderMagicNumber()==56789) {int halt2=1;}///if this magicnumber has an order open... halt!
                   }
                  }
                  }
       // check for long position (BUY) possibility
      if(
         
          (Close[0]-MaCurrent)<=buyfark )
         
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-Stoploss,Ask+TakeProfit*Point,"Scalp",34567,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }
         else Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
        }
      // check for short position (SELL) possibility
      if ((Close[0]-MaCurrent)<=buyfark)
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+Stoploss,Bid-TakeProfit*Point,"Scalp",56789,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
         else Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
      return(0);
     }
     return(0);
   }
// the end.
 
canca:

Hi,

I am trying to write my first MQL4 algorithm but it doesnt work as i expected :)

My basic algoritm will work on CHINA50 and it needs to do;

When price moves above moving average for 30 pips, go short and take profit 12 pips, stop loss 20 pips 

When price moves below moving average for 30 pips , go long and take profit 10 pips , stop loss 20 pips

There should be only 1 position open at a time. And it needs to work in 30seconds time frame

When i try this on Startegy test, it opens an order in February and never closes :)


I will appreciate any help, thanks.


this code make me  confused . 

You need to read mql4 document more . 

 

Your stop loss is the current price plus or minus $200. Convert the 200 to points like you did for your take profit, and you'll have at least that issue solved.

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-Stoploss,Ask+TakeProfit*Point,"Scalp",34567,0,Green);
ticket   =  OrderSend(Symbol(), OP_BUY, NormalizeDouble(Lots, 2), Ask, 3, NormalizeDouble(Ask - (Stoploss * Point), 
Digits), NormalizeDouble(Ask + (TakeProfit * Point), Digits), "Scalp", 34567, 0, clrGreen);
 
 ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-Stoploss,Ask+TakeProfit*Point
You buy at the Ask and sell at the Bid.
    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid reaches it. Using the Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?
    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25
    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

  1. Stoploss not multiplied by point.

  2. You 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.

  3.        // check for long position (BUY) possibility
          if( (Close[0]-MaCurrent)<=buyfark ){
             ticket=OrderSend(Symbol(),OP_BUY,Lots,…
            ⋮
            }
          // check for short position (SELL) possibility
          if ((Close[0]-MaCurrent)<=buyfark){
             ticket=OrderSend(Symbol(),OP_SELL,…
    Your buy and sell conditions are identical.
 

Thanks for the great advices, it works now.

The only problem now is when stop loss hits, it reopens the position right away , how can i add  a few tick delay after stop loss hit?

After stop loss hits,  wait for 5 ticks to recheck the conditions for example.

 

You could reset a variable to zero when you have open positions, and then increment that number by one on each tick when you have no open positions.

A number of ticks is not the way to go however. Five ticks, for example, could be nearly as fast as one tick a lot of the time. You would likely be better off waiting until a new bar.

 

Hi, but that will prevent opening after TP too.

I need to prevent reopening after stop loss only, i checked other entries on similar issues but couldnt find any solution. 

Basic Principles - Trading Operations - MetaTrader 5 Help
Basic Principles - Trading Operations - MetaTrader 5 Help
  • www.metatrader5.com
is an instruction given to a broker to buy or sell a financial instrument. There are two main types of orders: Market and Pending. In addition, there are special Take Profit and Stop Loss levels. is the commercial exchange (buying or selling) of a financial security. Buying is executed at the demand price (Ask), and Sell is performed at the...
 
So then you just need to check your order history for the last order to determine if it was hit SL or TP.
 

I just found some code and applied it but it opens no positions.

I guess i wrote some of codes on wrong order probably in highlighed area. Can you check it please? 


extern int TakeProfit = 1300;
extern int  Lots = 1;
extern int  Stoploss=1700;
input int      EMA=250;
input int      sellfark=30;
input int      buyfark=-30;

#include <MQL4OrderPool.mqh>
input int magic_number1 = 34567 ;
input int magic_number2 = 56789 ;
input int num_losing_trades = 1;
input int wait_hours = 3;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
MQL4OrderPool pool;
int OnInit()
{
   pool.Init(Symbol(),magic_number1||magic_number2,MODE_HISTORY,ORDERS_FILLED,SORT_CLOSE_TIME_DESCENDING);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnTick()
{
   if(IsWaitTime())
      return;
}
//+------------------------------------------------------------------+
bool IsWaitTime()
{
   pool.Refresh();
   int cnt=0;
   for(int i=0;i<pool.Total();i++)
   {
      if(pool[i].OrderProfit() < 0.0)
         cnt++;
      else
         break;
   }
   if(cnt >= num_losing_trades && TimeCurrent() - pool[0].OrderCloseTime() < 20)
      return true;
   return false;
}



int start()

  {
  

   double MaCurrent;
   int ticket, total;
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
   if(Bars<10)
     {
      Print("bars less than 100");
      return(0);  
     }
   if(TakeProfit<8)
     {
      Print("TakeProfit less than 10");
      return(0);  // check TakeProfit
     }
   MaCurrent=iMA(NULL,0,EMA,0,MODE_EMA,PRICE_CLOSE,0);
  
   total=OrdersTotal();
   if(total<1) 
    {
      // no opened orders identified
      if(AccountFreeMargin()<(3*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
     
      
     if(OrdersTotal()>0){
         for(int i=1; i<=OrdersTotal(); i++)          // Checking to make sure there are no open orders. Keep this set to zero unless you want the advisor to open more than one buy at a time or more than one sell at a time.
         {
            if (OrderSelect(i-1,SELECT_BY_POS)==true) // If the next is available
               {
                   if(OrderMagicNumber()==34567) {int halt1=1;}///if this magicnumber has an order open... halt!
                   if(OrderMagicNumber()==56789) {int halt2=1;}///if this magicnumber has an order open... halt!
                   }
                  }
                  }
       // check for long position (BUY) possibility
       
       
       
       
       

      if(
         
          (Close[0]-MaCurrent)<=buyfark )
         
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid-Stoploss*Point,Bid+TakeProfit*Point,"Scalp",34567,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }
         else Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
        }
      // check for short position (SELL) possibility
      if ((Close[0]-MaCurrent)>=sellfark)
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Ask+Stoploss*Point,Ask-TakeProfit*Point,"Scalp",56789,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
         else Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
      return(0);
     }
     return(0);
    }
    
// the end.
Reason: