Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1098

 

хм, странная ситуация, вроде активность  в топике я поднял,  вопрос у меня был, с моей точки зрения конкретный, а вместо ответа пока получил "а зачем тебе это?"

ОК, мне нужно в тестере промасштабировать ТС сразу на несколько ТФ, хочу это реализовать с помощью СБ CTrade, вот пример (собранный из 2-х моих примеров): открываем каждый новый бар на 9-ти ТФ по одному ордеру, тикет запоминаем и по номеру тикета определяем закрылся ли ордер? и какое направление было у закрытого ордера?

в MQL4 код для тестера будет выглядеть так:

//+------------------------------------------------------------------+
//|                                                        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);
           }
        }
  }

нужен код для тестера, т.е. минимум проверок и максимально быстро работающий в оптимизаторе

как написать этот код в MQL5 с помощью СБ CTrade ???!!!

 
Igor Makanu:

хм, странная ситуация, вроде активность  в топике я поднял,  вопрос у меня был, с моей точки зрения конкретный, а вместо ответа пока получил "а зачем тебе это?"

ОК, мне нужно в тестере промасштабировать ТС сразу на несколько ТФ, хочу это реализовать с помощью СБ CTrade, вот пример (собранный из 2-х моих примеров): открываем каждый новый бар на 9-ти ТФ по одному ордеру, тикет запоминаем и по номеру тикета определяем закрылся ли ордер? и какое направление было у закрытого ордера?

в MQL4 код для тестера будет выглядеть так:

как написать этот код в MQL5 с помощью СБ CTrade ???!!!

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопросы от начинающих MQL5 MT5 MetaTrader 5

Vladimir Karputov, 2019.07.21 12:56

Итак, основа основ - Идентификатор позиции (POSITION_IDENTIFIER), но ни как не тикет позиции. Это важно, как раз из-за неттинга:

POSITION_IDENTIFIER

Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция.

 

Идентификатор позиции указывается в каждом ордере (ORDER_POSITION_ID) и сделке (DEAL_POSITION_ID), которая ее открыла, изменила или закрыла. Используйте это свойство для поиска ордеров и сделок, связанных с позицией.

 

При развороте позиции в режиме неттинга (единой сделкой in/out) идентификатор позиции POSITION_IDENTIFIER не изменяется. Однако при этом POSITION_TICKET изменяется на тикет ордера, в результате которого произошел разворот. В режиме хеджинга разворот позиции не предусмотрен.

long


Значит нужно запоминать и отслеживать идентификатор позиции (POSITION_IDENTIFIER).


Теперь уточнённая задача: при первом запуске открываем ПОЗИЦИЮ BUY и запоминаем её (ВНИМАНИЕ: запоминать нужно идентификатор позиции, но не тикет). Если позиция была закрыта - открываем противоположную позицию: например жила-была позиция BUY, затем она была закрыта, а значит открывается сразу позиция SELL.


Теперь решить задачу станет намного легче.


 
Vladimir Karputov:

пролистал справку, не вижу у СБ CTrade методов для работы с идентификатором позиции, т.е. СБ CTrade не умеет определять самостоятельно открыт ордер или закрыт? какой тип был у последнего закрытого ордера?

какую библиотеку нужно использовать для этой цели?

 
Igor Makanu:

пролистал справку, не вижу у СБ CTrade методов для работы с идентификатором позиции, т.е. СБ CTrade не умеет определять самостоятельно открыт ордер или закрыт? какой тип был у последнего закрытого ордера?

какую библиотеку нужно использовать для этой цели?

Ну я уже сто раз говорил - выкиньте из лексикона слово "ордер". Пока Вы этого не сделаете - Вы не сможете идти дальше. В общем я вероятно Вам не смогу помочь. Печаль.

 
Vladimir Karputov:

Ну я уже сто раз говорил - выкиньте из лексикона слово "ордер". Пока Вы этого не сделаете - Вы не сможете идти дальше. В общем я вероятно Вам не смогу помочь. Печаль.

А подскажите, как понимать это:

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:

Ну я уже сто раз говорил - выкиньте из лексикона слово "ордер". Пока Вы этого не сделаете - Вы не сможете идти дальше. В общем я вероятно Вам не смогу помочь. Печаль.

OK? сформулирую вопрос иначе:

как используя запомненный тикет с помощью CTrade::ResultOrder()

узнать:

1. закрыта ли позиция?

2. какой тип сделки был у закрытой позиции?

3. нужна одновременная работа с 9-ю позициями, ордерами или тикетами или ... НаВашеУсмотрениеЛюбаяТерминология  на счете типа хэдж


в такой формулировке мой вопрос однозначный? (воспроизводимый пример под MQl4 выложен выше)

ЗЫ: я не могу забыть слово ордер, к сожалению это слово используется в справке наряду с другими терминами: https://www.mql5.com/ru/docs/standardlibrary/tradeclasses/ctrade/ctraderequestorder

 
Igor Makanu:

хм, странная ситуация, вроде активность  в топике я поднял,  вопрос у меня был, с моей точки зрения конкретный, а вместо ответа пока получил "а зачем тебе это?"

Причина в некомпетентности так отвечающих. Мне понадобилось пять минут на написание и одна попытка на проверку.


MT4

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопросы от начинающих 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;
  }
}


Чтобы это написать, не надо быть сильным разбирающимся, достаточно знать только основы MT5.


ЗЫ На неттинге маленький нюанс существует при определении типа закрытой позиции. Но здесь это не играет роли.

 
fxsaber:

Чтобы это написать, не надо быть сильным разбирающимся, достаточно знать только основы MT5.

Благодарю!

Да это и искал решение если не получилось с помощью СБ в "пять строк" написать

Но сколько я понял, что одной СБ CTrade не получится решить мою задачу?  И нужно было еще и CPositionInfo использовать? - если хочу по нескольким ТФ одновременно 9 позиций сопровождать?

ЗЫ: сижу со смарт ТВ справку MQL5 листаю - довольно неплохо описаны торговые функции, использование СБ под вопросом.... примитивные стратегии вроде имеет смысл использовать СБ, чуть сложнее - функционал недостаточен или не очевидное использование, возможно нужна практика - попробую еще "покрутить" СБ


Еще раз Спасибо!

 
fxsaber:

Причина в некомпетентности так отвечающих. Мне понадобилось пять минут на написание и одна попытка на проверку.


MT4


MT5


Чтобы это написать, не надо быть сильным разбирающимся, достаточно знать только основы MT5.


ЗЫ На неттинге маленький нюанс существует при определении типа закрытой позиции. Но здесь это не играет роли.

Вот здесь

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

кроется потенциальная ошибка.

В историческом списке ордера не расположены в порядке их появления в этом списке. Сталкивался с этим при разработке библиотеки. Положился как раз на это. Но оказалось, что всё не так просто. Попробуйте выставить поочерёдно лимитные и стоповые ордера в порядке: лимит -> стоп -> лимит -> стоп -> лимит -> стоп, и удаляя каждый в любом порядке, смотрите который записан в историческом списке последним. Будете удивлены.

 
Artyom Trishkin:

Вот здесь

кроется потенциальная ошибка.

В историческом списке ордера не расположены в порядке их появления в этом списке. Сталкивался с этим при разработке библиотеки. Положился как раз на это. Но оказалось, что всё не так просто. Попробуйте выставить поочерёдно лимитные и стоповые ордера в порядке: лимит -> стоп -> лимит -> стоп -> лимит -> стоп, и удаляя каждый в любом порядке, смотрите который записан в историческом списке последним. Будете удивлены.

Там нет ошибки, т.к. список сформирован через HistorySelectByPosition.

Причина обращения: