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

 
Vitalie Postolache:
Чудес не бывает. Раз магики разные, то и позиции различать советникик должны. Код будет?

Первый (тестовый, именно для совместного эксперимента):

  

#include <Trade\Trade.mqh>

CTrade  trade;

int OnInit()
  {
   trade.SetAsyncMode(true);
   trade.SetExpertMagicNumber(111);
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {

   if (PositionsTotal()==0)
   {
      trade.Buy(1);
   }
  
  }

  

Второй (такой же, с другим магиком):

 

#include <Trade\Trade.mqh>

CTrade  trade;

int OnInit()
  {
   trade.SetAsyncMode(true);
   trade.SetExpertMagicNumber(222);
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {

   if (PositionsTotal()==0)
   {
      trade.Buy(1);
   }
  
  }

 

Причем, как только позицию закрываю вручную, советники моментально видят это и открывают новые - одновременно. Если один открылся, пока второй не активен - второй уже не открывается.

 
dimnik:

На одном инструменте в разных окнах должно работать несколько советников. 

Можно ли как-то сделать так, чтобы PositionsTotal() считал только свои позиции? А то как только один советник открывает позицию, другие тоже считают, что уже в позиции.

MagicNumber поставил разные, не помогает.

Пример советника, который перебирает все позиции и закрывает только СВОИ - только по своему символу и своему Magic:

//+------------------------------------------------------------------+
//|                                                     CloseALL.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
CTrade         m_trade;                      // trading object
CPositionInfo  m_position;                   // trade position object
//--- input parameter
input ulong    m_magic=159753698;            // magic number
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   CloseAll();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Close All                                                        |
//+------------------------------------------------------------------+
void CloseAll()
  {
   Print(__FUNCTION__);
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
            m_trade.PositionClose(m_position.Ticket());
  }
//+------------------------------------------------------------------+


Добавлено: я надеюсь Вы работает на торговом счетё hedge???

 
dimnik:

  Причем, как только позицию закрываю вручную, советники моментально открывают новую. 

А, ну так конечно же, PositionsTotal не различает позиции по магику или ещё как-то, она выдаёт общее их количество на счёте. Надо в цикле перебирать позиции от 0 до PositionsTotal()-1, смотреть магик и считать.

О, пока писал, уже и показали как именно надо (:
 
dimnik:

На одном инструменте в разных окнах должно работать несколько советников. 

Можно ли как-то сделать так, чтобы PositionsTotal() считал только свои позиции? А то как только один советник открывает позицию, другие тоже считают, что уже в позиции.

MagicNumber поставил разные, не помогает.

PositionsTotal() никак не фильтрует по магикам. Для этого надо перебирая позиции считать только "свои" своей функцией.
 


Добавлено: я надеюсь Вы работает на торговом счетё hedge???

Нет, не Hedge. Значит, PositionTotal() не сможет учитывать только свои позиции?

А класс CTrade в таком случае сможет учитывать свои позиции отдельно от других?

 
dimnik:

Нет, не Hedge. Значит, PositionTotal() не сможет учитывать только свои позиции?

А класс CTrade в таком случае сможет учитывать свои позиции отдельно от других?

На неттинге по каждому символу может быть НЕ БОЛЕЕ ОДНОЙ позиции. При этом в отношении Magic действует правило

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

Magic number

Vladimir Karputov, 2016.12.25 12:38

На netting кто последний того и тапки - то есть magic у позиции будет такой, какой был у последней сделки по этому инструменту.. 

Проверяем:

//+------------------------------------------------------------------+
//|                                             ReplacementMagic.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Что происходит с magic на netting"
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      Print("Этот пример только для netting!");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   static int counter=-10;
   if(counter%300==0)
     {
      //--- генерируем Magic
      ulong m_magic=MathRand();
      Print("new Magic: ",IntegerToString(m_magic));
      //--- устанавливаем новый Magic
      m_trade.SetExpertMagicNumber(m_magic);
      //--- определим лот
      double lots=0.0;
      if(MathRand()%2==0)
         lots=0.01;
      else
         lots=0.02;

      //--- определяем, что открывать: Buy или Sell
      if(MathRand()%2==0) // значит Buy
        {
         m_trade.Buy(lots);
        }
      else // значит Sell
        {
         m_trade.Sell(lots);
        }
     }
   counter++;
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
         if(m_position.SelectByIndex(i))
            if(m_position.Symbol()==Symbol())
              {
               //string text=ChartGetString(0,CHART_COMMENT)+"\n"+
               //            "Magic: "+IntegerToString(m_position.Magic());
               //Comment(text);
               Print("Обнаружена позиция с Magic: "+IntegerToString(m_position.Magic()));
              }
     }
  }
//+------------------------------------------------------------------+


 


Файлы:
 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL4 MT4 MetaTrader 4".
 
Подскажите, как узнать результат последней одной или нескольких сделок?
 
dimnik:
Подскажите, как узнать результат последней одной или нескольких сделок?

Есть два пути:

прямо в советнике использовать OnTradeTransaction() и отлавливать сделки, которые были записаны в историю.

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_profit       =0.0;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
        }
      else
         return;
      if(deal_symbol==Symbol() && deal_magic==m_magic)
         if(deal_entry==DEAL_ENTRY_OUT)
           {
            // здесь ваши действия
           }
     }
  }

или обращаться к торговой истории, например что-то вроде этого:

//+------------------------------------------------------------------+
//|                                               HistorySelect.mq5  |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Реверс позиции и исследование \"DEAL_POSITION_ID\" истории сделок"
#property script_show_inputs
//---
input datetime start=D'2016.08.05 09:00:00';
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      Print("This script cannot be run on a hedge; Этот скрипт нельзя запускать на хедж");
      return;
     }
   Print_IDs();
  }
//+------------------------------------------------------------------+
//| List all positions and deals                                     |
//+------------------------------------------------------------------+
void Print_IDs(void)
  {
//--- запрашиваем историю сделок и ордеров за указанный период серверного времени
   HistorySelect(start,TimeCurrent()+86400);
   uint     total    =HistoryDealsTotal();   // количество сделок в истории
   ulong    ticket   =0;                     // тикет сделки в истории
   long     type     =0;                     // тип сделки
   long     deal_id=0;   // идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
   double   volume   =0.0;                   // объём сделки
   double   profit   =0.0;                   // финансовый результат сделки
   double   price    =0.0;                   // цена сделки
   string   symbol   =NULL;                  // имя символа, по которому произведена сделка
   long     entry    =0;                     // направление сделки – вход в рынок, выход из рынка или разворот
//--- for all deals
   for(uint i=0;i<total;i++)
     {
      //--- try to get deals ticket
      if((ticket=HistoryDealGetTicket(i))>0)
        {
         //--- get deals properties
         type     =HistoryDealGetInteger(ticket,DEAL_TYPE);
         deal_id  =HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
         volume   =HistoryDealGetDouble(ticket,DEAL_VOLUME);
         profit   =HistoryDealGetDouble(ticket,DEAL_PROFIT);
         price    =HistoryDealGetDouble(ticket,DEAL_PRICE);
         symbol   =HistoryDealGetString(ticket,DEAL_SYMBOL);
         entry    =HistoryDealGetInteger(ticket,DEAL_ENTRY);
         Print(EnumToString((ENUM_DEAL_ENTRY)entry),
               ", type ",EnumToString((ENUM_DEAL_TYPE)type),
               ", price ",DoubleToString(price,Digits()),
               ", Deal ",symbol," volume ",DoubleToString(volume,2),
               ", DEAL_POSITION_ID #",deal_id,
               ", profit ",DoubleToString(profit,2));
        }
     }
   Print("");
  }
//+------------------------------------------------------------------+


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

Файлы:
 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

Обработчик события отслеживает все сделки с магиками советника.

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

Как исправить? Или может по-другому сделать в принципе?