Eroarea 146 (- fluxul de tranzacții este ocupat -) și modul de abordare a acesteia - articole despre mql4

1. Conceptul de "flux de tranzacționare" în terminalul MetaTrader 4

Din ajutorul MetaEditor:

Pentru comerțul de experți și script-uri, doar un singur fir care se execută în contextul comerțului programului (automat de context, de tranzacționare de la experți și script-uri). Prin urmare, în cazul în care contextul este ocupat operațiuni comerciale de un expert, un alt expert sau script-ul nu poate în acest moment, apel funcții de tranzacționare din cauza unei erori 146 (ERR_TRADE_CONTEXT_BUSY)


2. Funcția IsTradeAllowed ()

Cea mai ușoară modalitate de a determina dacă un fir de tranzacționare este liber este să utilizați funcția IsTradeAllowed ().
Din ajutorul MetaEditor:

Returnează TRUE dacă EA este permis să tranzacționeze și fluxul de tranzacții este gratuit, în caz contrar returnează FALSE

Ie Puteți încerca să tranzacționați numai dacă funcția IsTradeAllowed () returnează TRUE.
Verificarea trebuie efectuată imediat înainte de operațiunea de tranzacționare.

Un exemplu de utilizare incorectă a funcției:

În acest exemplu, starea fluxului comercial este verificată chiar la începutul funcției start (). Această decizie eronată - pentru timpul petrecut de expert în calcule (necesitatea de a intra pe piață, nivelurile Stop Loss, Take Profit, dimensiunea lotului etc.), fluxul comercial poate fi ocupat de un alt expert. În acest caz, încercarea de a deschide o poziție nu va reuși.

Un exemplu de utilizare corectă a funcției:

Aici, verificarea are loc chiar înainte ca poziția să fie deschisă, iar probabilitatea ca celălalt expert să se "prindă" între aceste două acțiuni este mult mai mică (dar încă acolo, care va fi discutată puțin mai târziu).

În această metodă, există două dezavantaje semnificative:

  • există posibilitatea ca experții să efectueze simultan un control și, după ce au primit o "lumină verde", vor încerca simultan să facă schimb
  • în cazul în care testul eșuează, data viitoare când EA încearcă să tranzacționeze numai la bifarea următoare. Și o astfel de întârziere nu este justificată.

A doua problemă poate fi rezolvată pur și simplu - trebuie doar să "așteptați" până când fluxul de tranzacționare este liber. Apoi, expertul va începe tranzacționarea imediat după terminarea celuilalt expert.

Va arata cam asa:

În implementarea actuală avem din nou locuri problematice:
  • în primul rând pentru că IsTradeAllowed () funcția este responsabil nu numai pentru starea fluxurilor comerciale, dar, de asemenea, pentru „capuse“, rezolutia unui expert pentru comerț, expertul poate „închide“ într-o buclă infinită, și se va opri numai atunci când eliminat manual din graficul
  • în al doilea rând, în cazul în care expertul va trebui să aștepte până când fluxul comercial de cel puțin un al doilea, prețurile se pot schimba și comerțul asupra lor nu poate fi - este necesar să se actualizeze datele și se recalculează nivelurile de deschidere a Stop Loss si Take Profit pentru pozitiile viitoare.

Codul, ținând cont de corecțiile, va arăta astfel:

În acest exemplu, ați adăugat:
  • actualizarea informațiilor despre piață (RefreshRates ()) și conversia ulterioară a nivelurilor SL și TP
  • Timp maxim de așteptare MaxWaiting_sec, dacă este depășit, expertul nu va mai funcționa

În această formă, acest cod poate fi deja folosit de experții săi.

Atingerea finală este "eliminată" tot ce privește verificarea într-o funcție separată. Aceasta va facilita integrarea sa în experți și va simplifica utilizarea.

Modelul expertului care utilizează funcția:

Să tragem câteva concluzii:

Funcția IsTradeAllowed () este ușor de utilizat și este ideală pentru a face distincția între accesul la fluxul de tranzacționare și munca simultană a doi sau trei experți. Din cauza deficiențelor care apar în ea, utilizarea acesteia atunci când lucrează cu mai mulți experți nu garantează absența erorii 146 și poate determina expertul să se închidă cu caseta de selectare "Permiteți experților să vândă".

De aceea vom analiza o modalitate alternativă de a rezolva această problemă - folosind o variabilă globală ca fiind "semafor".

3. Variabilele globale ale terminalului client

Mai întâi un pic despre concepte.

Variabilele globale ale terminalului client sunt variabile, la care accesul este disponibil tuturor experților, scripturilor și indicatorilor. Ie O variabilă globală creată de un expert poate fi utilizată de alți experți (în cazul nostru, pentru a distinge între accesări).

Pentru a lucra cu variabilele globale în MQL 4 există mai multe funcții:

  • GlobalVariableCheck () - pentru a verifica dacă există o variabilă globală
  • GlobalVariableDel () - pentru a elimina variabila globală
  • GlobalVariableGet () - pentru a obține valoarea variabilei globale
  • GlobalVariableSet () - pentru a crea și modifica valoarea unei variabile globale
  • GlobalVariableSetOnCondition () - pentru a modifica variabila globală de la o valoare (indicată de utilizator) la alta. Ie Diferența față de GlobalVariableSet () este că noua valoare va fi atribuită numai la o anumită valoare veche. Această funcție este cheia pentru crearea unui semafor.
  • GlobalVariablesDeleteAll () - pentru a elimina toate variabilele globale (nu știu cine ar putea avea nevoie de acest :)

De ce să folosiți funcția GlobalVariableSetOnCondition (), mai degrabă decât o combinație de GlobalVariableGet () și GlobalVariableSet ()? Da, toate din aceleași motive - între folosirea a două funcții poate dura ceva timp. Și un alt expert are șansa de a "închide" procesul de comutare a semaforului. Nu putem permite asta.

4. Ideea de bază a unui semafor

Un expert care dorește să facă schimburi ar trebui să verifice starea semaforului. Dacă există o "lumină roșie" asupra semaforului (variabilă globală = 1), atunci un alt expert este deja tranzacționat și trebuie să așteptați. Dacă pe semaforul "lumină verde" (variabila globală = 0), puteți începe imediat tranzacționarea (fără a uita să instalați o "lumină roșie" pentru alți experți).

În total, trebuie să creați 2 funcții - una pentru setarea "luminii roșii" și una pentru setarea "lumină verde". Sarcina la prima vedere este simplă. Dar să nu sari la concluzii, ci mai degrabă să încerce să formuleze un flux de lucru pentru fiecare funcție (să le TradeIsBusy () și TradeIsNotBusy () numesc) și să le pună în aplicare efectiv.

5. Funcția TradeIsBusy ()

După cum sa menționat deja, funcția principală a funcției va fi așteptarea apariției "lumină verde" și a includerii "luminii roșii". În plus, trebuie să verificăm dacă există o variabilă globală și să o creezi, în caz că nu există. Acest control este mai logic (și mai economic) de făcut din funcția init () a expertului. Dar atunci ar exista o probabilitate ca utilizatorul să o șterge și toți experții care lucrează la acel moment nu vor putea să facă schimb. Prin urmare, îl vom plasa în corpul funcției create.

Toate aceste acțiuni ar trebui să fie însoțite de ieșirea de informații și tratarea erorilor care au apărut atunci când lucrați cu o variabilă globală. De asemenea, nu uitați de "agățat" - timpul funcției ar trebui să fie limitat.

Iată ce ar trebui să obținem:

Apoi, totul pare să fie clar:

  • verificați existența unei variabile globale și, în caz de eșec, creați-o
  • încercați să modificați valoarea unei variabile globale de la 0 la 1. Aceasta va funcționa numai dacă valoarea acesteia este = 0.

Funcția poate funcționa maximum de secunde MaxWaiting_sec și nu împiedică ștergerea expertului din program.
Informații despre toate erorile care apar sunt afișate în jurnal.

6. Funcția TradeIsNotBusy ()

Funcția TradeIsNotBusy efectuează sarcina inversă - include "lumină verde".

Nu are limită de timp și nu poate fi oprită de utilizator. Motivația este destul de simplă - dacă nu includeți "lumina verde", niciun expert nu va putea să facă schimb.

Desigur, nu există nici un cod de retur - rezultatul poate fi doar o reușită.

Iată cum arată:

7. Integrarea în experți și utilizare

Acum avem 3 funcții pentru a diferenția accesul la fluxul de tranzacționare. Pentru a facilita integrarea acestora în experți, puteți crea un fișier TradeContext.mq4 și îl puteți include cu directiva #include (fișierul este atașat).

Un șablon expert care utilizează funcțiile TradeIsBusy () și TradeIsNotBusy ():

Utilizarea TradeIsBusy () și TradeIsNotBusy () poate fi doar o singură problemă - dacă după fluxul comercial este ocupat, expert șters din diagramă, aceasta variabila TradeIsBusy rămâne egală cu 1. Alți experți, atunci nu va fi în măsură să comerțului.

Problema este rezolvată pur și simplu - nu ștergeți expertul din diagramă, dacă acesta tranzacționează;)

De asemenea, este posibil ca variabila TradeIsBusy să nu fie resetată când terminalul este terminat. În acest caz, utilizarea funcției TradeIsNotBusy () din funcția init () a expertului ajută.

Oh, și în orice moment valoarea unei variabile poate fi modificat manual - butonul F3 în terminalul (este o caracteristică fără acte de a interzice tuturor experților comerciale;)

De ce un font atât de mare? Din câte știu, eroarea 146 este generată de terminal, cererea nu este trimisă brokerului. Dar de ce, dacă există un mecanism de verificare a fluxului de tranzacționare?

- În ceea ce privește fontul - acesta este pentru admin, astfel că site-ul uneori funcționează cu Chrome (Google Chrome) - zoom în fereastră percepe pentru un font mare. - Am adăugat condiția de a verifica dacă fluxul este liber, potrivit muncitorului-țăran, fără probleme, dar există o șansă foarte mică ca cei doi consilieri de la diferitele perechi de valute să se ciocnească în același moment. Dacă una dintre ele este oprită de un terminal (nu de un broker), atunci acest lucru este acceptabil. Acum, tranzacționez pe demo (6 consilieri, se pare că au 7 oferte + schimbarea comenzilor) - pentru ziua respectivă, după adăugarea cecului, nu există încă greșeli. Mulțumesc!

Bună ziua, ajutați-vă sau ajutați-vă să înțelegeți motivul erorilor. Pe VPS am un terminal cu un consilier. Nu lucrez cu mâinile mele, consilierul însuși funcționează. Când am achiziționat VPS-ul și am reinstalat terminalul (din moment ce a existat o actualizare a terminalului în forex4you), foarte multe, foarte des, au apărut greșeli. Am aplicat forex4you, trimis la VPS. Apel la VPS, nu cunosc problema și este trimis aici pe acest site. Ce poate provoca astfel de erori, VPS sau terminal? Te rog ajută-mă să înțeleg problema, pentru că am pierderi din cauza acestor eșecuri. 1 eroare - TradeDispatcher: contextul comerțului este ocupat 2 eroare - nu se poate conecta conexiunea Starea conexiunii, de mai jos, pe dreapta, schimb și nu mă ajută.

Articole similare