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

 
fxsaber:

L'opzione giusta con un semplice esempio

Penso che sia meglio aspettare che l'ordine sia preso in considerazione se non è ancora in posizione.
 
Комбинатор:
Penso che sia meglio se l'ordine non è ancora stato contabilizzato nella posizione, aspettare che venga contabilizzato.

Non capisco l'idea.

 
Schema di implementazione condizionale per OrderSend normale (senza timeout)
static MqlTradeResult LastResult = {0};

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult &Result )
{ 
  LastResult = Result;
}

// Условный алгоритм реализации штатной OrderSend
bool OrderSend( const MqlTradeRequest &Request, MqlTradeResult &Result )
{  
  bool Res = OrderSendAsync(Request, Result);
  
  if (Res)
  {
    while (LastResult.request_id != Result.request_id)
      OnTradeTransaction(); // условно-схематичный вызов
          
    Result = LastResult;    
    Res = (Result.retcode == TRADE_RETCODE_PLACED) ||
          (Result.retcode == TRADE_RETCODE_DONE) ||
          (Result.retcode == TRADE_RETCODE_DONE_PARTIAL);

    LastResult.request_id = 0;
  }
    
  return(Res);
}


Questo diagramma mostra che quando un ordine a mercato viene piazzato usando OrderSendAsync in MetaQuotes-Demo, è impossibile catturare in modo affidabile l'ordine corrispondente che viene piazzato finché l'ordine non viene eseguito o rifiutato. Cioè non ci sono meccanismi semplici in MT5 per valutare i risultati intermedi del loro OrderSendAsync.

 

sembra essere in tema,

Vorrei sottolineare che questo codice :

if ( !OrderSend(request,result) ) PrintFormat("OrderSend error %d",GetLastError());
else Print(result.price);

funziona perfettamente sulla DEMO (result=request),

ma su REAL - è impossibile ottenere un risultato (risultato=0,0). ... A meno che non aspetti qualche secondo.

 
Ivan Ivanov:

Sembra essere nel soggetto,

Vorrei sottolineare che tale codice :

Su DEMO funziona perfettamente (result=request),

ma su REAL - è impossibile ottenere il risultato (risultato=0.0). ... A meno che non aspetti qualche secondo.

Mancano dati - registri, valori dei campi della struttura dopo OrderSend, nome del server commerciale.

 
fxsaber:

Il punto in poche parole è questo: se c'è un ordine a mercato, consideratelo anche una "posizione". Tra virgolette perché è una posizione avvolta. 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.

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++;  // если мы сюда попадаем при проверке состояния, не запускать стратегию вообще, т.к. это промежуточное состояние.
 
Комбинатор:

Potrebbe non esserci un segnale di trading nel prossimo tick. Io stesso uso l'MT4-style, quindi non posso fare a meno di vedere queste "posizioni" senza mettermi nei guai.

 
fxsaber:

Mancano dati - registri, valori dei campi della struttura dopo OrderSend, nome del server commerciale.

//+------------------------------------------------------------------+
//|                                                      TestBUY.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{//--- объявление и инициализация запроса и результата
  MqlTradeRequest request={0};
  MqlTradeResult result={0};
//--- параметры запроса
  request.action =TRADE_ACTION_DEAL;
  request.symbol=_Symbol; 
  request.volume=0.01;
  request.type=ORDER_TYPE_BUY;
  request.price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
  request.deviation=5;
  request.magic=1234;
  request.tp=0.0;
  request.comment=DoubleToString(request.price,_Digits);
//--- отправка запроса
  if ( !OrderSend(request,result) )
    PrintFormat("OrderSend error %d",GetLastError()); // если отправить запрос не удалось, вывести
//--- информация об операции
  PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order," NewOrder");
}


2018.02.20 15:20:35.845 Trades ordine #66745055 comprare 0.01 / 0.01 EURUSDeur a mercato fatto in 610.625 ms

2018.02.20 15:20:35.935 Transazioni affare #5461453 comprare 0.01 EURUSDeur a 1.23403 fatto (basato sull'ordine #66745055)

2018.02.20 15:20:35.845 TestBUY (EURUSDeur,M15) retcode=10009 deal=0 order=66745055

Se la richiesta è soddisfatta (10009) , perché trattare=0

 
Ivan Ivanov:

Se la richiesta è fatta (10009), perché deal=0

È quasi dove la discussione è iniziata. I link hanno tutti i dettagli.

C'è una soluzione per far funzionare perfettamente OrderSend, ma sarebbe pubblicità.

 
fxsaber:

L'opzione giusta con un semplice esempio

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.

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++;  

SZY Inserisci questo codice qui e controlla il risultato sul server demo.

Invito tutti gli interessati a discutere questa questione. La mia opinione su questo argomento è la seguente:


  1. Invia l'ordine al server
  2. Un ordine a mercato appare e può essere eventualmente cancellato, ma lo abbiamo già contato come posizione?
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++;  

Questo ciclo aggiunge una posizione se viene trovato un ordine che non ha un identificatore di posizione (l'ID è zero).

Abbiamo restituito un'altra posizione.

Cosa succede se l'ordine viene cancellato dal server?

...

Penso che quando si calcolano gli ordini di mercato, dovremmo restituire WRONG_VALUE, per esempio, se ne abbiamo trovato uno - le posizioni non possono essere meno di zero. Questo sarà un segnale che c'è un ordine di mercato non registrato. Ma non per aggiungere il numero di posizioni.

Motivazione: