Discussion of article "Writing an Expert Advisor using the MQL5 Object-Oriented Programming approach" - page 2

 
Yedelkin:
If the Bid at the opening will be at 1.2695, we already have 5 pips of loss automatically. If at the same time SL is 50 pips according to the developer's idea, then 45 more pips have to pass in the unfavourable direction before it triggers. I.e., when the stop loss is triggered, Bid should be not at 1.2645, but at 1.2650; and Ask, respectively, at 1.2655.

1. About the loss of 5 pips at the opening.

You are right about the loss, if we close the position at the same moment (conditionally) we will get a loss in the amount of the spread, the very 5 pips.

Since longs are closed at the Bid (counter) price.

At least logically in this case we should get this loss (and it is correct).

This is also true for closing with a counter order. What result do you think we will get when the counter order is triggered at the price of 1.2695 (which is where the Bid is at the moment)?

Well, you will not claim that the opening price of SHORT positions is Ask?

2. Let's deal with the BU close

We remember that we opened in Buy at 1.27 (this price is now a BU level for us).

It is reasonable to assume that the BU close will occur if the Bid price reaches 1.27 (i.e. it will go exactly 5 pips up).

Let's check our statement by closing on the CU with the help of a counter order. The opening price of such a position should be at 1.27, and as we know Sell orders are placed at Bid. Currently Bid is at 1.2695. Therefore, to close in the BU it needs to pass 5 pips, so there is no error in calculations and the statement is correct.

3. about SL and TP

Two statements rule here:

а. Longs open at Ask and close at Bid; Shorts open at Bid and close at Ask.

б. The distance to TP and SL are calculated from the Open Price, the calculation takes into account the direction of the position.


In exact accordance with the second statement, we will determine the SL and TP prices for our example. At Open Price 1.27 SL = 1.2650 and TP = 1.28 (according to the conditions described above).

According to the first statement, the LONG (and in the example it is the LONG) will open on the condition that Ask will be equal to 1.27 (and Bid will be equal to 1.2695, based on the spread of 5 pips). 4.

4. Now let's determine under what conditions our SL and TP will be triggered.

Our position will be closed when one of the conditions is met (if there are no other factors):

On TP - If Bid reaches 1.28 (100 pips from 1.27), Ask at this time will be at 1.2805 (the first statement and the size of the spread rule here).

Let's check our statement by closing on TP using a counter position. The opening price of such a position should be at 1.28, and as we know Sell orders are placed at Bid. Currently Bid is at 1.2695. Therefore, to close on TP it is necessary to pass 5 pips (to cover losses on the spread) + 100 pips to fix the profit.

On SL - If the price reaches the SL level, equal to 1.2650 as we remember.


Now let's understand what price it will be. Logically, it should be the Bid price (which corresponds to the opening price of the counter order).

We remember that at present (according to the condition of position opening) Bid is at 1.2695. Therefore, the price needs to pass 45 pips before the SL triggers.

Thus, we will record a loss equal to the spread (5 pips) + 45 pips that the price had time to pass before the SL triggers.

From this point of view you are right

Let's check our statement by closing on SL using a counter position. The opening price of such a position should be at 1.2650, and as we know Sell orders open at Bid. Currently Bid is at 1.2695. Therefore, to close on SL it is necessary to pass 45 pips. When SL is triggered, a loss of 50 pips will be recorded (5 pips on the spread + 45 pips on the move against us).

PS

But from this point of view, this example for MQL4 is not very clear to me.

int ticket;

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
    {
     ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green);
     if(ticket<0)
       {
        Print("OrderSend failed with error #",GetLastError());
        return(0);
       }
    }

More precisely, I am not very clear on the basis of what logic and what statements SL and only it is considered.

But based on this example (and only from it) I get the following

//Basic example
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL = Bid-Loss*Point,TP = Ask+Profit*Point,"My order #"+counter,16384,0,Green);
//Order to open a market position
ticket=OrderSend(Symbol(),OP_BUY,1,1.27,3,1.2645 = 1.2695-50*Point,1.28 = 1.27+100*Point);

Based on the values Open = 1.27, SL = 1.2645 and TP = 1.28 I understand the following:

1. The position is opened when Ask reaches the price of 1.27 (in our case it is already there);

2. The BU level is located at the price of 1.27 and in order to close on it the rate of the symbol (in our case EUR) should grow by the spread size (in our case 5 pips);

3. At the moment of opening, we immediately get a loss in the amount of the spread (in case we close the position IMMEDIATELY), because the open position, based on logical statements, should be closed with a counter order. In MQL4 code, such an operation will look as follows

//Basic example
ticket=OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0);
//Closing a position on the market with a counter order
ticket=OrderSend(Symbol(),OP_SELL,1,1.2695,3,0,0);

4. TP is triggered after the price reaches the level of 1.28. Logically, this should be the Bid price, since the counter order is opened at this price (the trade is executed when the Bid price reaches the value of 1.28). Based on this, the closing in the MQL4 code should look as follows

//Closing a TP position with a market order (counter order)
ticket=OrderSend(Symbol(),OP_SELL,1,1.28,3,0,0);
//Closing a position with a counter pending order (limiter)
ticket=OrderSend(Symbol(),OP_SELLLIMIT,1,1.28,3,0,0);

5. SL will be triggered after the rate of the symbol being traded (in our case EUR) falls by 50 pips from the moment of opening.


Now the most interesting thing

Let's check the opening of a market position based on the same example from the MQL4 Help (a classic example, which has probably been used by thousands of people).

We will use this code to check it

//+------------------------------------------------------------------+
double PriceOpen,PriceSL,PriceTP;
int ticket;
//+------------------------------------------------------------------+
//Formulate prices for the order
PriceOpen = Ask;
PriceSL   = Bid-500*Point;
PriceTP   = PriceOpen+1000*Point;
//Order to open a market position
ticket = OrderSend(Symbol(),OP_BUY,0.10,PriceOpen,5,PriceSL,PriceTP);
//+------------------------------------------------------------------+

Executing this code on Alpari's server (using real quotes) gives the following result

2010.08.24 09:12:47 '******': instant order buy 0.10 EURUSD at 1.26292 sl: 1.25776 tp: 1.27292

It is easy to guess that in this case we will get the following sizes SL = 516 (or 51 pips for 4 digits) TP = 1000 (or 100 pips for 4 digits)

PPS

Let's look at the MQL4 Help:

Parameters:
symbol - Name of the financial instrument, with which the trade operation is performed.
cmd - Trade operation. Can be any of the trade operation values.
volume - Number of lots.
price - Opening price.
slippage - Maximum allowable price deviation for market orders (buy or sell orders).
stoploss - Position closing price when the loss level is reached (0 in case of no loss level).
takeprofit - Position closing price when profitability level is reached (0 in case of absence of profitability level).
comment - Text of the order comment. The last part of the comment can be changed by the trade server.
magic - Magic number of the order. It can be used as a user-defined identifier.
expiration - Expiration period of the pending order.
arrow_colour - Colour of the opening arrow on the chart. If the parameter is absent or its value is CLR_NONE, the opening arrow is not displayed on the chart.
Example:
  int ticket; if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point, "My order #"+counter,16384,0,Green); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } } }

"Here tell me where the truth is brother?"...?

OrderSend - Документация на MQL4
  • docs.mql4.com
OrderSend - Документация на MQL4
 
Yedelkin:

I don't understand the following part of the code:

// Copy the closing price of the previous bar (bar 1) to the corresponding Expert Advisor variable
   Cexpert.setCloseprice(mrate[1].close);  // bar 1 closing price
//--- Check if there is a buy position
   if (Cexpert.checkBuy()==true)
   {
      if (Buy_opened) 
         {
            Alert("We already have a position to buy!!!"); 
            return;    // Do not add to the long position
         }
      double aprice = NormalizeDouble(latest_price.ask,_Digits);
      double stl    = NormalizeDouble(latest_price.ask - STP*_Point,_Digits);
      double tkp    = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits);
      int    mdev   = 100;
      // place the order
      Cexpert.openBuy(ORDER_TYPE_BUY,Lot,aprice,stl,tkp,mdev);
   }
If we are going to open a buy position, we should focus on the latest_price.ask price, but when setting a Stop Loss and Take Profit for such a position - on the latest_price.bid price. Is this correct? Why do Stop Loss and Take Profit are set based on the ask price in the code text? Is it a misprint or a peculiarity of a particular strategy (the code has a similar construction for opening a Sell position)?

This part of the code should be understood on the basis of the following statements:

а. Long - open at Ask and close at Bid; Short - open at Bid and close at Ask;

б. Positions are closed by counter orders;

в. The BU level is at the Open Price;

г. Distance to TP and SL are calculated from the Open Price (CU level);

д. TP will be triggered when the price Bid reaches a level equal to Open Price + Profit size;

e. SL will be triggered when the security reaches the Bid level equal to Open Price - Loss size.

The author of the Expert Advisor was most likely guided by similar statements in his work. To make everything as clear as possible, I offer an illustration of the above with the help of the following screen (we are interested in the red rectangle).


 
Interesting:

e. SL will be triggered when the price Bid reaches a level equal to Open Price - Loss size.

Thanks, I understand the logic. But still, according to point "e" it turns out that when the stoploss is triggered, Bid should be not at 1.2645, but at 1.2650; and Ask, respectively, at 1.2655.

 
Yedelkin:

Thanks, I understand the logic. But still, according to point "e" it turns out that when a stoploss is triggered, Bid should be not at 1.2645, but at 1.2650; and Ask, respectively, at 1.2655.

It may be so, you need to check what exactly happens when triggering a stop-loss by the market (well, or adjust the matrix model taking into account all the available closing possibilities)....


For point "e" (as I understand it)

In case of counting from Open (Ask) it will be 1.27-50 = 1.2650 (price will pass 45 pips and the pose will close), if I understood correctly. In this case I think SL should work at Bid 1.2650 and Ask 1.2655.

Another thing, if we count from Bid, then we will get the price 1.2695-50 - 1.2645 (you can't argue with maths). If we calculate SL from Bid we will get 1.27-1.2645 = 55 pips (which as I understand was not part of our plans).

PS

At least, this model allows us to correctly break the SL and TP levels from the Open price (in my opinion correctly)...

Of course, it would be interesting to hear the developers' official opinion on how prices should be calculated in reality (not only SL and TP).

 

Question.


100 greenbacks - is it in ruble or u.e.? ;)

 
that was promised to go away.
 
Jager:

Question.


100 greenbacks - is it in ruble or u.e.? ;)

This is the timeout value in milliseconds. This parameter has already been removed from all trading functions.
 

Hi  thanks for the well laid out example.

 But I have to ask is it right?  

 In the EA it is checking for a trade opportunity at the start of each new bar. 

In the class function  getbuffers() it retrieves the last 3 bars data starting at the current bar 0 which has only just been formed and therefore the value is errornous.

 void MyExpert::getBuffers()
  {
   if(CopyBuffer(ADX_handle,0,0,3,ADX_val)<0 || CopyBuffer(ADX_handle,1,0,3,plus_DI)<0
      || CopyBuffer(ADX_handle,2,0,3,minus_DI)<0 || CopyBuffer(MA_handle,0,0,3,MA_val)<0)

 

Should it not be retrieving the last 3 bars indicator data starting at position 1?

thanks

 

Great Article Samuel

Thank you in advance for this priceless article,

So based on this article, we could include functions such as IsNewBar or Buy_opened to the class and just calling it from EA.

Thank you again,

I hope seeing more article from you,

Hamed, 

 

Please help me to understand something I don't understand:

At the very beginning of the EA the function is called:

  Cexpert.doInit(ADX_Period,MA_Period);
при этом для ее корректного выполнения требуются уже установленные параметры symbol  и period :
//+-----------------------------------------------------------------------+
// PUBLIC FUNCTIONS OF OUR CLASS 
//+-----------------------------------------------------------------------+
/*
 Initialising 
*/
void MyExpert::doInit(int adx_period,int ma_period)
{
   //--- Get ADX indicator handle
   ADX_handle=iADX(symbol,period,adx_period);
  //--- Get Moving Average indicator handle
   MA_handle=iMA(symbol,period,ma_period,0,MODE_EMA,PRICE_CLOSE);
однако, заполнение этих параметров конкретными значениями происходит позже, уже после Cexpert.doInit :
//--- start the initialisation function
   Cexpert.doInit(ADX_Period,MA_Period);
//--- setting all necessary variables for our class object
   Cexpert.setPeriod(_Period);     // sets the period
   Cexpert.setSymbol(_Symbol);     // specifies the symbol (currency pair)
   
   Никак не пойму, как может правильно выполниться Cexpert.doInit, если переменной symbol пока не присвоено
значение (или как-то присвоено ?) Застрял тут и дальше никак . Спасибо.