Caratteristiche utili da KimIV - pagina 2

 
Che ne dite di questo:
if (err==146)
{
while (IsTradeContextBusy())
{
if (IsTradeAllowed()) break;
else
Sleep(1000*1,1);
}}
Penso che questa sia una soluzione più veloce. Per favore, condividete i vostri commenti.
Grazie.
 
Red.Line писал (а): Grazie per l'utile argomento, anche se sono su torte bruciate, ma comunque forse qualcuno ha affrontato il problema di accumulare e campionare da grandi set di dati in µl. µl e banche dati? Qualcuno ha pensato in questa direzione?
Certamente una soluzione semplice, ma qualcosa. https://forum.mql4.com/ru/9377
 
zhuki:
Cosa ne pensi di questa variante:
if (err==146)
{
  while (IsTradeContextBusy())
  {
    if (IsTradeAllowed()) break;
    else 
    Sleep(1000*1,1);
  }
}
Questa mi sembra una soluzione più rapida, io lavoro in questo modo. Commento.
Grazie.

Mi andrà bene. Con comprensione. La pausa è minore, funziona più velocemente... Ma c'è una ridondanza ingiustificata nella tua versione.

La funzione IsTradeContextBusy restituisce il flag di occupazione del thread commerciale. Non c'era affatto una tale funzione prima della costruzione del 195°. Così abbiamo usato la funzione IsTradeAllowed che restituisce un segno che l'EA è autorizzato a commerciare e il flusso commerciale è libero.

Permettiamo all'EA di fare trading selezionando la casella "Allow EA to trade" nella finestra di dialogo delle proprietà dell'EA (tasto F7).

L'errore 146 (Trade Stream is busy) non ha niente a che fare con il fatto di permettere all'Expert Advisor di fare trading. Perciò, rivediamo le proprietà della funzione IsTradeAllowed nella misura in cui si riferiscono solo al thread commerciale.

Quindi, il thread di scambio è libero e la funzione IsTradeAllowed restituisce True. Il thread commerciale è occupato, la funzione IsTradeAllowed restituisce False. Ora diamo un'occhiata ai valori restituiti dalla funzione IsTradeContextBusy. Il thread commerciale è libero, la funzione IsTradeContextBusy restituisce False. Il thread commerciale è occupato, la funzione IsTradeContextBusy restituisce True. Possiamo vedere che per gli stessi stati di flusso commerciale, i valori delle funzioni IsTradeAllowed e IsTradeContextBusy sono opposti. Inoltre, queste funzioni si duplicano a vicenda piuttosto che completarsi a vicenda per quanto riguarda gli stati dei flussi commerciali. Pertanto, uno di loro può essere escluso. Quale? La funzione IsTradeAllowed, come ho già detto sopra, oltre al flag di stato del flusso di commercio, restituisce anche il flag che permette all'EA di commerciare che in questa situazione, cioè quando si gestisce l'errore 146 (Trade Flow è occupato), non è necessario per noi. Pertanto, sarà necessario e sufficiente utilizzare solo una funzione IsTradeContextBusy. Se eseguite le abbreviazioni di cui sopra, il vostro codice sarà ridotto al mio:

if (err==146) while (IsTradeContextBusy()) Sleep(1000*1,1);
con la sola differenza della dimensione della pausa. Ma questa è una questione di gusti, preferenze personali, stile di trading e così via. Si potrebbe mettere una pausa di 0,1 secondi. Non è una questione di principio... Preferisco solo 11 secondi.
 
Ma per la precisione preferisco ancora fare una pausa tra tutti i tipi di operazioni di trading da 5 secondi al rilascio del filo. Grazie.
 

Sono stati trovati due errori nella funzione SetOrder:

  1. Uso scorretto della funzione MarketInfo. Avrebbe dovuto essere chiamato DOPO aver controllato il parametro sy, non PRIMA.
  2. Correzione dei livelli di impostazione dell'ordine lavorati in modo errato. Inoltre, i livelli di prezzo degli stop e dei takeover non sono stati corretti. Ora è fissato e funziona perfettamente. Ho testato questo per molto tempo usando lo script di prova che mostrerò un po' più tardi.

Attenzione! Il post con la funzione SetOrder per il trading online è stato corretto. La funzione è un po' più lunga. Non entrava in tutto il post, quindi ha dovuto essere spostato nel rimorchio.

 

In questo post ho deciso di dare i punti principali spiegando come funziona la funzione SetOrder. Io stesso non lavoro con gli ordini, cioè qui sono nel territorio di qualcun altro. Forse qualcuno che sa come funziona la funzione SetOrder potrà suggerire miglioramenti o trovare errori.

1. Nelle prime righe di codice, le variabili locali sono dichiarate e alcune di esse sono inizializzate. Per esempio, in lsComm, vengono scritti il nome dell'EA e il nome del timeframe restituito dalla funzione GetNameTF. A proposito, non mi soffermerò su funzioni come GetNameOP, GetNameTF, Message, ecc.

string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

2. Controllo dei parametri ricevuti. Se sy è vuoto, viene inizializzato con il nome dello strumento corrente. La variabile per il colore dell'icona sul grafico è inizializzata dal tipo di operazione. Se il tempo di scadenza non nullo dell'ordine è inferiore al tempo corrente, viene azzerato.

if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;

3. il corpo del ciclo di tentativi di trading, il cui numero è limitato dal valore della variabile globale NumberOfTry. Le operazioni eseguite all'interno del ciclo principale della funzione SetOrder vanno oltre.

for (it=1; it<=NumberOfTry; it++)

4. Se la funzione SetOrder non viene eseguita nel tester, ha la possibilità di terminare il suo funzionamento. L'attesa del ciclo di rilascio del flusso commerciale viene eseguita qui. Le variabili dell'ambiente di mercato vengono aggiornate e viene registrata l'ora corrente.

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
  Print("SetOrder(): Остановка работы функции");
  break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();

5. Invio di una richiesta a un server commerciale. Se il biglietto è positivo, la funzione SetOrder viene terminata.

ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
  if (UseSound) PlaySound(NameFileSound); break;
 

6. Se il biglietto è negativo, viene eseguita l'elaborazione degli errori di esecuzione.
7. In caso di errori 128 (La data del timeout è scaduta), 142 (L'ordine è stato accodato) e 143 (Ordine accettato dal commerciante per l'esecuzione) facciamo una pausa di 66 secondi. Dopo la pausa, utilizzando la funzione ExistOrders (che descriveremo più avanti) controlliamo se l'ordine è già stato impostato nell'intervallo di tempo tra la richiesta del server e il momento attuale. Se l'ordine è stato impostato, uscite dalla funzione.

err=GetLastError();
if (err==128 || err==142 || err==143) {
  Sleep(1000*66);
  if (ExistOrders(sy, op, mn, ot)) {
    if (UseSound) PlaySound(NameFileSound); break;
  }
  Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
  continue;
}

8. La dimensione dell'oggetto e i prezzi Bid e Ask sono memorizzati nelle variabili locali.

mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);

9. In caso di errore 130 (stop errato) i livelli di prezzo dell'ordine, stop e take out sono corretti se possibile.

// Неправильные стопы
if (err==130) {
  switch (op) {
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) pp=pa-msl*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) pp=pb+msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) pp=pb-msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
  }
  Print("SetOrder(): Скорректированы ценовые уровни");
}

10. Le informazioni, che possono aiutare a risolvere il problema o a trovare l'errore in seguito, vengono visualizzate nel rapporto.

Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa,"  Bid=",pb,"  sy=",sy,"  ll=",ll,"  op=",GetNameOP(op),
      "  pp=",pp,"  sl=",sl,"  tp=",tp,"  mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy);

Alla fine elaboriamo altri errori. Alcuni mostrano una lunga pausa (5 minuti), altri bloccano l'Expert Advisor, altri permettono ulteriori tentativi di trading, ecc.

Questo è tutto! Fine della descrizione!

 

La funzione ExistOrders().

Restituisce un flag per l'esistenza di un ordine. Risponde alla domanda se l'ordine è impostato o no. Puoi usare questa funzione per richiedere qualsiasi ordine, così come altri più specifici. Il filtro di richiesta è configurato utilizzando i parametri della funzione:

  • sy - Impone una restrizione sul nome dello strumento. Il parametro predefinito è "" - nessuna restrizione, cioè qualsiasi strumento. Se si passa NULL, la selezione dell'ordine sarà limitata dal simbolo corrente.
  • op - pone una restrizione sul tipo di ordine. Nessun vincolo di default, cioè qualsiasi tipo di ordine è controllato. I valori validi del parametro sono -1, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT e OP_SELLSTOP.
  • mn - pone un limite al numero di identificazione ("magico") dell'ordine. Nessun vincolo di default, cioè l'ordine con qualsiasi numero magico è controllato.
  • ot - pone un limite al tempo di impostazione dell'ordine. Viene controllato per assicurarsi che l'ordine sia stato impostato dopo il valore di questo parametro. Per default non c'è limite, cioè un ordine con qualsiasi tempo di impostazione è controllato.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal(), ty;
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty>1 && ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ot<=OrderOpenTime()) return(True);
          }
        }
      }
    }
  }
  return(False);
}
 

Esempi di come usare la funzione ExistOrders().

1. Verificare la disponibilità di qualsiasi ordine

ExistOrders();

2. Controlla la disponibilità di qualsiasi ordine su qualsiasi strumento sul grafico corrente

ExistOrders(NULL);

3. Controlla la presenza di un ordine BuyLimit su qualsiasi strumento

ExistOrders("", OP_BUYLIMIT);

4. Controlla se c'è un ordine SellStop con il numero magico 123456 su EURUSD

ExistOrders("EURUSD", OP_SELLSTOP, 123456);

5. Controlla la disponibilità di qualsiasi ordine con un tempo di preparazione di 2 ore o meno

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);
Nel trailer c'è uno script per testare la funzione ExistOrders. I primi 4 esempi nello script sono commentati.

File:
 

Attenzione! Nel post del 12.03.2008 07:24 ho sostituito l'allegato SetOrder.mq4