Организация цикла перебора ордеров - страница 12

 
Artyom Trishkin:

- Для чего нужна сковорода?

- Например для того, чтобы яичницу пожарить.

- так разговор-то не о яичнице, а о сковороде...


ооо - прикольно - сцепились два нападающих ... жгите - а то скучно как то ... 

 
Artyom Trishkin:

- Для чего нужна сковорода?

- Например для того, чтобы яичницу пожарить.

- так разговор-то не о яичнице, а о сковороде...

Видал? Уже считают что мы с тобой сцепились в схватке, почти смертельной.

Чё-то мне уже лениво стало продолжать эту дискуссию. Я не могу понять зачем каждую миллисекунду надо перебирать ордера. Разве что из них яичницу жарить...

 
Alexey Viktorov:

Видал? Уже считают что мы с тобой сцепились в схватке, почти смертельной.

Чё-то мне уже лениво стало продолжать эту дискуссию. Я не могу понять зачем каждую миллисекунду надо перебирать ордера. Разве что из них яичницу жарить...

Ага..., прям в пятку вцепился... :)
Я ж не говорю, что каждую. Но часто - дабы вовремя засечь изменение окружения.
 
ну я так не играю  ... стухли ... разочаровали ... 
 

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

Организация цикла перебора ордеров

fxsaber, 2017.10.06 02:00

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

Версия без обращения к истории.

struct HISTORY_UNIT
{
  long Ticket;
  int Type;
  double Lots; 
    
  HISTORY_UNIT( void ) : Ticket(::OrderTicket()), Type(::OrderType()), Lots(::OrderLots())
  {
  }

  bool operator !=( const HISTORY_UNIT &Unit ) const
  {
    return((this.Ticket != Unit.Ticket) || (this.Type != Unit.Type) || (this.Lots != Unit.Lots));
  }
      
  bool IsChange( void )
  {
    const HISTORY_UNIT Tmp;
    const bool Res = (this != Tmp);
    
    if (Res)
      this = Tmp;
      
    return(Res);
  }
};

// Возвращает true только в случае, если с последнего вызова произошли торговые изменения
bool IsChange( void )
{
  static HISTORY_UNIT History[];  

  const int Total = OrdersTotal();  
  bool Res = (ArraySize(History) != Total);

  for (int i = 0, j = Res ? ArrayResize(History, 0, Total) : 0; i < Total; i++)      
    if (OrderSelect(i, SELECT_BY_POS))
    {
      if (Res || (Res = History[j].IsChange()))
        ArrayResize(History, j + 1, Total);
      
      j++;
    }
  
  return(Res);
}

Эта версия особенно актуальна для MT5 на VPS, т.к. MT5 работает с Историей очень медленно и затратно по вычислительным ресурсам.

 
fxsaber:

Версия без обращения к истории.

Эта версия особенно актуальна для MT5 на VPS, т.к. MT5 работает с Историей очень медленно и затратно по вычислительным ресурсам.


В таком случае лучше воспользоваться штатной OnTrade().

OnTrade

Функция вызывается при наступлении события Trade, которое возникает при изменении списка выставленных ордеров и открытых позиций, истории ордеров и истории сделок. При любом торговом действии (выставлении отложенного ордера, открытии/закрытии позиции, установке стопов, срабатывании отложенных ордеров и т.п.) соответствующим образом изменяется история ордеров и сделок и/или список позиций и текущих ордеров.

 
Sergey Chalyshev:

В таком случае лучше воспользоваться штатной OnTrade().

Нельзя, к сожалению. Об этом ветка.

 
Мало, кто будет спорить с этим утверждением

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

Ошибки, баги, вопросы

fxsaber, 2018.01.23 09:39

После неудачного и удачного OrderSend должно быть заново полностью считано текущее торговое окружение. Это правило должно действовать всегда.

Это универсальное правило. Но немногие задумываются над его реализацией в MT5. Поэтому написал шаблон большинства несложных ТС (в кодобазе почти все такие)

// Шаблон большинства ТС

#include <Trade/Trade.mqh>

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит позицию соответствующего типа
bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type )
{
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 )
{
  static CTrade Trade;    
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET))));

  // Открыли позицию по сигналу
  return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb)));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, POSITION_TYPE_BUY);
  else if (SellSignal(Symb))
    Action(Symb, POSITION_TYPE_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

По какой-то причине некоторые пишут больше кода для таких же ТС. Но на самом деле этот код справляется не хуже. Большинство ТС требуют написания только BuySignal и SellSignal. Больше ничего не нужно.

Пример шаблона специально написан с помощью СБ. Поэтому вопрос к спецам по MT5, код правильный?

 
fxsaber:
Мало, кто будет спорить с этим утверждением

Это универсальное правило. Но немногие задумываются над его реализацией в MT5. Поэтому написал шаблон большинства несложных ТС (в кодобазе почти все такие)

По какой-то причине некоторые пишут больше кода для таких же ТС. Но на самом деле этот код справляется не хуже. Большинство ТС требуют написания только BuySignal и SellSignal. Больше ничего не нужно.

Пример шаблона специально написан с помощью СБ. Поэтому вопрос к спецам по MT5, код правильный?

Вот по этому утверждению:

После неудачного и удачного OrderSend должно быть заново полностью считано текущее торговое окружение. Это правило должно действовать всегда.

Зачем после неудачного тянуть вообще всё? Зачем историю ордеров и позиций шерстить? Текущие ордера и позиции тоже? Не достаточно обновить цены и необходимые на текущий момент данные?

 
Artyom Trishkin:

Зачем после неудачного тянуть вообще всё? Зачем историю ордеров и позиций шерстить? Текущие ордера и позиции тоже? Не достаточно обновить цены и необходимые на текущий момент данные?

Если настолько буквально понимать, то можно прочитать и прошедшую тиковую историю по каждому символу из Обзора рынка. Но, думаю, Вам же на самом деле понятен смысл утверждения.

Код это утверждение, вроде, как реализовывает. Поэтому и был вопрос ко всем, кто разбирается в MT5: код правильный?

Причина обращения: