Как правильно работать в MT5 с OrderSend - страница 9

 
Документация по MQL5: Программы MQL5 / Выполнение программ
Документация по MQL5: Программы MQL5 / Выполнение программ
  • www.mql5.com
Программы MQL5 / Выполнение программ - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber:

Извините, но нет желания разбираться с Вашими скриптами

Добавлено

Но есть выход из положения

Так как функция OrderrSend() синхронная, то получив ордер, мы

убеждаемся, что история синхронизирована в OnTradeTransaction()

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
    switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
         switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Ордер синхронизирован с историей
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }

 И никаких танцев!

 
prostotrader:

И никаких танцев!

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

Как правильно работать в MT5 с OrderSend

fxsaber, 2016.11.10 10:00

Заметьте, что это скрипт и никаких Event-ов быть не может. Единственный выход - тупой Sleep.

Если переписать этот скрипт с помощью СБ, ничего не поменяется.

 
fxsaber:
ВЫ можете извращаться со Sleep, как пожелаете....
 
prostotrader:
ВЫ можете извращаться со Sleep, как пожелаете....

На кой повторять то же, что уже сами предлагали и что озвучивалось еще до этого другими?

В ветке все сказано про возможные проблемы с OnTradeTransaction. В частности, про работу нескольких советников одновременно.

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

OnTrade и OnTradeTransaction именно для этого и делалось. И когда это зарождалось, разработчики считали, что одновременная работа более, чем с одним советником на счету - идиотизм.

Ну ошибались они на этот счет, с кем не бывает.

Попробуйте написать следующую функцию в советнике

  1. i = 0.
  2. Открываем позицию на symbol[i].
  3. Если i++ >= 5 - выходим.
  4. Если новая позиция не имеет проскальзывания, то возвращаемся на п.2. Если же есть проскальзывание, выходим.
 
fxsaber:

На кой повторять то же, что уже сами предлагали и что озвучивалось еще до этого другими?

В ветке все сказано про возможные проблемы с OnTradeTransaction. В частности, про работу нескольких советников одновременно.

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

OnTrade и OnTradeTransaction именно для этого и делалось. И когда это зарождалось, разработчики считали, что одновременная работа более, чем с одним советником на счету - идиотизм.

Ну ошибались они на этот счет, с кем не бывает.

Попробуйте написать следующую функцию в советнике

  1. i = 0.
  2. Открываем позицию на symbol[i].
  3. Если i++ >= 5 - выходим.
  4. Если новая позиция не имеет проскальзывания, то возвращаемся на п.2. Если же есть проскальзывание, выходим.

У меня, сейчас, на реале (в одном терминале) работает 41 эксперт, которые в совокупности за торговый день

устанавливают 2000 ордеров открывают и закрывают позиции и никаких трудностей я ВООБЩЕ не испытываю! 

Добавлено

Нужно исходить и того функционала, который есть, а не из того "мне так надо".

Разработчики, по возможности, исправляют ошибки и устраняют недочёты, учитывая пожелания

пользователей (правда очень медленно).

Думается что и с OederSend() скоро разберутся.  

 
prostotrader:

У меня, сейчас, на реале (в одном терминале) работает 41 эксперт, которые в совокупности за торговый день

устанавливают 2000 ордеров открывают и закрывают позиции и никаких трудностей я ВООБЩЕ не испытываю! 

Это называется съехать с темы.

Когда речь заходит даже о простейшей логике

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

Как правильно работать в MT5 с OrderSend

fxsaber, 2016.11.15 13:30

Попробуйте написать следующую функцию в советнике

  1. i = 0.
  2. Открываем позицию на symbol[i].
  3. Если i++ >= 5 - выходим.
  4. Если новая позиция не имеет проскальзывания, то возвращаемся на п.2. Если же есть проскальзывание, выходим.
Кто-то ее реализует сразу
// MQL4&5-code

#property strict

#include <MT4Orders.mqh>    // https://www.mql5.com/ru/code/16006

void Func( const string &Symbols[] )
{
  const int Total = ArraySize(Symbols);
  
  for (int i = 0; i < Total; i++)
  {
    const double Price = SymbolInfoDouble(Symbols[i], SYMBOL_ASK);
    const int digits = (int)SymbolInfoInteger(Symbols[i], SYMBOL_DIGITS);
    
    if (!OrderSelect(OrderSend(Symbols[i], OP_BUY, 1, Price, 100, 0, 0, DoubleToString(Price, digits)), SELECT_BY_TICKET) ||
        (NormalizeDouble(Price - OrderOpenPrice(), digits) != 0)) // если не получилось открыть или есть проскальзывание - выходим
      break;
  }
}

void OnStart() // OnTick
{
  const string Symbols[] = {"EURUSD", "GBPUSD", "AUDUSD", "USDCAD", "USDJPY"};
  
  Func(Symbols);
}

А кто-то ждет маны небесной от разработчиков.
 

Я уже говорил, что Вы вправе извращаться как угодно (у каждого есть это право). 

 
prostotrader:

Я уже говорил, что Вы вправе извращаться как угодно (у каждого есть это право). 

давно это было, но помню, этот парень, ну, этот - fxsaber чудеса творил,

до сих пор в codebase MT4 хранятся его коды, его код чтения сайтов по WinInet  

используют  многие программисты до сих пор...

а потому, сдается мне, он никакой не извращениц... 

 
Выдрал из библиотеки сюда синхронизированный OrderSendSync
uint OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

const bool IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
                       ::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));
                      
                      

bool Waiting( const bool FlagInit = false )
{
  static ulong StartTime = 0;

  if (FlagInit)
    StartTime = ::GetMicrosecondCount();

  const bool Res = (::GetMicrosecondCount() - StartTime < OrderSend_MaxPause);

  if (Res)
    ::Sleep(0);

  return(Res);
}

bool EqualPrices( const double Price1, const double Price2, const int digits)
{
  return(::NormalizeDouble(Price1 - Price2, digits) == 0);
}

#define WHILE(A) while (!(Res = (A)) && Waiting())

bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
  bool Res = ::OrderSend(Request, Result);

  if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (OrderSend_MaxPause > 0))
  {
    Res = (Result.retcode == TRADE_RETCODE_DONE);
    Waiting(true);

    if (Request.action == TRADE_ACTION_DEAL)
    {
      WHILE(::HistoryOrderSelect(Result.order))
        ;

      Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
                    ((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));

      if (Res)
        WHILE(::HistoryDealSelect(Result.deal))
          ;
    }
    else if (Request.action == TRADE_ACTION_PENDING)
    {
      if (Res)
        WHILE(::OrderSelect(Result.order))
          ;
      else
      {
        WHILE(::HistoryOrderSelect(Result.order))
          ;

        Res = false;
      }
    }
    else if (Request.action == TRADE_ACTION_SLTP)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
        {
          EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
          EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
          {
            EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
            EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_MODIFY)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if (::OrderSelect(Result.order))
        {
          EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
          EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if (::OrderSelect(Result.order))
          {
            EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
            EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_REMOVE)
      if (Res)
        WHILE(::HistoryOrderSelect(Result.order))
          ;
  }

  return(Res);
}

#undef WHILE
Идея по коду должна быть понятна. Возможно, что-то не учел. Ошибок в работе не замечал.