Errori tipici e come affrontarli quando si ha a che fare con l'ambiente del trading

 
In questo thread discuteremo gli errori comuni commessi quando si lavora con l'ambiente di trading del terminale in alcuni algoritmi, i metodi della loro eliminazione ed evitare in futuro.
 
OK.
Solo come introduzione:
L'Expert Advisor analizza la direzione (o il profitto, ... ) dell'ultimo ordine chiuso. L'ultimo ordine è stato chiuso 2 giorni fa.
Il trader ha impostato la profondità della storia a 1 giorno.
OrdersHistoryTotal() non vede quell'ordine.
La soluzione?
 
Andrei Fandeev:
Ok.
Solo come introduzione:
L'Expert Advisor analizza la direzione (o il profitto, ... ) dell'ultimo ordine chiuso. L'ultimo ordine è stato chiuso 2 giorni fa.
E il trader ha impostato la profondità della storia a 1 giorno.
OrdersHistoryTotal() non vede quell'ordine.
Soluzione?

Per MT4 - a mio parere, senza ambiguità, dare all'utente un avvertimento quando si lancia l'EA per utilizzare la profondità di storia richiesta.

MT5 permette di caricare la storia alla profondità richiesta.

 
Artyom Trishkin:

Per MT4 - a mio parere, senza ambiguità, dare all'utente un avvertimento quando si lancia l'EA per utilizzare la profondità di storia richiesta.

Fare affidamento sull'utente è una cattiva idea. Ci deve essere un controllo.
Artem, in MT4 non ho trovato Get per ottenere il valore della profondità della storia impostata.
È davvero impossibile ottenerlo programmaticamente?

 
Andrei Fandeev:

Fare affidamento sull'utente è una cattiva idea. Hai bisogno di un assegno.
Artem, in MT4 non sono riuscito a trovare il valore della profondità della storia impostata.
È davvero impossibile ottenerlo programmaticamente?

Infatti.

 

Ci sono due paradigmi per lavorare con l'ambiente di trading e scrivere EAs.

  1. Gli ingressi degli eventi (OnTick, OnTimer, ecc.) dipendono l'uno dall'altro. Ci sono informazioni che DEVONO avere tra gli eventi (non per la velocità, come la cache, ma per l'usabilità). Per esempio, dobbiamo salvare il risultato di OrderSendAsync e usarlo in OnTradeTransaction. Le cache NON sono informazioni obbligatorie e sono usate solo per accelerare. Ecco perché non li consideriamo subito.
  2. Gli ingressi degli eventi (OnTick, OnTimer, ecc.) NON sono dipendenti l'uno dall'altro. Ogni ingresso è da zero. Più o meno come uno script che tu stesso esegui su ogni evento.
In MT4 si potrebbe probabilmente risolvere tutto attraverso la seconda opzione. MT5 non è così chiaro.


Vantaggi della seconda opzione rispetto alla prima

  • È possibile terminare l'algoritmo in qualsiasi punto (normale e anormale).
  • È possibile iniziare/continuare l'algoritmo in qualsiasi punto.
  • Alta affidabilità.


Svantaggi

  • In Tester sarà inferiore alla prima variante in termini di prestazioni.
  • La logica "da zero" vi fa scrivere del codice un po' "illogico", che richiede un po' di abitudine nella prima fase.

 

Come posso confrontare le API degli ambienti di trading? Introdurre un'ampia varietà di TS diversi. E immaginiamo la nostra API virtuale ideale, che permetterebbe uno sforzo minimo per incarnare il TS in un codice affidabile.

Se è possibile creare questa API virtuale molto ideale come wrapper di un'API reale, allora l'API originale è eccellente. Nonostante lo sforzo e il tempo necessario per creare un wrapper.


MT4 e MT5 sono API eccellenti secondo questo criterio. Solo le API di origine sono difficili, ma permettono (senza vincoli architettonici/tecnici) di scrivere un grande wrapper, e quindi sono buone.

Quindi quando dicono che MT5 è più complesso di MT4 - vogliono dire che non hanno ancora incontrato un wrapper MT5 (forse non è stato ancora scritto) che sia facile da usare come il wrapper MT4 che usano.


In generale, entrambe le piattaforme permettono di creare una singola API di alto livello (wrapper) da API di basso livello. Quindi la complessità delle loro API dell'ambiente di trading è uguale!

 

MT4 ha un'API di livello piuttosto alto, quindi poche persone cercano di scrivere un wrapper universalmente più user-friendly. Ma questo non è il caso di MT5 - l'API originale di basso livello richiede solo di scrivere un qualche tipo di wrapper. Quindi non ha molto senso discutere le caratteristiche di ogni wrapper in questo thread. Piuttosto, è importante mostrare che un wrapper sarà ancora necessario. Quali caratteristiche di un'API di basso livello devono essere considerate quando si scrive un'API di alto livello.

В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!

Sulla base di questa affermazione, dobbiamo imparare a scrivere codice MT5 che non sia inferiore al codice MT4 in termini di usabilità. I wrapper API possono essere diversi (la sintassi di solito), ma architettonicamente MT5 non dovrebbe essere inferiore a MT4, altrimenti l'affermazione evidenziata è persa. Pertanto, il codice più ingombrante di MT5 non dovrebbe essere visto come un motivo di critica, ma come un aiuto per cucirlo in un involucro non meno user friendly di MT4.

 
Prendiamo un semplice MT4-template TS

Forum sul trading, sistemi di trading automatico e strategie di trading di prova

Organizzare un ciclo di ordini

fxsaber, 2018.02.15 23:19

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

#property strict // обязательно

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

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

// Находит ордер соответствующего типа
bool OrdersScan( const string Symb, const int Type )
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == Symb))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const int Type, const double Lots = 1 )
{
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((OrdersScan(Symb, 1 - Type)) && (Res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100)));

  // Открыли позицию по сигналу
  return(Res && !OrdersScan(Symb, Type) && OrderSend(Symb, Type, Lots, SymbolInfoDouble(Symb, Type ? SYMBOL_BID : SYMBOL_ASK), 100, 0, 0));
}

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

void OnTick()
{
  Strategy(_Symbol);
}

Non mostra minimamente la convenienza di MT4, serve solo come punto di confronto di base. È quella barra inferiore di usabilità che un wrapper MT5 dovrebbe essere in grado di tenere. Il modello è scritto sulla base del secondo paradigma.


Sembrerebbe che scriviamo la stessa cosa su MT5

Forum sul trading, sistemi di trading automatico e strategie di trading di prova

Organizzare un ciclo di overflow degli ordini

fxsaber, 2018.02.15 22:30

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

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

Per qualche motivo alcune persone scrivono più codice per lo stesso TS. Ma in realtà questo codice fa altrettanto bene. La maggior parte dei TC richiede solo la scrittura di BuySignal e SellSignal. Non c'è bisogno di altro.

Il modello di esempio è specificamente scritto con SB. Quindi domanda agli esperti di MT5, il codice è corretto?


La funzione che mostra la necessità di un wrapper è segnata in rosso. Il suo problema è descritto qui. Qualcuno ricorderà che questo è un antico problema di riapertura della posizione che è stato risolto usando Sleep in tempi antichi, aspettando che la posizione si aprisse dopo OrderSend. Ma in realtà, questo problema non ha nulla a che fare con OrderSend. Devi sapere come leggere correttamente l'ambiente di trading.

 
fxsaber:

Devi essere in grado di leggere correttamente l'ambiente di trading.

Come farlo con un semplice esempio

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;
      
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderGetTicket(i) && (OrderGetInteger(ORDER_TYPE) <= ORDER_TYPE_SELL) &&
        !OrderGetInteger(ORDER_POSITION_ID) && (OrderGetString(ORDER_SYMBOL) == Symb))
      Res++;  

/*
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

Il punto in poche parole è questo: se c'è un ordine a mercato, consideratelo anche una "posizione". Tra virgolette, perché è una posizione incartata. Il codice evidenziato di solito non appare da nessuna parte. Ma evita di riaprire le posizioni. La cosa più interessante qui è evidenziata in rosso. La necessità di questo chip non è immediatamente evidente.

La questione è che ci sono i cosiddetti ordini di chiusura del mercato. Lo stesso SL/TP. Ovviamente, non vorremmo vedere tali ordini di mercato come "posizioni". E non vorremmo che anche gli ordini che abbiamo piazzato si chiudessero. Quindi la condizione evidenziata è il filtro appropriato.


ZZZ incolla questo codice qui e controlla il risultato sul server demo.

 
fxsaber:

L'opzione giusta con un semplice esempio

Il punto in poche parole è questo: se c'è un ordine di mercato, consideratelo anche una "posizione". Tra virgolette, perché è una posizione incartata. Il codice evidenziato di solito non appare da nessuna parte. Ma evita di riaprire le posizioni. La cosa più interessante qui è evidenziata in rosso. La necessità di questo chip non è immediatamente evidente.

La questione è che ci sono i cosiddetti ordini di chiusura del mercato. Lo stesso SL/TP. Ovviamente, non vorremmo vedere tali ordini di mercato come "posizioni". E non vorremmo che anche gli ordini che abbiamo piazzato si chiudessero. Quindi la condizione evidenziata è il filtro appropriato.


HZ incolla questo codice qui e controlla il risultato sul server demo.

Domanda: cosa succede se dopo aver inviato un ordine di compravendita fino al prossimo tick l'ordine a mercato non viene piazzato dal server?

Motivazione: