Questions from Beginners MQL5 MT5 MetaTrader 5 - page 1098

 

Hmm, strange situation, like the activity in the topic I raised, I had a question, from my point of view specific, but instead of an answer so far I got "why do you need it?

I want to do it with SB CTrade, here is an example (compiled from 2 my examples): We open everynew bar at 9 TF by one order, we memorize the ticket and determine the direction of a closed order by the ticket number.

In MQL4, the code for the tester would look like this

//+------------------------------------------------------------------+
//|                                                        tst__.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
input int TP = 100;
input int SL = 100;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CNewbar
  {
private:
   datetime          mnewtime;
   ENUM_TIMEFRAMES   mperiod;
public:
                     CNewbar()                        { mperiod=PERIOD_CURRENT;  mnewtime=TimeCurrent(); }
                     CNewbar(ENUM_TIMEFRAMES period)  { mperiod=period;          mnewtime=TimeCurrent(); }
   bool              NewBar(){ datetime t=iTime(NULL,mperiod,0); if(mnewtime<t){ mnewtime=t; return(true); } return(false);  }
  };

ENUM_TIMEFRAMES  TF[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
CNewbar *BAR[9];
int ticket[9];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   for(int i=0;i<9;i++) BAR[i]=new CNewbar(TF[i]);
   ArrayInitialize(ticket,-1);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   for(int i=0;i<9;i++) delete BAR[i];
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   for(int i=0;i<9;i++)
      if(BAR[i].NewBar())
        {
         if(ticket[i]<0) ticket[i]=OrderSend(_Symbol,OP_BUY,0.1,Ask,30,Ask-SL*_Point,Ask+TP*_Point);
         if(OrderSelect(ticket[i],SELECT_BY_TICKET) && OrderCloseTime()>0)
           {
            int cmd=1-OrderType();
            double open=cmd ? Bid : Ask;
            double tp = open - (cmd ? 1 : -1) * TP * _Point;
            double sl = open + (cmd ? 1 : -1) * SL * _Point;
            ticket[i]=OrderSend(_Symbol,cmd,0.1,open,30,sl,tp);
           }
        }
  }

we need a code for the tester, i.e. the minimum number of checks and the fastest possible work in the optimizer.

how to write this code in MQL5 with SB CTrade ?

 
Igor Makanu:

Hmm, strange situation, like the activity in the topic I raised, I had a question, from my point of view specific, but instead of an answer so far I got "why do you need it?

I want to do it with SB CTrade, here is an example (compiled from 2 my examples): We open every new bar at 9 TF by one order, we memorize the ticket and determine the direction of a closed order by the ticket number.

In MQL4, the code for the tester would look like this

how to write this code in MQL5 using SB CTrade ?

Forum on trading, automated trading systems & strategy testing

FAQ from Beginners MQL5 MT5 MetaTrader 5

Vladimir Karputov, 2019.07.21 12:56

So, the basis is thePOSITION_IDENTIFIER, but not the position ticket. It's important just because of the netting:

POSITION_IDENTIFIER

The position identifier is a unique number, which is assigned to each newly opened position and does not change throughout its lifetime. It corresponds to the ticket of the order with which the position was opened.

The position identifier is specified in each order (ORDER_POSITION_ID) and each trade (DEAL_POSITION_ID) which opened, changed or closed it. Use this property to search for orders and trades related to the position.

When a position is reversed in netting mode (a single in/out trade), the POSITION_IDENTIFIER identifier of the position is not changed. However, POSITION_TICKET is changed to the order ticket which resulted in the reversal. In the hedging mode there is no position reversal.

long


So, we have to keep track of the position identifier (POSITION_IDENTIFIER).


Now, a more accurate task: at first run, we open a BUY POSITION and memorize it (WARNING: we should memorize the position ID, not the ticket). If the position has been closed, we open an opposite position: e.g. once upon a time there was a BUY position, then it was closed, which means that we open a SELL position right away.


Now it will be much easier to solve the problem.


 
Vladimir Karputov:

i.e. CTrade does not know how to independently detect if an order is open or closed, what was the type of the last closed order?

which library should I use for this purpose?

 
Igor Makanu:

i.e. does CTrade does not know how to independently detect if an order is open or closed? what was the type of the last closed order?

Which library should we use for this purpose?

I've told you a hundred times already, so please remove the word "order" from your vocabulary. Until you do so, you won't be able to move on. Anyway, I probably won't be able to help you. That's too bad.

 
Vladimir Karputov:

Well, I've told you a hundred times - get the word 'warrant' out of your vocabulary. Until you do that, you can't move on. Anyway, I probably can't help you. That's too bad.

Well, tell me what you mean by that:

GN      0       16:24:14.030    Core 1  2018.06.06 08:00:00   Sell market. Ticket = 20
JF      0       16:24:14.030    Core 1  2018.06.06 08:00:00   Sell market. Identifier = 0
FQ      0       16:24:14.030    Core 1  2018.06.19 16:00:00   ======closePosition======
HG      0       16:24:14.030    Core 1  2018.06.19 16:00:00   market buy 0.10 AUDUSD, close #20 (0.73633 / 0.73637 / 0.73633)
PH      0       16:24:14.030    Core 1  2018.06.19 16:00:00   deal #21  buy 0.10 AUDUSD at 0.73637 done (based on order #21)
 KJ      0       16:24:14.030    Core 1  2018.06.19 16:00:00   deal performed [#21  buy 0.10 AUDUSD at 0.73637]
IL      0       16:24:14.030    Core 1  2018.06.19 16:00:00   order performed buy 0.10 at 0.73637 [#21  buy 0.10 AUDUSD at 0.73637]
RN      0       16:24:14.030    Core 1  2018.06.19 16:00:00   CTrade::OrderSend: market buy 0.10 position #20  AUDUSD [done at 0.73637]
HN      0       16:24:14.030    Core 1  2018.06.19 16:00:00   Позиция с магиком 2544113114312914, тикетом 20 и лотом 0.1 успешно закрыта.
LO      0       16:24:14.030    Core 1  2018.06.19 16:00:00   Очистка данных произведена.
CH      0       16:24:14.030    Core 1  2018.06.19 16:00:00   ======checkMargin======
OF      0       16:24:14.030    Core 1  2018.06.19 16:00:00   market buy 0.10 AUDUSD (0.73633 / 0.73637 / 0.73633)
DS      0       16:24:14.030    Core 1  2018.06.19 16:00:00   deal #22  buy 0.10 AUDUSD at 0.73637 done (based on order #22)
 RM      0       16:24:14.030    Core 1  2018.06.19 16:00:00   deal performed [#22  buy 0.10 AUDUSD at 0.73637]
DS      0       16:24:14.030    Core 1  2018.06.19 16:00:00   order performed buy 0.10 at 0.73637 [#22  buy 0.10 AUDUSD at 0.73637]
FF      0       16:24:14.030    Core 1  2018.06.19 16:00:00   CTrade::OrderSend: market buy 0.10 AUDUSD [done at 0.73637]
MJ      0       16:24:14.030    Core 1  2018.06.19 16:00:00   magic = 2544113114312914
RR      0       16:24:14.030    Core 1  2018.06.19 16:00:00   balance = 11308.94
JK      0       16:24:14.030    Core 1  2018.06.19 16:00:00   lot = 0.10
HQ      0       16:24:14.030    Core 1  2018.06.19 16:00:00   Buy market. Ticket = 22
CJ      0       16:24:14.030    Core 1  2018.06.19 16:00:00   Buy market. Identifier = 20
HR      0       16:24:14.030    Core 1  2018.07.04 08:00:00   ======closePosition======
FI      0       16:24:14.030    Core 1  2018.07.04 08:00:00   market sell 0.10 AUDUSD, close #22 (0.74021 / 0.74025 / 0.74021)
RF      0       16:24:14.030    Core 1  2018.07.04 08:00:00   deal #23  sell 0.10 AUDUSD at 0.74021 done (based on order #23)
 ID      0       16:24:14.030    Core 1  2018.07.04 08:00:00   deal performed [#23  sell 0.10 AUDUSD at 0.74021]
GM      0       16:24:14.030    Core 1  2018.07.04 08:00:00   order performed sell 0.10 at 0.74021 [#23  sell 0.10 AUDUSD at 0.74021]
NQ      0       16:24:14.030    Core 1  2018.07.04 08:00:00   CTrade::OrderSend: market sell 0.10 position #22  AUDUSD [done at 0.74021]
PO      0       16:24:14.030    Core 1  2018.07.04 08:00:00   Позиция с магиком 2544113114312914, тикетом 22 и лотом 0.1 успешно закрыта.
FO      0       16:24:14.030    Core 1  2018.07.04 08:00:00   Очистка данных произведена.
CH      0       16:24:14.030    Core 1  2018.07.04 08:00:00   ======checkMargin======
OI      0       16:24:14.030    Core 1  2018.07.04 08:00:00   market sell 0.10 AUDUSD (0.74021 / 0.74025 / 0.74021)
JO      0       16:24:14.030    Core 1  2018.07.04 08:00:00   deal #24  sell 0.10 AUDUSD at 0.74021 done (based on order #24)
 LM      0       16:24:14.030    Core 1  2018.07.04 08:00:00   deal performed [#24  sell 0.10 AUDUSD at 0.74021]
ND      0       16:24:14.030    Core 1  2018.07.04 08:00:00   order performed sell 0.10 at 0.74021 [#24  sell 0.10 AUDUSD at 0.74021]
LI      0       16:24:14.030    Core 1  2018.07.04 08:00:00   CTrade::OrderSend: market sell 0.10 AUDUSD [done at 0.74021]
OJ      0       16:24:14.030    Core 1  2018.07.04 08:00:00   magic = 2544113114312914
RR      0       16:24:14.030    Core 1  2018.07.04 08:00:00   balance = 11335.85
DK      0       16:24:14.030    Core 1  2018.07.04 08:00:00   lot = 0.10
PN      0       16:24:14.030    Core 1  2018.07.04 08:00:00   Sell market. Ticket = 24
QE      0       16:24:14.030    Core 1  2018.07.04 08:00:00   Sell market. Identifier = 22
NR      0       16:24:14.030    Core 1  2018.07.19 00:00:00   ======closePosition======
NF      0       16:24:14.030    Core 1  2018.07.19 00:00:00   market buy 0.10 AUDUSD, close #24 (0.73968 / 0.73989 / 0.73968)
JI      0       16:24:14.030    Core 1  2018.07.19 00:00:00   deal #25  buy 0.10 AUDUSD at 0.73989 done (based on order #25)
 QK      0       16:24:14.030    Core 1  2018.07.19 00:00:00   deal performed [#25  buy 0.10 AUDUSD at 0.73989]
MM      0       16:24:14.030    Core 1  2018.07.19 00:00:00   order performed buy 0.10 at 0.73989 [#25  buy 0.10 AUDUSD at 0.73989]
PN      0       16:24:14.030    Core 1  2018.07.19 00:00:00   CTrade::OrderSend: market buy 0.10 position #24  AUDUSD [done at 0.73989]
DO      0       16:24:14.030    Core 1  2018.07.19 00:00:00   Позиция с магиком 2544113114312914, тикетом 24 и лотом 0.1 успешно закрыта.
LP      0       16:24:14.030    Core 1  2018.07.19 00:00:00   Очистка данных произведена.
KK      0       16:24:14.030    Core 1  2018.08.08 16:00:00   ======checkMargin======
RI      0       16:24:14.030    Core 1  2018.08.08 16:00:00   market sell 0.10 AUDUSD (0.73933 / 0.73937 / 0.73933)
GO      0       16:24:14.030    Core 1  2018.08.08 16:00:00   deal #26  sell 0.10 AUDUSD at 0.73933 done (based on order #26)
 OM      0       16:24:14.030    Core 1  2018.08.08 16:00:00   deal performed [#26  sell 0.10 AUDUSD at 0.73933]
JD      0       16:24:14.030    Core 1  2018.08.08 16:00:00   order performed sell 0.10 at 0.73933 [#26  sell 0.10 AUDUSD at 0.73933]
QI      0       16:24:14.030    Core 1  2018.08.08 16:00:00   CTrade::OrderSend: market sell 0.10 AUDUSD [done at 0.73933]
HN      0       16:24:14.030    Core 1  2018.08.08 16:00:00   Sell market. Ticket = 26
CF      0       16:24:14.030    Core 1  2018.08.08 16:00:00   Sell market. Identifier = 0
 
Vladimir Karputov:

Well, I've told you a hundred times - get the word 'warrant' out of your vocabulary. Until you do that, you can't move on. Anyway, I probably can't help you. That's too bad.

OK? Let me rephrase the question:

How do you use a remembered ticket with CTrade::ResultOrder()

to find out:

1. whether the position is closed?

2. what type of deal did the closed position have?

3. we need to simultaneously handle 9 positions, orders or tickets, or ... OnAnyTerminology on a hedge account


in this formulation is my question unambiguous? (reproducible example under MQl4 posted above)

ZS: I can't forget the word order, unfortunately this word is used in the help along with other terms:https://www.mql5.com/ru/docs/standardlibrary/tradeclasses/ctrade/ctraderequestorder

 
Igor Makanu:

Hm, it's a strange situation, I seemed to have raised the topic, my question was specific from my point of view, but instead of an answer I got "why do you need it?

The reason is the incompetence of so responders. It took me five minutes to write it and one attempt to check it.


MT4

Forum on trading, automated trading systems and strategy tester

Questions from beginners MQL5 MT5 MetaTrader 5

fxsaber, 2019.07.21 12:54

void OnTick()
  {
   static int ticket1 = -1;
   
   if(ticket1<0) ticket1=OrderSend(_Symbol,OP_BUY,0.1,Ask,30,Ask-100*_Point,Ask+100*_Point);

   if(OrderSelect(ticket1,SELECT_BY_TICKET) && OrderCloseTime())
    {
     int cmd=1-OrderType();
     double open = cmd ? Bid : Ask;
     double tp = open - (cmd ? 1 : -1) * 100 * _Point;
     double sl = open + (cmd ? 1 : -1) * 100 * _Point;
     ticket1=OrderSend(_Symbol,cmd,0.1,open,30,sl,tp);
    }
  }


MT5

#include <Trade\Trade.mqh>

#define  Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  static CTrade Trade; // Не стал возиться с Deviation.
  static ulong ticket1 = 0;
 
  if (!ticket1)
    ticket1 = Trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, 0.1, Ask, Ask - 100 * _Point, Ask + 100 * _Point) ? Trade.ResultOrder() : 0;
  else if (!PositionSelectByTicket(ticket1) && HistorySelectByPosition(ticket1))
  {
    ENUM_ORDER_TYPE cmd = (ENUM_ORDER_TYPE)HistoryOrderGetInteger(HistoryOrderGetTicket(HistoryOrdersTotal() - 1), ORDER_TYPE);
    double open = cmd ? Bid : Ask;
    double tp = open - (cmd ? 1 : -1) * 100 * _Point;
    double sl = open + (cmd ? 1 : -1) * 100 * _Point;
    ticket1 = Trade.PositionOpen(_Symbol, cmd, 0.1, open, sl, tp) ? Trade.ResultOrder() : 0;
  }
}


You don't need to be a strong proficient to write this, you only need to know the basics of MT5.


ZS On netting there is a little nuance in determining the type of closed position. But it doesn't play a role here.

 
fxsaber:

You don't need to be strong to write this, you just need to know the basics of MT5.

Thank you!

Yes, I was looking for a solution if I could not write it in five lines with SB

But how much I understood, that one SB CTrade will not be able to solve my problem? And I had to use CPositionInfo as well? - If I want to accompany 9 positions by several TFs at the same time?

ZS: I'm sitting in the MQL5 help with smart TV - quite well described trade functions, the use of SatB is under a question .... i think it makes sense to use SB for primitive strategies, a bit more complicated - the functionality is insufficient or not obvious use, maybe i need more practice - i will try to "twist" the SB


Thanks again!

 
fxsaber:

The reason is incompetence so answered. It took me five minutes to write and one attempt to check.


MT4


MT5


You don't need to be a strong proficient to write this, you only need to know the basics of MT5.


You do not need to know the basics, you only need to know the basic MT5 basics. But it doesn't matter here.

This is where

ENUM_ORDER_TYPE cmd = (ENUM_ORDER_TYPE)HistoryOrderGetInteger(HistoryOrderGetTicket(HistoryOrdersTotal() - 1), ORDER_TYPE);

there is a potential mistake.

In the historical list the warrants are not arranged in the order in which they appear in that list. Stumbled across this when developing the library. I relied on it. But it turned out to be not so simple. Try to set limit and stop orders in turn in the following order: limit -> stop -> limit -> stop -> limit -> stop and delete each in any order and see which order is the last one recorded in the history list. You will be surprised.

 
Artyom Trishkin:

This is where

there is a potential error.

In the history list, the orders are not arranged in the order in which they appear in the list. I encountered this when developing the library. I relied on it. But it turned out to be not so simple. Try to set limit and stop orders in turn in the following order: limit -> stop -> limit -> stop -> limit -> stop and delete each in any order and see which order is the last one recorded in the history list. You will be surprised.

There is no error there, as the list is generated through HistorySelectByPosition.

Reason: