Errori, bug, domande - pagina 540

 

Il mio Expert Advisor, che sta partecipando al campionato, sta eseguendo azioni errate a causa del funzionamento errato della libreria standard di CTrade.

Uso la funzione PositionClose per chiudere le posizioni. Ma insieme alla chiusura delle posizioni, questa funzione stessa APRE le transazioni!

La funzione si usa così:

//--- Объект класса СTrade
CTrade mytrade;
//--- Объект класса СPositionInfo
CPositionInfo myposition;

//+------------------------------------------------------------------+
//| Проверяет и если нужно, закрывает открытую позицию               |
//+------------------------------------------------------------------+
bool ClosePosition(string ptype,double clp)
  {
   bool R=false, marker=false; int i;
     
      if(myposition.Select(_Symbol)==true)
        {
         if(myposition.Symbol()==_Symbol)
           {
            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {R=mytrade.PositionClose(_Symbol,50,5); if (R == true && myposition.Select(_Symbol)==false) break;}
               if(i >= 1) 
                 {//--- запрос успешно выполнен
                  Alert("Открытая позиция была успешно закрыта!!");
                  marker=true;
                 }
               else
                 {
                  Alert("Запрос на закрытие позиции не выполнен - ошибка: ",mytrade.ResultRetcodeDescription());
                 }
            //  }
           }
        }
      return(marker);
     }

PositionClose finisce per aprire a volte ordini inutili.

Qui, l'operazione di acquisto è stata chiusa prima e poi è stata aperta un'ulteriore operazione di vendita della stessa dimensione. Inoltre, AccountInfoDouble(ACCOUNT_FREEMARGIN) non ha notato questo commercio extra. Perché è stato seguito da uno scambio con un lotto più grande, anche se non c'erano abbastanza soldi per questo secondo la MM usata.

Mi rendo conto che forse non sto usando le funzioni MQL in modo ottimale. Ma il fatto che una funzione della libreria proprietaria MQL destinata alla chiusura delle operazioni apra da sola le operazioni non si adatta alla mia idea di comportamento accettabile delle funzioni.

 
masharov:

Capisco che potrei non usare le funzioni MQL in modo ottimale. Ma il fatto che una funzione di libreria proprietaria MQL destinata alla chiusura delle operazioni apra le operazioni da sola non si adatta alla mia idea di comportamento accettabile delle funzioni.

Leggi l'articolo Trading Events in MetaTrader 5:

Gli eventi commerciali e i cambiamenti nella storia commerciale sono riportati attraverso canali indipendenti. Quando si invia una richiesta di acquisto utilizzando la funzione OrderSend(), è possibile riconoscere immediatamente il biglietto dell'ordine, che è stato creato se la richiesta è stata controllata con successo. Ma allo stesso tempo, l'ordine stesso potrebbe non apparire ancora nel terminale del cliente, e un tentativo di selezionarlo usando la funzione OrderSelect() fallirà.

Vedere anche l'articolo Ordini, posizioni e compravendite in MetaTrader 5
 

Non ho usato la funzione OrderSend. Viene utilizzata la funzione PositionClose della libreria standard MQL, che è progettata per lavorare con gli ordini.

L'aiuto per questa funzione non descrive che può aprire compravendite.

Citazione dal riferimento:

PositionClose

Chiude una posizione al simbolo specificato.

bool PositionClose(
const string symbol, // simbolo
ulong deviation=ULONG_MAX // deviation
)

Parametri

simbolo

[Nome dello strumento commerciale, sul quale la posizione dovrebbe essere chiusa.

deviazione=ULONG_MAX

[Deviazione massima dal prezzo corrente (in punti).

Valore restituito

true - se il controllo di base delle strutture ha successo, altrimenti false.

Nota

Il buon esito del metodo PositionClose(...) non significa sempre la buona esecuzione di un'operazione di trading. È necessario controllare il risultato di una richiesta di compravendita (codice di ritorno del server di compravendita) chiamando il metodo ResultRetcode().

 
masharov:

Non ho usato la funzione OrderSend. Viene utilizzata la funzione PositionClose della libreria standard MQL, che è stata progettata per semplificare il lavoro con gli ordini.

L'aiuto per questa funzione non descrive che può aprire compravendite.

Citazione dal riferimento:

PositionClose

Chiude una posizione al simbolo specificato.

bool PositionClose(
const string symbol, // simbolo
ulong deviation=ULONG_MAX // deviation
)

Parametri

simbolo

[Nome dello strumento commerciale, sul quale la posizione dovrebbe essere chiusa.

deviazione=ULONG_MAX

[Deviazione massima dal prezzo corrente (in punti).

Valore restituito

true - se il controllo di base delle strutture ha successo, altrimenti false.

Nota

Il buon esito del metodo PositionClose(...) non significa sempre la buona esecuzione di un'operazione di trading. Il risultato dell'esecuzione della richiesta di compravendita (il codice di ritorno del server di compravendita) deve essere controllato chiamando il metodo ResultRetcode().

Non c'è nessun errore nella funzione di libreria PositionClose(...). Ma ce n'è uno nel tuo codice. Ecco la citazione del riferimento.

Успешное окончание работы метода PositionClose(...) не всегда означает успешное совершение торговой операции. 
Необходимо проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode(). 

Io, per esempio, non vedo questo controllo nel tuo codice.

 
masharov:

Non ho usato la funzione OrderSend. Viene utilizzata la funzione PositionClose della libreria standard MQL, che è progettata per lavorare con gli ordini.

L'aiuto per questa funzione non descrive che può aprire compravendite.


E potete guardare l'implementazione della funzione PositionClose:

bool CTrade::PositionClose(const string symbol,ulong deviation)
  {
   bool   partial_close=false;
   int    retry_count  =10;
   uint   retcode      =TRADE_RETCODE_REJECT;
//--- check stopped
   if(IsStopped(__FUNCTION__)) return(false);
//--- variables
   string action,result;
//--- clean
   ClearStructures();
   do
     {
      //--- checking
      if(PositionSelect(symbol))
        {
         if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //--- prepare request for close BUY position
            m_request.type =ORDER_TYPE_SELL;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
           }
         else
           {
            //--- prepare request for close SELL position
            m_request.type =ORDER_TYPE_BUY;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
           }
        }
      else
        {
         //--- position not found
         m_result.retcode=retcode;
         return(false);
        }
      //--- setting request
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.symbol      =symbol;
      m_request.deviation   =(deviation==ULONG_MAX) ? m_deviation : deviation;
      m_request.type_filling=m_type_filling;
      m_request.volume      =PositionGetDouble(POSITION_VOLUME);
      //--- check volume
      double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
      if(m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close=true;
        }
      else
         partial_close=false;
      //--- order check
      if(!OrderCheck(m_request,m_check_result))
        {
         //--- copy return code
         m_result.retcode=m_check_result.retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      //--- order send
      if(!OrderSend(m_request,m_result))
        {
         if(--retry_count!=0) continue;
         if(retcode==TRADE_RETCODE_DONE_PARTIAL)
            m_result.retcode=retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      retcode=TRADE_RETCODE_DONE_PARTIAL;
      if(partial_close) Sleep(1000);
     }
   while(partial_close);
   if(m_log_level>LOG_LEVEL_ERRORS)
      printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
//--- ok
   return(true);
  }
 

Ho pensato che non avevo bisogno di studiare il codice sorgente delle librerie standard.

L'aiuto non descrive la possibilità di aprire trade con la funzione PositionClose. I controlli e le protezioni contro l'apertura di compravendite con la funzione PositionClose, che il vostro team ha sviluppato, dovrebbero contenere se stessi. Credo che le librerie standard siano un codice ideale che dovrebbe servire da modello per gli altri. Pertanto, non dovrebbe essere necessario analizzare il codice delle librerie prima di utilizzarle.

Citazione:

La libreria standard MQL5 è scritta in linguaggio MQL5 ed è progettata per facilitare la scrittura di programmi (indicatori, script, esperti) agli utenti finali. La libreria fornisce un facile accesso alla maggior parte delle funzioni interne di MQL5.

 
masharov:

Ho pensato che non avevo bisogno di studiare il codice sorgente delle librerie standard.

L'aiuto non descrive la possibilità di aprire trade con la funzione PositionClose. I controlli e le protezioni contro l'apertura di compravendite con la funzione PositionClose, che il vostro team ha sviluppato, dovrebbero contenere se stessi. Credo che le librerie standard siano un codice ideale che dovrebbe servire da modello per gli altri. Pertanto, l'analisi del codice delle librerie prima di utilizzarle non dovrebbe essere richiesta.

L'ignoranza della legge non vi esime dalla responsabilità. Dove si trova nel vostro codice il controllo della chiusura della posizione?

            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {
                 R=mytrade.PositionClose(_Symbol,50,5); 
                 if (R == true && myposition.Select(_Symbol)==false) break;
                }

Espressione

R == true

indica solo che la funzione PositionClose() è stata eseguita con successo, ma non che la posizione è stata chiusa:

Nota

Il completamento con successo del metodo PositionClose(...) non significa sempre l'esecuzione con successo di un'operazione di trading. È necessario controllare il risultato dell'esecuzione di una richiesta di compravendita (codice di ritorno del server di compravendita) chiamando il metodo ResultRetcode().

La seconda espressione

myposition.Select(_Symbol)==false)

è equivalente a

PositionSelect(_Symbol)==false)

e inoltre non dà alcuna garanzia per le operazioni commerciali asincrone. Una posizione è già stata chiusa sul server commerciale e il terminale non ha ancora ricevuto un messaggio al riguardo. Così, si scopre che avete creato un bug nel vostro codice.

Nella vita reale, non tutto è così liscio come nel tester; ci possono essere piccoli ritardi tra l'invio di una richiesta di compravendita e il risultato della sua esecuzione. Ognuno risolve questo problema da solo, per cominciare non sarebbe male controllare il codice di ritorno usando la funzione ResultRetcode(), come è scritto nell'aiuto.

 

Di nuovo.

Mi rendo conto che forse non sto usando le funzioni MQL in modo ottimale. Ma il fatto che una funzione della libreria proprietaria MQL destinata allachiusura delle operazioniapra da sola le operazioni non si adatta alla mia idea di comportamento accettabile delle funzioni.

Tutto quello che dici si applica alla chiusura delle transazioni. Sì, l'EA non controlla in modo ottimale le posizioni di chiusura. Ma questo non permette ad una funzione progettata per chiudere di aprire da sola le transazioni.

L'aiuto dice:

PositionClose

Chiude la posizione secondo il simbolo specificato.

Non viene descritta alcuna condizione che la funzione possa aprire un trade. La raccomandazione di controllare il codice di ritorno serve anche solo per controllare ulteriormente se il trade è chiuso o no.

 
masharov:

Di nuovo.

Capisco che potrei non usare le funzioni MQL in modo ottimale. Ma il fatto che la funzione della libreria proprietaria MQL destinata allachiusura delle compravenditeapra le compravendite da sola non si adatta alla mia idea di comportamento accettabile delle funzioni.
Non c'è una funzione di chiusura della posizione, c'è solo la funzione per inviare una richiesta di acquisto o vendita (e quale sarà il risultato - apertura o chiusura di una posizione - è sconosciuto). Nel vostro caso, a causa di un errore algoritmico, vengono inviate richieste ripetute senza controllare se la richiesta precedente è stata eseguita.
 
Rosh:
Non c'è una funzione di chiusura della posizione, c'è solo la funzione di inviare una richiesta di acquisto o di vendita (e il risultato - l'apertura o la chiusura di una posizione - è sconosciuto). Nel vostro caso, a causa di un errore algoritmico, vengono inviate richieste ripetute senza controllare se la richiesta precedente è stata eseguita.

L'Aiuto ha questa funzione

Riferimento a MQL5 / Libreria Standard / Classi di trading / CTrade / PositionClose

Chiude la posizione con il simbolo specificato.

L'utente non dovrebbe preoccuparsi di come la funzione è implementata a basso livello. Poiché questa funzione esiste, MetaQuotes ha garantito che non avrà alcun comportamento non standard non descritto nella guida.

La libreria standard MQL5 è scritta in MQL5 e mira a facilitare la scrittura di programmi (indicatori, script e Expert Advisors) da parte degli utenti finali. La libreria fornisce un facile accesso alla maggior parte delle funzioni interne di MQL5.