Organizzazione del ciclo dell'ordine - pagina 8

 
Alexey Viktorov:

L'ho fatto sembrare così complicato? Il DC fa soldi con gli spread e le commissioni, il programmatore fa soldi scrivendo codice.

Uno dei trader dice che dovremmo risparmiare su spread e commissioni (non pagare il più possibile).

L'altro commerciante dice che non è giusto scrivere il codice per i soldi (se possibile, non pagare).

Entrambi si prendono cura del proprio portafoglio. Non sembrano differire l'uno dall'altro...

Tranne che tu, come programmatore, sostieni il primo e discuti il secondo dimostrandogli che ha torto.

Capisco il commerciante che vuole trovare un programmatore più economico. Capisco anche il trader che cerca condizioni di trading migliori. Qual è il problema? Cosa c'è di sbagliato nel voler risparmiare?

Ma qui è una storia diversa. Pensare al proprio algoritmo per farlo funzionare più efficacemente con gli ordini, e quindi aumentare il profitto del sistema - significa essere un buon sviluppatore. A mio parere, si possono trascurare diversi pip solo nella fase di test di massima di un'idea.

 
Andrey Khatimlianskii:

Capisco il commerciante che vuole trovare un programmatore più economico. Capisco anche il trader che cerca condizioni di trading migliori. Qual è il problema? Cosa c'è di sbagliato nel voler risparmiare?

Ma qui è una storia diversa. Pensare al proprio algoritmo per farlo funzionare più efficacemente con gli ordini, e quindi aumentare il profitto del sistema - significa essere un buon sviluppatore. Penso che possiamo trascurare diversi pip solo nella fase di test approssimativo di un'idea.

Bene. E in qualche modo capisco la tua riluttanza a scrivere ancora gratis. Nessun problema...

In generale, non sono contrario a cercare di risparmiare, ma non fino alla follia. Non puoi mettere il risparmio sullo spread in testa al trading...

 
Alexey Viktorov:

Non mi dispiace cercare di risparmiare in generale, ma non fino al punto di essere pazzo. Non puoi mettere il risparmio sullo spread al centro del trading...

Se si fanno i conti, non è così assurdo. Ma non sto cercando di convincere.

 
Andrey Khatimlianskii:

Se fai i conti, non è così stupido. Ma non sto cercando di convincere.

Bisogna contare i profitti, non i costi.

Se si risparmiano i costi, è molto facile fare delle perdite. Se il TS è progettato per sostenere delle spese, ma dà un profitto, allora questo è un buon TS, perché in uno scenario diverso, potrebbe fare una perdita.

Infatti, i vincitori non vengono giudicati!

 

La pagina 7 della pagina attuale non può essere spostata in un argomento separato (si potrebbe anche linkarla come "Ulteriori discussioni qui") e continuare ciò per cui è stata creata in questo thread?

 
Vitaly Muzichenko:

Bisogna contare i profitti, non i costi.

Quando si risparmiano i costi, è molto facile fare delle perdite. Se il TS è progettato per sostenere delle spese, ma allo stesso tempo dà un reddito, allora è un buon TS, perché in un altro scenario, potrebbe fare una perdita.

E in generale, i vincitori non vengono giudicati!

Non capisco il motivo di questo commento.

Si tratta della poca importanza della dimensione della commissione per le strategie super redditizie?

 
Eseguiamo il seguente Expert Advisor sulla MT4 EURUSD
// В случае изменения количества ордеров по основному символу, сигнализирует об их количестве

// #include <MT4Orders.mqh>

const bool Init =  EventSetMillisecondTimer(1);

int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

void OnTimer()
{
  static int PrevAmount = 0;
  
  const int Amount = AmountOrders(_Symbol);
  
  if (Amount != PrevAmount)
  {
    PrevAmount = Amount;
    
    Alert(Amount);
  }    
}


Apriamo 5 ordini EURUSD e 5 USDJPY a caso. Ora diamo un'occhiata al codice innocuo di AmountOrders e immaginiamo il seguente scenario

  1. Siamo in AmountOrders a runtime dove i == 3.
  2. Chiudiamo una posizione su USDJPY. Gli ordini vengono poi scossi nella tabella degli ordini correnti.
  3. Quando i == 2, possiamo incontrare lo stesso ordine del punto 1 attraverso OrderSelect. A causa di questo, AmountOrders può restituire un valore in più di quello che era in realtà.


Ecco una conferma di ciò che abbiamo detto

#property strict

void OnStart()
{
  for (int i = 0; i < 5; i++)
    OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
    
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i > 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      if (OrderSelect(i - 1, SELECT_BY_POS))      
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
}


Risultato

2017.10.06 01:28:05.885 TestTets EURUSD,M1: close #240725107  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.775 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.775 TestTets EURUSD,M1: close #240725108  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.673 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.673 TestTets EURUSD,M1: close #240725110  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.578 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.578 TestTets EURUSD,M1: close #240725111  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.480 TestTets EURUSD,M1: open #240725112  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.343 TestTets EURUSD,M1: open #240725111  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.253 TestTets EURUSD,M1: open #240725110  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.138 TestTets EURUSD,M1: open #240725108  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.035 TestTets EURUSD,M1: open #240725107  buy 1.00 EURUSD at 1.17121 ok


Lo stesso biglietto può uscire due volte in un innocuo ciclo di conteggio degli ordini!

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
fxsaber:

Lo stesso biglietto può uscire due volte in un innocuo ciclo di conteggio degli ordini!

Per mettere a tacere tutti i dubbi, fate quanto segue.

Installare l'Expert Advisor

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

void OnTimer()
{
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}


Lanciare lo script

#property strict

void OnStart()
{
  // Открыли позиции
  for (int i = 0; i < 25; i++)
    OrderSend(_Symbol, OP_BUY, 1, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0);

  int Tickets[];
  const int Total = OrdersTotal();
  
  ArrayResize(Tickets, Total);
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS))
      Tickets[i] = OrderTicket();
    
  // Закрыли позиции
  for (int i = 0; i < Total; i++)
    OrderClose(Tickets[i], 1, SymbolInfoDouble(_Symbol, SYMBOL_BID), 100);
}


E osserviamo che l'EA seleziona gli stessi ordini sotto diversi indici. E questo può portare al completo fallimento della logica di trading.

 
fxsaber:

l'EA seleziona gli stessi ordini con indici diversi. E questo può portare a una rottura completa della logica di trading.

Quindi, questo è il problema principale nella sua interezza! Come organizzare il ciclo degli ordini? Per esempio, come scrivere correttamente una tale funzione?

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}


Questo thread è iniziato specificando la necessità di alcune azioni ripetute quando c'è una pausa nel ciclo di ricerca. Una pausa di circa un millisecondo è sufficiente per vedere l'effetto.

Finora una tale stampella.

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

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      Res = 0;
    }
    else if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

Ma non c'è certezza che funzioni sempre correttamente.

 
fxsaber:

Per mettere a tacere tutti i dubbi, fate quanto segue.

Installare l'Expert Advisor

Eseguire lo script

E vediamo che l'EA seleziona gli stessi ordini sotto diversi indici. E questo può portare al completo fallimento della logica di trading.

Ho cambiato

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

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

void OnTimer()
{
  int PrevTicket = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      PrevTicket = 0;
    }
    
    else if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}

Abbiamo cambiato lo script senza avvisi.

Motivazione: