English 中文 Español Deutsch 日本語 Português
preview
Выставление ордеров в MQL5

Выставление ордеров в MQL5

MetaTrader 5Трейдинг | 12 января 2024, 15:27
1 573 2
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Введение

В любой торговой системе нам приходится иметь дело с ордерами, такими как открытие позиций, установка стоп-лосса и тейк-профита, а также изменение ордеров. Поэтому очень важно понимать, как обрабатывать операции с ордерами в MQL5 при создании торговой системы для MetaTrader5. Цель этой статьи — предоставить простое руководство по большинству операций с ордерами и позициями. Рассмотрены следующие темы:

Надеюсь, статья поможет вам в бесперебойной разработке вашей торговой системы MetaTrader 5 в отношении размещения ордеров. Тестируйте все приложения, приведенные в этой статье, чтобы убедиться, что они прибыльны и подходят вашему стилю торговли. Их основная цель — привести пример создания торговой системы с использованием двух разных методов работы с ордерами, сделками и позициями.

Внимание! Все содержание настоящей статьи предоставляется "как есть", предназначено только для целей обучения и не является торговой рекомендацией. Статья не несет в себе каких-либо гарантий результатов. Все, что вы применяете на практике на основе этой статьи, вы делаете исключительно на свой страх и риск, автор не гарантирует никаких результатов.

Ордера, позиции и сделки

В этой части мы поговорим о важных терминах, чтобы понять, как эффективно работать с ордерами. Также мы рассмотрим разницу между тремя понятиями, связанными с ордерами в MetaTrader 5. Это ордер, сделка и позиция. Мы можем рассматривать эти термины как шаги совершения сделки.

Ордер - запрос, полученный торговым сервером, на открытие сделки на покупку или продажу с определенным лотом или объемом по определенной цене. Есть два типа ордеров: рыночный и отложенный.

  • Рыночный ордер может быть исполнен немедленно по текущей рыночной цене.
  • Отложенный ордер исполняется при заранее определенных цене и времени. 

Отложенные ордера в свою очередь бывают следующих типов:

    • Buy stop - отложенный ордер на покупку по определенной цене, которая выше текущей цены на рынке.
    • Buy limit - отложенный ордер на покупку по определенной цене, которая ниже текущей цены на рынке.
    • Sell stop - отложенный ордер на продажу по определенной цене, которая ниже текущей цены на рынке.
    • Sell limit - отложенный ордер на продажу по определенной цене, которая выше текущей цены на рынке.

После размещения ордера, независимо от того, является ли он рыночным или отложенным, его можно найти на вкладке "Торговля" панели инструментов в MetaTrader 5. Ниже приведен пример:

1. Вкладка "Торговля"


При закрытии или отмене ордера без исполнения его можно найти на вкладке "История" в окне "Инструменты".

2. Вкладка "История"

Модификацию открытых ордеров рассмотрим ниже.

Сделка - результат исполнения торгового ордера. Это действия входа на рынок/выхода с рынка. Допустим, исполнен ордер на покупку одного лота. После этого мы закрыли часть позиции в 0,5 лота, затем закрыли оставшиеся 0,5 лота. Последовательность сделок будет следующей:

  • вход на 1 лот
  • продажа 0.5 лота
  • продажа 0.5 лота

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

3. Сделки

Позиция - последовательность длинных или коротких сделок покупки или продажи финансового актива. Мы можем найти активные позиции на вкладке "Торговля" либо на вкладке "История", если выберем отображение позиций.

4. Позиции

Исполняемой ценой ордера на покупку является цена Ask, а исполняемой ценой при закрытии является цена Bid. С другой стороны, исполняемая цена ордера на продажу — это цена Bid, а исполняемая цена при закрытии — цена Ask.

OrderSend()

После рассмотрения важных терминов, касающихся исполнения сделок в MetaTrader 5, узнаем, как автоматически исполнять ордера в MQL5. Вы можете ознакомиться с разделом "Торговые функции" в справке MQL5.

Мы рассмотрим функцию OrderSend(), которую можно использовать для выполнения торговых операций путем отправки запросов на торговый сервер. Другими словами, ее можно использовать для размещения, изменения и закрытия ордеров.

Ниже приведен формат этой функции:

bool  OrderSend(
   MqlTradeRequest&  request,      
   MqlTradeResult&   result        
   );

Как видим, функция имеет два параметра:

  • Структура MqlTradeRequest содержит параметры ордера и все необходимые поля или переменные для совершения торговых сделок. Объекты передаются по ссылке, согласно амперсандам. TradeRequest - метод взаимодействия клиентского терминала и торгового сервера для исполнения ордеров.
  • Структура MqlTradeResult: TradeResult возвращает результаты запроса ордера. Объекты также передаются по ссылке.

Структура MqlTradeRequest:

Структура представляет собой набор связанных данных разных типов. Определение структуры MqlTradeRequest выглядит так:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type
   ulong                         magic;            // Expert Advisor ID (magic number)
   ulong                         order;            // Order ticket
   string                        symbol;           // Trade symbol
   double                        volume;           // Requested volume for a deal in lots
   double                        price;            // Price
   double                        stoplimit;        // StopLimit level of the order
   double                        sl;               // Stop Loss level of the order
   double                        tp;               // Take Profit level of the order
   ulong                         deviation;        // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // The ticket of an opposite position
  };

Мы можем объявить объект MqlTradeRequest с помощью следующей строки кода:

MqlTradeRequest request;

Затем мы можем присвоить параметры торговли переменным созданного объекта запроса, добавив точку (.) после объекта, как показано в следующем примере:

request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;

Ниже приведен список всех членов или переменных структуры MqlTradeRequest, а также их допустимые значения для назначения.

Переменная Описание Принятое значение для назначения
action Тип торговой операции

Один из ENUM_TRADE_REQUEST_ACTIONS (TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY)

magic ID советника для идентификации ордеров, размещенных определенным советником Любое значение ulong
order Тикет ордера. Необходим при использовании TRADE_ACTION_MODIFY или TRADE_ACTION_REMOVE в переменной действия.  Любое значение ulong
symbol Указанный символ или инструмент для торговли. (_SYMBOL) относится к текущему Любой строковый символ
volume Торговый объем или лоты  Любое разрешенное значение double
price Цена открытия Значение double
stoplimit Цена открытия лимитного отложенного ордера. Действие должно быть TRADE_ACTION_PENDING, а переменная типа должна быть ORDER_TYPE_BUY_STOP_LIMIT или ORDER_TYPE_SELL_STOP_LIMIT. Переменная необходима для стоп-лимитных ордеров Значение double
sl Цена стоп-лосса сделки Значение double
tp Цена тейк-профита сделки Значение double
deviation Максимальное отклонение цены в пунктах Значение ulong
type Тип ордера Один из ENUM_ORDER_TYPE (ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, 
ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT,  ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT)
type_filling Тип или политика исполнения ордера Один из ENUM_ORDER_TYPE_FILLING (ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN)
type_time Тип истечения отложенного ордера Один из ENUM_ORDER_TYPE_TIME (ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY)
expiration Время истечения отложенного ордера. Необходимо, если type_time равен ORDER_TIME_SPECIFIED Значение datetime
comment Комментарий к ордеру Значение string
position Тикет позиции. Требуется при изменении или закрытии позиции для ее идентификации. Значение ulong
position_by Тикет противоположной позиции. Используется при закрытии позиции противоположной по тому же символу. Значение ulong

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

  • Рыночный ордер
  • Добавление стоп-лосса и тейк-профита
  • Отложенный ордер
  • Изменение отложенного ордера
  • Удаление отложенного ордера

Рыночный ордер:

В этом типе действия нам нужно разместить рыночный ордер, что означает, что ордер будет размещен по текущей рыночной цене. Мы будем использовать действие (TRADE_ACTION_DEAL). Если это ордер на покупку, он будет размещен по текущей цене Ask, а если ордер на продажу, - по текущей цене Bid. Вот как это сделать: 

После объявления объектов MqlTradeRequest и MqlTradeResult присвоим следующие значения необходимым переменным:

request.action = TRADE_ACTION_DEAL;                    &nbsthe p;   //market order palcement
request.type = ORDER_TYPE_BUY;                             //type of order is buy
request.symbol = _Symbol;                                  //applied for the cuurrent symbol
request.volume = 0.1;                                      //the lot size
request.type_filling = ORDER_FILLING_FOK;                  //the filling policy fill or kill
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);      //the price is the current ask for buy
request.sl = 0;                                            //stop loss is 0
request.tp = 0;                                            //take profit is 0
request.deviation = 50;                                    //slippage is 50
OrderSend(request, result);                                //calling the OrderSend function

Как видим, мы не добавляли значения стоп-лосса и тейк-профита. Мы можем добавить их значения в код вместе с другими переменными или добавить их с помощью другого действия, как показано в следующем разделе.

Добавляем стоп-лосс и тейк-профит:

Когда нам нужно добавить стоп-лосс и тейк-профит, мы назначаем TRADE_ACTION_SLTP к переменной action, как показано в следующем примере.

request.action = TRADE_ACTION_SLTP;          //adding sl and tp
request.symbol = _Symbol;                    //applied for the cuurrent symbol
request.sl = 1.07000;                        //sl price
request.sl = 1.09000;                        //tp price
OrderSend(request, result);                  //calling the OrderSend function


Отложенный ордер:

Если мы хотим разместить отложенный ордер, мы можем использовать другое действие (TRADE_ACTION_PENDING). Затем определяем тип ордера. Мы можем установить время, если нам нужно время истечения отложенного ордера.

request.action = TRADE_ACTION_PENDING;          //pending order placement
request.type = ORDER_TYPE_BUY_STOP;             //type of order is buy stop
request.symbol = _Symbol;                       //applied for the cuurrent symbol
request.volume = 0.1;                           //the lot size
request.price = 1.07000;                        //opening price
request.sl = 1.06950;                           //stop loss
request.tp = 1.07100;                           //take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.08.31 00.00';       //expiration time - datetime constant          
request.type_filling = ORDER_FILLING_FOK;       //the filling policy fill or kill
request.stoplimit = 0;                          //for stoplimit order only
OrderSend(request, result);                     //calling the OrderSend function


Изменение отложенного ордера:

При изменении отложенного ордера нам нужно получить номер его тикета. Для этого мы можем использовать функцию OrderGetTicket. Эта функция возвращает тикет соответствующего ордера, по которому мы можем выбрать ордер и работать с ним.

ulong  OrderGetTicket( 
   int  index      // Number in the list of orders 
   );

Допустим, у нас есть переменная (ticket), содержащая тикет ордера. Мы можем использовать эту переменную, чтобы присвоить тикет ордера переменной ордера объекта запроса. Затем мы можем изменить ордер, используя действие (TRADE_ACTION_MODIFY), как в следующем примере.

request.action = TRADE_ACTION_MODIFY;           //pending order modyfying
request.order = ticket;                         //ticket variable that holds the pending order ticket to modify
request.price = 1.07050;                        //new opening price
request.sl = 1.07000;                           //new stop loss
request.tp = 1.07150;                           //new take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.09.01 00.00';       //new expiration time - datetime constant        
OrderSend(request, result);                     //calling the OrderSend function

Удаление отложенного ордера:

Если нам нужно удалить отложенный ордер, мы можем сделать это с помощью действия (TRADE_ACTION_REMOVE). Нам также понадобится номер тикета отложенного ордера, который нам нужно удалить. Мы можем использовать тикет переменной с расчетом, что он содержит необходимый номер тикета.

request.action = TRADE_ACTION_REMOVE;           //pending order remove
request.order = ticket;                         //ticket variable that holds the pending order ticket to remove
OrderSend(request, result);                     //calling the OrderSend function

Структура MqlTradeResult:

Структура MqlTradeResult возвращает результат успешности ордера после его размещения функцией OrderSend(). Он содержит информацию с торгового сервера, такую как номер тикета, объем и цена.

Ниже приведено определение структуры MqlTradeResult:

struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by description of trade server return code)
   uint     request_id;       // Request ID set by the terminal during the dispatch 
   int      retcode_external; // Return code of an external trading system
  };

Мы можем объявить объект с именем result и передать его в качестве второго параметра после первого (request) при вызове функции OrderSend().

MqlTradeResult result;

Как мы видим из переменных структуры MqlTradeResult, переменная retcode очень важна, поскольку она возвращает код с торгового сервера, чтобы указать, был ли запрос успешным.

Если сделка не размещена, код возврата указывает на ошибку. Вы можете изучить список кодов возврата в справочника MQL5. Крайне важно включить в нашу торговую систему код, сообщающий о том, возвращается ошибка или нет, как показано в следующем примере:

   if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
     {
      Print("Trade Placed Successfully");
     }
   else
     {
      Print("Trade Not Placed, Error ", result.retcode);
     }

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

Применение OrderSend()

Нам нужно создать простую торговую систему, которая сможет совершать сделки с помощью функции OrderSend(). Торговая система представляет собой простое пересечение скользящих средних, и действие заключается только в размещении рыночного ордера.

Цель в данном случае — понять различия при создании одной и той же торговой системы с использованием OrderSend() и класса CTrade. Ниже приведены шаги по созданию пересечения MA с помощью функции OrderSend().

В глобальной области создадим две целочисленные переменные (simpleMA, barTotal) без присвоения. Присвоение будет сделано позже - в OnInit.

int simpleMA;
int barsTotal;

SimpleMA будет назначена функции iMA, которая возвращает хэндл технического индикатора скользящего среднего. Параметры такие:

  • symbol - имя символа, _Symbol относится к текущему инструменту.
  • period - таймфрейм. Мы будем использовать PERIOD_H1 - часовой таймфрейм.
  • ma_period - период скользящей средней. Используем 50.
  • ma_shift - сдвиг по горизонтали.
  • ma_method - тип скользящей средней. Укажем простую.
  • applied_price - тип цены для расчета скользящей средней. Будем использовать цену закрытия.

BarsTotal будет присвоен функции iBars, которая возвращает количество баров. Параметры:

  • symbol - имя символа
  • timeframe - период таймфрейма
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);

В OnTick() создадим два массива: один - для цен с использованием MqlRates для хранения информации о ценах, объемах и спреде, а другой — для скользящей средней с типом переменной double

   MqlRates priceArray[];
   double mySMAArray[];

Определение цен спроса и предложения

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Создадим два объекта для функции OrderSend(): один - для request с использованием MqlTradeReuest, а другой - для result с использованием MqlTradeResult, а затем сбросим переменную request по ссылке.

ZeroMemory(request);

Установка флага AS_SERIES для двух созданных массивов priceArray и mySMAArray с помощью функции ArraySetAsSeries. Параметры:

  • array[] - необходимый массив
  • flag - направление индексации массива.
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Получение исторических данных MqlRates с помощью функции CopyRates. Параметры:

  • symbol - имя символа или _Symbol для текущего символа или инструмента.
  • time frame - период таймфрейма или _period для текущего таймфрейма.
  • start position - стартовая позиция.
  • count - объем данных для копирования.
  • rates_array - целевой массив для копирования.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Получение буфера данных индикатора с помощью функции CopyBuffer. Параметры:

  • indicator_handle - хэндл индикатора (MA).
  • buffer_num - номер индикаторного буфера.
  • start_pos - позиция начала расчета.
  • count - объем для копирования.
  • buffer[] - целевой массив.
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Определение последней, предыдущей цены закрытия, последнего и предыдущего значений SMA

   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Создадим целочисленную переменную bar и присвоим ее iBars.

int bars=iBars(_Symbol,PERIOD_H1);

Проверим равенство barsTotal и переменной bars

if(barsTotal != bars)

Обновим значение barsTotal, чтобы оно было равно bars, если они не равны друг другу

barsTotal=bars;

Проверим условие стратегии на открытие сделки: превышает ли последнее закрытие последнее значение SMA после того, как предыдущее закрытие было меньше предыдущего значения SMA

if(prevClose<prevSMAVal && lastClose>SMAVal)

Откроем рыночный ордер на покупку с использованием подходящих переменных, связанных с функцией MqlTradeRequest.

         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Проверим условие стратегии на открытие сделки на продажу: меньше ли последнее закрытие последнего значения SMA после того, как предыдущее закрытие было больше предыдущего значения SMA

if(prevClose>prevSMAVal && lastClose<SMAVal)
Откроем рыночный ордер на продажу с использованием подходящих переменных, связанных с функцией MqlTradeRequest.
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Ниже приведен полный код создания этого типа торговой системы с помощью функции OrderSend().

//+------------------------------------------------------------------+
//|                                     OrderSend_Trading_system.mq5 |
//+------------------------------------------------------------------+
int simpleMA;
int barsTotal;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
     }
  }

Класс CTrade

Мы изучили, как размещать ордера с помощью функции OrderSend() и получили простой способ доступа к торговым функциям. Мы можем использовать готовый класс CTrade, предоставляемый MQL5, или создать собственный. Как можно использовать готовый класс CTrade в MQL5? Дополнительную информацию можно найти в разделе CTrade справочника MQL5.

Во-первых, мы можем найти подключаемый файл класса CTrade в папке Trade папки include установочных файлов MetaTrader 5. Все, что нам нужно, это включить этот файл в советник для вызова и использования всех торговых функций, как указано ниже:

#include <Trade\Trade.mqh>

Создайте объект из класса CTrade.

CTrade trade;

После этого мы сможем использовать все торговые функции в классе CTrade, используя trade перед точкой (.) и желаемой функцией. Мы можем использовать все функции операций с ордерами и позициями, доступ к параметрам последнего запроса, результатам проверки и выполнения последнего запроса и другие.

Мы упомянем некоторые важные функции так же, как и в случае с OrderSend(), чтобы понять различия между двумя методами. Разберемся, как сделать следующее:

  • Рыночный ордер
  • Добавление стоп-лосса и тейк-профита
  • Отложенный ордер
  • Изменение отложенного ордера
  • Удаление отложенного ордера

Рыночный ордер:

После создания нашего торгового объекта мы можем использовать функцию PositionOpen для размещения рыночного ордера. Ее параметры:

  • symbol - необходимый символ
  • order_type - тип ордера для открытия позиции
  • volume - размер лота
  • price - цена открытия позиции
  • sl - цена стоп-лосса
  • tp - цена тейк-профита
  • comment - комментарий или NULL

Ниже приведен пример:

trade.PositionOpen(
   _Symbol,             //to be applied for the current symbol
   ORDER_TYPE_BUY,      //to place buy order
   0.1,                 //lot size or volume
   Ask,                 //opening price of the order - current ask
   Ask-(500*_Point),    //sl
   Ask+(1000*_Point),   //tp
   NULL                 //NULL
);

Чтобы открыть рыночный ордер, мы также можем использовать дополнительные методы в CTrade, например Buy или Sell, вместо PositionOpen.

Добавляем стоп-лосс и тейк-профит:

Мы можем изменить позицию по символу или номеру тикета, используя функцию PositionModify. Параметры:

  • symbol or ticket - при изменении позиции по символу, указываем символ, при изменении по тикету указываем номер тикета.
  • sl - новая цена стоп-лосса
  • tp - цена тейк-профита

Пример изменения по символу:

trade.PositionModify(
   EURUSD,       //the symbol name
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Пример изменения по тикету:

trade.PositionModify(
   ticket,       //the ticket variable that holds the needed ticket number to modify
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Отложенный ордер:

Если нам нужно разместить отложенный ордер, используя класс CTrade, мы можем использовать функцию OrderOpen. Параметры:

  • symbol - имя символа
  • order_type - тип отложенного ордера
  • volume - размер лота
  • limit_price - цена stop limit
  • price - цена исполнения отложенного ордера
  • sl - стоп-лосс
  • tp - тейк-профит
  • type_time - тип по истечению
  • expiration - переменная даты и времени истечения
  • comment - комментарий

В следующем примере показано размещение отложенного ордера на покупку с использованием функции OrderOpen.

         trade.OrderOpen(
            "EURUSD",                 // symbol
            ORDER_TYPE_BUY_LIMIT,     // order type
            0.1,                      // order volume
            0,                        // StopLimit price
            1.07000,                  // execution price
            1.06950,                  // Stop Loss price
            1.07100,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            ""                        // comment
         );

Изменение отложенного ордера:

Если нам нужно изменить размещенный отложенный ордер, мы можем сделать это, используя класс CTrade с помощью функции OrderModify. Параметры:

  • ticket - тикет отложенного ордера, который необходимо изменить
  • price - новая цена исполнения
  • sl - новая цена стоп-лосса
  • tp - новая цена тейк-профита
  • type_time - тип по истечению
  • expiration - переменная даты и времени истечения
  • stoplimit - цена лимитного ордера

Ниже приведен пример изменения отложенного ордера

         trade.OrderModify(
            ticket,                   // ticket number of the pending order to modify
            1.07050,                  // execution price
            1.07000,                  // Stop Loss price
            1.07150,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            0,                        // StopLimit price
         );

Удаление отложенного ордера:

Если вам нужно удалить отложенный ордер, вы можете сделать это с помощью функции OrderDelete. Для удаления требуется номер тикета отложенного ордера. Ниже приведен пример этой функции.

         trade.OrderDelete(
            ticket,                 // tick number of the pending order to delete
         );

Применение класса CTrade

Создадим ту же торговую систему, которую мы создали с помощью OrderSend(). Мы будем использовать класс CTrade, чтобы понять различия в работе функций.

Ниже приведены единственные различающиеся шаги по созданию торговой системы с использованием класса CTrade. Остальные шаги совпадают с рассмотренными выше.

Подключаем файл Trade с помощью препроцессора #include

#include <Trade\Trade.mqh>

Создадим торговый объект из класса CTrade.

CTrade trade;

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

trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);

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

trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);

Ниже приведен полный код для создания торговой системы с использованием класса CTrade:

//+------------------------------------------------------------------+
//|                                        CTrade_Trading_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
int simpleMA;
int barsTotal;
CTrade trade;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
        }
     }
  }

Заключение

Мы рассмотрели, как работают ордера, позиции и сделки в MQL5, а также увидели, как создать торговую систему, используя два метода торговых операций - OrderSend и CTrade.

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

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

  • OpenSend_Trading_System
  • CTrade_Trading_System

Целью упомянутых приложений является только практическое понимание различий между ними, поэтому будьте осторожны: вы должны протестировать их перед использованием на любом реальном счете, чтобы убедиться, что они прибыльны и подходят для вашей торговли.

Я полагаю, что вы оценили простоту использования готового класса CTrade при работе с торговыми операциями. Он позволяет сэкономить много времени и сил, не считая других возможностей классов в программировании в целом.

Если вы хотите узнать больше об объектно-ориентированном программировании на MQL5, вы можете прочитать мою предыдущую статью "Объектно-ориентированное программирование (ООП) в MQL5". Надеюсь, она будет для вас полезной. MQL5 предоставляет необходимые инструменты для простой и эффективной разработки и создания торговых приложений.

Надеюсь, статья будет для вас полезной и поможет вам в достижении торговых целей. В разделе "Статьи" моего профиля вы можете найти серию статей о создании торговых систем на основе самых популярных технических индикаторов. Надеюсь, они также окажутся полезными.

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/13229

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (2)
rurubest
rurubest | 8 апр. 2024 в 12:45
здравствуйте! 
По вашему коду пишу простое выставление заявки по инструменту! 


double price = 94500;

   double stopLoss = price - (500 * _Point);

    double takeProfit = price + (1000 * _Point);


    ulong ticket = trade.OrderOpen(

"SiM4",                 // symbol

            ORDER_TYPE_BUY,     // order type
            1.0,                      // order volume
            price,                        // StopLimit price
            stopLoss,                  // execution price
            takeProfit,                  // Stop Loss price
            NULL  
         );
возвращает значение GetLastError() = 0 и заявка не выставляется и сделки тоже нет
Надо ли при выставлении заявки от брокера какой то специальный токен доступа прописывать?

Rashid Umarov
Rashid Umarov | 8 апр. 2024 в 13:12
rurubest #:
возвращает значение GetLastError() = 0 и заявка не выставляется и сделки тоже нет
Надо ли при выставлении заявки от брокера какой то специальный токен доступа прописывать?
Посотрите логи и анализируйте результат выполнения OrderSend. 
Популяционные алгоритмы оптимизации: Алгоритмы искусственной микро-иммунной системы (Micro Artificial immune system, Micro-AIS) Популяционные алгоритмы оптимизации: Алгоритмы искусственной микро-иммунной системы (Micro Artificial immune system, Micro-AIS)
Статья рассказывает о методе оптимизации, основанном на принципах функционирования иммунной системы организма — Micro Artificial Immune System (Micro-AIS) — модификацию AIS. Micro-AIS использует более простую модель иммунной системы и простые операции обработки иммунной информации. Статья также обсуждает преимущества и недостатки Micro-AIS по сравнению с обычным AIS.
Нейросети — это просто (Часть 72): Прогнозирование траекторий в условиях наличия шума Нейросети — это просто (Часть 72): Прогнозирование траекторий в условиях наличия шума
Качество прогнозирование будущих состояний играет важную роль в метода Goal-Conditioned Predictive Coding, с которым мы познакомились в предыдущей статье. В данной статье я хочу познакомить Вас с алгоритмом, способным значительно повысить качество прогнозирования в стохастических средах, к которым можно отнести и финансовые рынки.
Теория категорий в MQL5 (Часть 19): Индукция квадрата естественности Теория категорий в MQL5 (Часть 19): Индукция квадрата естественности
Мы продолжаем рассмотрение естественных преобразований, рассматривая квадратичную индукцию естественности. Небольшие ограничения на реализацию мультивалютности для экспертов, собранных с помощью мастера MQL5, означают, что мы демонстрируем свои возможности по классификации данных с помощью скрипта. В качестве основных областей применения рассматриваются классификация изменений цен и, соответственно, их прогнозирование.
Создаем алгоритм маркет-мейкинга на MQL5 Создаем алгоритм маркет-мейкинга на MQL5
Как работают маркет-мейкеры на рынке? Рассмотрим этот вопрос и создадим примитивный алгоритм маркет-мейкинга.