Выставление ордеров в MQL5
Введение
В любой торговой системе нам приходится иметь дело с ордерами, такими как открытие позиций, установка стоп-лосса и тейк-профита, а также изменение ордеров. Поэтому очень важно понимать, как обрабатывать операции с ордерами в MQL5 при создании торговой системы для MetaTrader5. Цель этой статьи — предоставить простое руководство по большинству операций с ордерами и позициями. Рассмотрены следующие темы:
- Ордера, позиции и сделки
- OrderSend()
- Применение OrderSend()
- Класс CTrade
- Применение класса CTrade
- Заключение
Надеюсь, статья поможет вам в бесперебойной разработке вашей торговой системы MetaTrader 5 в отношении размещения ордеров. Тестируйте все приложения, приведенные в этой статье, чтобы убедиться, что они прибыльны и подходят вашему стилю торговли. Их основная цель — привести пример создания торговой системы с использованием двух разных методов работы с ордерами, сделками и позициями.
Ордера, позиции и сделки
В этой части мы поговорим о важных терминах, чтобы понять, как эффективно работать с ордерами. Также мы рассмотрим разницу между тремя понятиями, связанными с ордерами в MetaTrader 5. Это ордер, сделка и позиция. Мы можем рассматривать эти термины как шаги совершения сделки.
Ордер - запрос, полученный торговым сервером, на открытие сделки на покупку или продажу с определенным лотом или объемом по определенной цене. Есть два типа ордеров: рыночный и отложенный.
- Рыночный ордер может быть исполнен немедленно по текущей рыночной цене.
- Отложенный ордер исполняется при заранее определенных цене и времени.
Отложенные ордера в свою очередь бывают следующих типов:
- Buy stop - отложенный ордер на покупку по определенной цене, которая выше текущей цены на рынке.
- Buy limit - отложенный ордер на покупку по определенной цене, которая ниже текущей цены на рынке.
- Sell stop - отложенный ордер на продажу по определенной цене, которая ниже текущей цены на рынке.
- Sell limit - отложенный ордер на продажу по определенной цене, которая выше текущей цены на рынке.
После размещения ордера, независимо от того, является ли он рыночным или отложенным, его можно найти на вкладке "Торговля" панели инструментов в MetaTrader 5. Ниже приведен пример:
При закрытии или отмене ордера без исполнения его можно найти на вкладке "История" в окне "Инструменты".
Модификацию открытых ордеров рассмотрим ниже.
Сделка - результат исполнения торгового ордера. Это действия входа на рынок/выхода с рынка. Допустим, исполнен ордер на покупку одного лота. После этого мы закрыли часть позиции в 0,5 лота, затем закрыли оставшиеся 0,5 лота. Последовательность сделок будет следующей:
- вход на 1 лот
- продажа 0.5 лота
- продажа 0.5 лота
Мы можем отобразить сделки, щелкнув правой кнопкой мыши на вкладке "История" окна "Инструменты" и выбрав "Сделки".
Позиция - последовательность длинных или коротких сделок покупки или продажи финансового актива. Мы можем найти активные позиции на вкладке "Торговля" либо на вкладке "История", если выберем отображение позиций.
Исполняемой ценой ордера на покупку является цена 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
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
По вашему коду пишу простое выставление заявки по инструменту!
double price = 94500;
double stopLoss = price - (500 * _Point);
double takeProfit = price + (1000 * _Point);
ulong ticket = trade.OrderOpen(
"SiM4", // symbol
возвращает значение GetLastError() = 0 и заявка не выставляется и сделки тоже нет
Надо ли при выставлении заявки от брокера какой то специальный токен доступа прописывать?
возвращает значение GetLastError() = 0 и заявка не выставляется и сделки тоже нет
Надо ли при выставлении заявки от брокера какой то специальный токен доступа прописывать?