Как работает - PositionCloseBy?

 

Кто может подсказать ответ на следующий вопрос:

 

Условие для закрытия встречных ордеров, Buy и Sell - метки наличия позиций.

 Например, пусть, позиция Buy = 1 лот, позиция Sell = 2 лота.

if(Buy!=0 && Sell!=0)  m_Trade.PositionCloseBy(Sell_Ticket, Buy_Ticket);

 Выражение то работает, то нет. Почему?

Не работает в том случае, если цена открытия позиции Sell ниже цены открытия позиции Buy.

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

Вот такие вот загадочные дела :) 

 
Vjacheslav Lapaev:

Кто может подсказать ответ на следующий вопрос:

 

Условие для закрытия встречных ордеров, Buy и Sell - метки наличия позиций.

 Например, пусть, позиция Buy = 1 лот, позиция Sell = 2 лота.

if(Buy!=0 && Sell!=0)  m_Trade.PositionCloseBy(Sell_Ticket, Buy_Ticket);

1) Выражение то работает, то нет. Почему?

2) Не работает в том случае, если цена открытия позиции Sell ниже цены открытия позиции Buy.

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

Вот такие вот загадочные дела :) 

  1. Проверяете коды возврата?
  2. Специально проверочный тест (тестировать на периоде с 2016.12.19 по сегодня, символ EURUSD,D1):
//+------------------------------------------------------------------+
//|                                              PositionCloseBy.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property description "PositionCloseBy(Sell_Ticket, Buy_Ticket) когда цена Sell_Ticket ниже цены  Buy_Ticket)"
#property description "позиция Buy = 0.01 лот, позиция Sell = 0.02 лота."
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#property version   "1.00"
//---
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
bool           BuyIsOpen=false;              // false - позиция Buy ещё не открыта
bool           SellIsOpen=false;             // false - позиция Sell ещё не открыта
bool           CloseBy=false;                // false - CloseBy ещё не выполняли
ulong          BuyTicket=0;                  // тикет позиции Buy
ulong          SellTicket=0;                 // тикет позиции Sell
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   BuyTicket=0;
   SellTicket=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!BuyIsOpen)
     {
      if(iTime(0)>=D'2016.12.19 09:00:00')
        {
         if(m_trade.Buy(0.01))
           {
            if(m_trade.ResultRetcode()==TRADE_RETCODE_DONE && m_trade.ResultDeal()!=0)
              {
               BuyTicket=m_trade.ResultDeal();
               BuyIsOpen=true;
              }
           }
        }
     }
//---
   if(!SellIsOpen)
     {
      if(iTime(0)>=D'2016.12.19 11:00:00')
        {
         if(m_trade.Sell(0.02))
           {
            if(m_trade.ResultRetcode()==TRADE_RETCODE_DONE && m_trade.ResultDeal()!=0)
              {
               SellTicket=m_trade.ResultDeal();
               SellIsOpen=true;
              }
           }
        }
     }
//---
   if(BuyIsOpen && SellIsOpen && !CloseBy)
     {
      if(iTime(0)>=D'2016.12.19 13:00:00')
        {
         if(m_trade.PositionCloseBy(SellTicket,BuyTicket))
           {
            Print("PositionCloseBy -> true. Result Retcode: ",m_trade.ResultRetcode(),
                  ", description of result: ",m_trade.ResultRetcodeDescription());
            CloseBy=true;
           }
         else
           {
            Print("PositionCloseBy -> false. Result Retcode: ",m_trade.ResultRetcode(),
                  ", description of result: ",m_trade.ResultRetcodeDescription());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Get Time for specified bar index                                 |
//+------------------------------------------------------------------+
datetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   datetime Time[1];
   datetime time=0;
   int copied=CopyTime(symbol,timeframe,index,1,Time);
   if(copied>0) time=Time[0];
   return(time);
  }
//+------------------------------------------------------------------+

Результат:

15:31:08.081    Tester  EURUSD,H1: testing of Experts\MyExp\CTrade\PositionCloseBy.ex5 from 2016.12.19 00:00 to 2016.12.20 00:00 started
15:31:46.218    Trade   2016.12.19 09:00:11   price corrected from 1.04762 to 1.04753, deviation: 10 (instant buy 0.01 EURUSD at 1.04762)(1.04746 / 1.04753 / 1.04746)
15:31:46.218    Trade   2016.12.19 09:00:11   instant buy 0.01 EURUSD at 1.04753 (1.04746 / 1.04753 / 1.04746)
15:31:46.218    Trades  2016.12.19 09:00:11   deal #2 buy 0.01 EURUSD at 1.04753 done (based on order #2)
15:31:46.218    Trade   2016.12.19 09:00:11   deal performed [#2 buy 0.01 EURUSD at 1.04753]
15:31:46.218    Trade   2016.12.19 09:00:11   order performed buy 0.01 at 1.04753 [#2 buy 0.01 EURUSD at 1.04753]
15:31:46.224    PositionCloseBy (EURUSD,H1)     2016.12.19 09:00:11   CTrade::OrderSend: instant buy 0.01 EURUSD at 1.04762 [done at 1.04753]
15:32:01.445    Trade   2016.12.19 11:00:01   instant sell 0.02 EURUSD at 1.04629 (1.04629 / 1.04638 / 1.04629)
15:32:01.445    Trades  2016.12.19 11:00:01   deal #3 sell 0.02 EURUSD at 1.04629 done (based on order #3)
15:32:01.445    Trade   2016.12.19 11:00:01   deal performed [#3 sell 0.02 EURUSD at 1.04629]
15:32:01.445    Trade   2016.12.19 11:00:01   order performed sell 0.02 at 1.04629 [#3 sell 0.02 EURUSD at 1.04629]
15:32:01.445    PositionCloseBy (EURUSD,H1)     2016.12.19 11:00:01   CTrade::OrderSend: instant sell 0.02 EURUSD at 1.04629 [done at 1.04629]
15:32:42.939    Trade   2016.12.19 13:00:02   close position #3 sell 0.02 EURUSD by position #2 buy 0.01 EURUSD (1.04441 / 1.04448 / 1.04441)
15:32:42.939    Trades  2016.12.19 13:00:02   deal #4 buy 0.01 EURUSD at 1.04753 done (based on order #4)
15:32:42.939    Trades  2016.12.19 13:00:02   deal #5 sell 0.01 EURUSD at 1.04629 done (based on order #4)
15:32:42.939    PositionCloseBy (EURUSD,H1)     2016.12.19 13:00:02   CTrade::OrderSend: close position #3 by #2 [done]
15:32:44.262    PositionCloseBy (EURUSD,H1)     2016.12.19 13:00:02   PositionCloseBy -> true. Result Retcode: 10009, description of result: done


 


Файлы:
 
Vladimir Karputov:
  1. Проверяете коды возврата?
  2. Специально проверочный тест (тестировать на периоде с 2016.12.19 по сегодня, символ EURUSD,D1):
Красиво. Спасибо. Разобрался.
 
#include <Trade\Trade.mqh>
CTrade        itrade;
...
Имеем 2 позиции:
Buy:
int ticket1 = 33; (с ценой 1,30853)
Sell:
int ticket2 = 19; (с ценой 1,31096)

Почему не срабатывает ф-я: itrade.PositionCloseBy(ticket1, ticket2);

Выходит ошибка: failed close position #15 sell 1 GBPUSD_i by position #19 [Invalid order]
 
Sysmart:
#include <Trade\Trade.mqh>
CTrade        itrade;
...
Имеем 2 позиции:
Buy:
int ticket1 = 33; (с ценой 1,30853)
Sell:
int ticket2 = 19; (с ценой 1,31096)

Почему не срабатывает ф-я: itrade.PositionCloseBy(ticket1, ticket2);

Выходит ошибка: failed close position #15 sell 1 GBPUSD_i by position #19 [Invalid order]

ENUM_SYMBOL_INFO_INTEGER

SYMBOL_ORDER_MODE

Флаги разрешенных типов ордера

int


SYMBOL_ORDER_CLOSEBY

64

Разрешение на закрытие позиции с помощью встречной – то есть открытой в противоположном направлении по тому же инструменту. Свойство задается для счетов с хеджинговой системой учета  (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)


Пример:

//+------------------------------------------------------------------+
//| Функция выводит на печать разрешенные для символа типы ордеров   |
//+------------------------------------------------------------------+
void Check_SYMBOL_ORDER_MODE(string symbol)
  {
//--- получим значение свойства, описывающего разрешенные типы ордеров
   int symbol_order_mode=(int)SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE);
//--- проверка на рыночные ордера (Market Execution)
   if((SYMBOL_ORDER_MARKET&symbol_order_mode)==SYMBOL_ORDER_MARKET)
      Print(symbol+": Рыночные ордера разрешены (Buy и Sell)");
//--- проверка на ордера типа Limit
   if((SYMBOL_ORDER_LIMIT&symbol_order_mode)==SYMBOL_ORDER_LIMIT)
      Print(symbol+": Ордера Buy Limit и Sell Limit разрешены");
//--- проверка на ордера типа Stop
   if((SYMBOL_ORDER_STOP&symbol_order_mode)==SYMBOL_ORDER_STOP)
      Print(symbol+": Ордера Buy Stop и Sell Stop разрешены");
//--- проверка на ордера типа Stop Limit
   if((SYMBOL_ORDER_STOP_LIMIT&symbol_order_mode)==SYMBOL_ORDER_STOP_LIMIT)
      Print(symbol+": Ордера Buy Stop Limit и Sell Stop Limit разрешены");
//--- проверка на возможность установки ордеров Stop Loss
   if((SYMBOL_ORDER_SL&symbol_order_mode)==SYMBOL_ORDER_SL)
      Print(symbol+": Ордера Stop Loss разрешены");
//--- проверка на возможность установки ордеров Take Profit
   if((SYMBOL_ORDER_TP&symbol_order_mode)==SYMBOL_ORDER_TP)
      Print(symbol+": Ордера Take Profit разрешены");
//---
  }


пример из справки устаревший - в нём нет проверки на 

//--- проверка разрешения на закрытие позиции с помощью встречной
   if((SYMBOL_ORDER_TP&symbol_order_mode)==SYMBOL_ORDER_CLOSEBY)
      Print(symbol+": Встречное закрытие разрешено");
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Для получения текущей рыночной информации служат функции SymbolInfoInteger(), SymbolInfoDouble() и SymbolInfoString(). В качестве второго параметра этих функций допустимо передавать один из идентификаторов из перечислений ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING соответственно. Некоторые символы (как правило...
 
Не понял, я привел свою ситуацию, по ней конкретно что не так, можете сказать?
 
Sysmart:
Не понял, я привел свою ситуацию, по ней конкретно что не так, можете сказать?

Сначала (перед отсылкой приказа на встречное закрытие) проведите проверку на SYMBOL_ORDER_CLOSEBY

 
Какой смысл проверять, если и так понятно что проверку не пройдет. Причину хочу понять..
 
Sysmart:
Какой смысл проверять, если и так понятно что проверку не пройдет. Причину хочу понять..
Причина: по данному символу запрещены встречные закрытия. 
 
Т.е. по GBPUSD я не могу встречно закрывать, по EURUSD например могу, так?
 
Sysmart:
Т.е. по GBPUSD я не могу встречно закрывать, по EURUSD например могу, так?

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