Organising the order cycle - page 12

 
Artyom Trishkin:

- What do you need a frying pan for?

- For example, to fry eggs.

- it's not about scrambled eggs, it's about the frying pan...


Ooh - funny - two strikers clashing... Keep it going, it's getting boring...

 
Artyom Trishkin:

- What do you need a frying pan for?

- Like frying eggs, for example.

- So we're not talking about scrambled eggs, we're talking about a frying pan...

Did you see that? Already think you and I are locked in a near-death experience.

I'm getting a little lazy about continuing this discussion. I can't understand why every millisecond you have to go through the orders. Unless it's to fry an egg...

 
Alexey Viktorov:

Did you see that? Already think you and I are locked in a near-death experience.

I'm getting a little lazy with this discussion. I can't understand why we have to go through the orders every millisecond. Unless you want to fry eggs with them...

Yep... got it right in the heel... :)
I'm not saying every time. But often, in time to detect a change in the environment.
 
well I don't play like that ... ...are dry... disappointed...
 

Forum on trading, automated trading systems and testing trading strategies

Organizing an order loop

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)));
}

Version without reference to history.

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);
}

This version is especially relevant for MT5 on VPS, as MT5 works with History very slowly and is computationally expensive.

 
fxsaber:

Version without history reference.

This version is especially relevant for MT5 on VPS, as MT5 is very slow and computationally intensive.


In such a case it's better to use the regular OnTrade().

OnTrade

This function is called when aTrade event occurs, which changes the list ofplaced orders andopen positions,order history andhistory of deals. When any trade action (pending order opening, position opening/closing, stops setting, pending order triggering, etc.) the history of orders and deals and/or list of positions and current orders is changed accordingly.

 
Sergey Chalyshev:

In that case, it's better to use the regular OnTrade().

You can't, unfortunately. This is what the branch is about.

 
Few will argue with this statement

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

fxsaber, 2018.01.23 09:39

After OrderSend failed and OrderSend succeeded, the current trading environment must be read completely again. This rule should always apply.

This is a universal rule of thumb. But few people think about its implementation in MT5. That's why I wrote a template of most uncomplicated TS (in kodobase almost all of them are like that)

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

#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);
}

For some reason some people write more code for the same TS. But in fact this code does just as well. Most TCs only require writing BuySignal and SellSignal. Nothing else is needed.

The template example is specifically written with SB. So question to MT5 experts, is the code correct?

 
fxsaber:
Hardly anyone would argue with this statement

This is a universal rule. But not many people think about its implementation in MT5. That's why I wrote a template of most uncomplicated TS (in kodobase almost all of them are like that)

For some reason some people write more code for the same TS. But in fact this code does just as well. Most TCs only require writing BuySignal and SellSignal. Nothing else is needed.

The example template is specifically written with SB. So question to MT5 experts, is the code correct?

On this statement:

After an OrderSend failure and a successful OrderSend, the current trading environment must be read completely again. This rule must always apply.

Why should we pull everything at all after a failure? Why should we check the order and position history? The current orders and positions too? It is not enough to update prices and necessary data for the current moment?

 
Artyom Trishkin:

Why pull everything after a bad one? Why bother with the history of orders and positions? Current orders and positions too? Isn't it enough to update prices and the data we need at the moment?

If you take it literally, then you can read the past tick history for each symbol from Market Watch. But I think you actually understand the meaning of the statement.

The code kind of implements that statement. That's why I had a question for everyone who understands MT5: is the code correct?

Reason: