Ordine, pozitii si tranzactii incheiate. Partea a II-a

[English version] [MQLmagazine.com in english] [Editia romaneasca]

In articolul precedent am vorbit despre cum sistemul pozitional difera de vechiul sistem de ordine folosit in MT4. In acest articol vom continua cu functiile care se ocupa de noul sistem.

Asa cum probabil stiai, ca si programator MetaTrader, singurul element care-i permite traderului sa-si cunoasca profiturile, pierderile si expunerea pe fiecare instrument este ordinul. Adica, totul incepe cu selectia si analiza fiecarui ordin, fie el ordin curent, sau ordin trecut, selectabil cu OrderSelect(). Sigur, numarul total de ordine este obtinut cu OrdersTotal() si OrdersHistoryTotal(). Deoarece MT4 are o foarte accentuata orientare monoasset, data aproape in intregime de limitarea monoasset pe care o are Strategy Tester, nici macar nu era nevoie pentru functii de pozitie, intrucat traderii aveau posibilitati limitate de a crea experti multiasset.

Incepem cu ce era deja cunoscut din MQL4, si anume lucrul cu ordine. Mai intai de toate, toata paleta de functii de ordine din MQL4 se restrange la cateva:
- OrdersTotal(), care intoarce numarul de ordine;
- OrderSelect(), functia obisnuita de selectie;
- OrderGetDouble(), OrderGetInteger(), OrderGetString(), care sa intoarca informatiile despre ordine;
- OrderGetTicket(), care este o versiune imbunatatita a lui OrderTicket() din MQL4; OrderTicket() din MQL4 intoarce tichetul ordinului selectat; pe cand OrderGetTicket() din MQL5 primeste indexul ordinului ca parametru, si-l mai si selecteaza, facand redundanta aplicarea lui OrderSelect() asupra rezultatului.
- si, desigur, OrderSend() ; apropo, era sa uit : nu mai exista OrderClose().

Functia OrdersTotal() intoarce numarul de ordine; desigur, numai numarul celor pending, pentru ca acestea sunt singurele ramase; orice ordin care este piata sau pending si este executat este incorporat in pozitie si dispare.

Functia OrderSelect() are urmatorul prototip:

1
2
3
4
bool  OrderSelect(
   ulong   ticket      // Tichetul ordinului
   uint    timeout=0   // Timeout in millisecunde
   );

Poti vedea diferentele majore cand e comparata cu vechea OrderSelect() din MQL4. Acea OrderSelect() functiona atat cu tichete cat si cu indecsi, pentru ordine curente cat si pentru ordine trecute. Acum functia solicita numarul de tichet, de unde rezulta ca vechiul mod de adresare:

OrderSelect(index,SELECT_BY_POS,MODE_TRADES)

este inlocuit de

OrderGetTicket(index)

Intoarcerea proprietatilor ordinului selectat se face cu OrderGetDouble(), OrderGetInteger(), OrderGetString(), urmarind regula generala stabilita de MQL5, ca functiile care intorc proprietati sa fie centralizate in mai putine functii, cate una pe fiecare tip principal de date.

Fiecare dintre cele trei functii are doua prototipuri, depinzand de cum sunt apelate, Un prototip le permite sa fie apelate ca si functii, admitand ca parametru doar proprietatea care este chestionta; celalalt prototip le permite sa fie apelate ca proceduri, admitand ca parametru proprietatea, si totodata o variabila de acelasi tip ca cel inclus in numele functiei. De exemplu, ai putea apela OrderGetDouble ca

sl=OrderGetDouble(ORDER_SL);

sau

OrderGetDouble(ORDER_SL,sl);

(desigur, cu sl previously declarat ca double). Un comportament similar se aplica celorlalte doua functii.

Proprietatea care este primita ca parametru de functia OrderGetDouble este de tip ENUM_ORDER_PROPERTY_DOUBLE:

Identificator Descriere Tipul rezultatului
ORDER_VOLUME_INITIAL Volumul initial al ordinului double
ORDER_VOLUME_CURRENT Volumul curent al ordinului double
ORDER_PRICE_OPEN Pretul specificat in ordin double
ORDER_SL Valoarea Stop Loss double
ORDER_TP Valoarea Take Profit double
ORDER_PRICE_CURRENT Pretul curent al simbolului double
ORDER_PRICE_STOPLIMIT Pretul Limita pentru un ordin StopLimit double

Toate acestea sunt cunoscute. Nu vad nimic in tabela care ar trebui ne ridice sprancenele.
La fel se intampla si cu OrderGetString(), care admite parametri de tip
ENUM_ORDER_PROPERTY_STRING:

Identifier Descriere Tipul rezultatului
ORDER_SYMBOL Simbolul ordinului string
ORDER_COMMENT Comentariul ordinului string

Dar cu adevarat interesanta este functia OrderGetInteger(). Pentru ca analiza lui OrderGetInteger(), ca si de altfel a lui OrderSend(), dezvaluie intentiile MetaQuotes in legatura cu MetaTrader5.
Parametrii admisibili sunt de tip ENUM_ORDER_PROPERTY_INTEGER:

Identificator Descriere Tip rezultat
ORDER_TIME_SETUP Momentul la care ordinul intra in vigoare datetime
ORDER_TYPE Tipul ordinului ENUM_ORDER_TYPE
ORDER_STATE Starea ordinului ENUM_ORDER_STATE
ORDER_TIME_EXPIRATION Timpul expirarii ordinului datetime
ORDER_TIME_DONE Momentul executiei sau anularii datetime
ORDER_TYPE_FILLING Felul executiei ENUM_ORDER_TYPE_FILLING
ORDER_TYPE_TIME Durata de viata a ordinului ENUM_ORDER_TYPE_TIME
ORDER_MAGIC ID-ul unui expert care a plasat ordinul (proiectat ca fie EA sa-si puna un numar unic) long

Mai intai, poti vedea ca nu toate tipurile sunt int, caci int e de fapt o familie de tipuri. Tipurile ENUM sunt tipuri care contin constante numerice speciale, care sunt constante intregi, deci compatibile cu int. Astfel avem ORDER_TYPE, care este destul de clar, similar cu cel din MQL4, cu diferenta ca doua tipuri de ordine sunt adaugate (sigur, constantele se scriu diferit ca cele din MQL4, dar descrierea e aceeasi):

ENUM_ORDER_TYPE:

Identificator Descriere
ORDER_TYPE_BUY Ordin de cumparare la piata
ORDER_TYPE_SELL Ordin de vanzare la piata
ORDER_TYPE_BUY_LIMIT Ordin de cumparare Limita
ORDER_TYPE_SELL_LIMIT Ordin de vanzare Limita
ORDER_TYPE_BUY_STOP Ordin de cumparare Stop
ORDER_TYPE_SELL_STOP Ordin de vanzare stop
ORDER_TYPE_BUY_STOP_LIMIT Dupa atingerea pretului ordinului, un ordin de cumparare Limita este lansat la pretul StopLimit (*Nou in MQL5*)
ORDER_TYPE_SELL_STOP_LIMIT Dupa atingerea pretului ordinului, un ordin de vanzare limita este lansat la pretul StopLimit (*Nou in MQL5*)

ENUM_ORDER_TRADE_TYPE specifica tipul ordinului in termeni de expirare:

Identifier Description
ORDER_TIME_GTC Bun pana la anulare
ORDER_TIME_DAY Bun pe parcursul zilei de trading
ORDER_TIME_SPECIFIED Cu timp specificat

Chestia care chiar ne ridica sprancenele aici e ENUM_ORDER_TYPE_FILLING:

ENUM_ORDER_TYPE_FILLING:

Identificator Descriere
ORDER_FILLING_AON Tranzactia se executa exclusv la volumul specificat, cu un pret egal sau mai bun decat cel specificat in ordin. Dca nu exista suficient volum de oferta pentru simbol, ordinul nu va fi executat.
ORDER_FILLING_CANCEL O intelegere de executie a ordinului cu un volum maxim posibil la un pret egal sau mai bun ca cel specificat in ordin. In acest caz, un ordin aditional pentru volumul neexecutat nu va fi plasat.
ORDER_FILLING_RETURN O intelegere de executie a ordinului la volumul maxim posibil la un pret egal sau mai bun decat cel specificat in ordin. In acest caz va fi plasat un ordin aditional pentru volumul neexecutat.

De ce nevoia pentru un parametru de executie intr-o platforma de retail ? Asta ne spune ca MetaQuotes pregateste MetaTrader5 pentru Nivelul II. “Pret mai bun” ? Nu specificam cumva cat de rau putea fi pretul acceptat prin parametrul Slippage ? Daca executia va fi controlata ca sa fie mai buna pentru trader, inclusiv spargerea ordinului in piese mai mici care raman pending, e sigur de nivel II. Pentru ca in contextul tradingului de retail de Nivel I nu ar avea sens. De ce? Datorita latentei. Ori pretul este mai bun si ordinul este executat in intregime la noul pret, ori pretul este mai rau, si avem o toleranta la asta, definita de Slippage. Daca noua cotatie ar fi un stream binar, 50% mai buna, 50% mai rea, atunci ai avea preturi mai bune in 50% din situatii, si nu ai avea o executie in celelalte 50%. Dar Slippage iti defineste o toleranta mai mare, asa ca admiti, in probabil 70% din cele 50% cazuri mai rele, ca esti multumit cu executie mai proasta. Noul tip de executie poate fi numai un semn al Nivelului II. Tradusa in Nivel I, inseamna ca brokerul permite sa ai ordinul partial/total executat la pretul specificat (plus/minus noul slippage, numit “deviatie”). In Nivelul II nu exista deviatie. Tradingul de nivel II nu admite executii mai proaste. Traderii pot fi avea executiile ordinelor totale, partiale sau deloc. Noul parametru de executie va da brokerilor posibilitatea de a organiza piata de Nivel II pentru trader. Deci ai putea aveao cumparare pending la Bid, sau o vanzare pending la Ask si chiar sa ai aceste ordine executate de alti participanti in ECN. Traderul de Nivel I, chiar daca scrie acelasi cod ca cel de Nivel II, va experimenta primele executii cand pretul ajunge la Ask pentru ordinul de cumparare sua cand pretul ajunge la Bid pentru ordinul de vanzare, ceea ce inseamna mult mai tarziu decat cerinta pentru Nivelul II. Totusi, pe Nivelul II, executia este jocul pietei, pe cand la Nivelul I, executia este obligatia brokerului. Aceste schimbari sunt confirmate de constantele din ENUM_ORDER_STATE, dar descriu cu acuratete starea ordinului, chiar si dinamica procesului de acceptare. Toate astea ar fi fost un nonsens in MT4, unde un ordin ar putea fi executat integral sau deloc:

ENUM_ORDER_STATE:

Identificator Descriere
ORDER_STATE_STARTED Ordin verificat, dar neacceptat inca de broker
ORDER_STATE_PLACED Ordin acceptat
ORDER_STATE_CANCELED Ordin anulat de client
ORDER_STATE_PARTIAL Ordin partial executat
ORDER_STATE_FILLED Ordin executat integral
ORDER_STATE_REJECTED Ordin respins
ORDER_STATE_EXPIRED Ordin expirat

O nota interesanta despre ORDER_MAGIC. MetaQuotes inca impinge ideea ca magicul sa fie utilizat ca used as identificator de expert. Initial, MQL5 avea acest ORDER_EXPERT_ID in loc de ORDER_MAGIC, dar apoi s-au intors la conceptul de numar magic. Sigur, numarul magic poate fi folosit ca identificator de expert, dar expert_id ar fi fost un nume inselator, indicand ca acesta ar fi fost singurul uz al numarului magic. Asa cum ati vazut in articolul nostru Trading Orientat pe Obiecte : o abordare POO a tradingului sunt destule moduri de a construi numere magice folositoare cu descrieri intentionale, care pot avea un inteles chiar pentru expert si care poate fi folosit ca eveniment de actiune.

Functia OrderSend() are urmatorul prototip:

1
2
3
4
bool  OrderSend(
   MqlTradeRequest&  request      // structura tranzactiei
   MqlTradeResult&   result       // structura raspunsului
   );

E mai elegant decat OrderSend() din MQL4. Functia accepta parametrii intr-o structura MqlTradeRequest, si raspunde intr-o structura MqlTradeResult. Lucru care e mai bun comparativ cu MQL4, unde o functie intoarce doar tichetul ordinului, si seteaza eroarea intr-o variabil de sistem MT4, care este interogata de trader cu functia GetLastError(). Acum structura MqlTradeResult contine toate raspunsurile in acelasi loc.

Membrii MqlTradeRequest:

Camp Tip Descriere
action ENUM_TRADE_REQUEST_ACTIONS Tipul operatiunii
magic ulong Numar care identifica expertual sau specifica un inteles al ordinului.
order ulong Tichetul ordinului. Este folosit pentru modificarea ordinelor pending.
symbol string Simbolul ordinului. Nu este necesar pentru operatiile de modificare a ordinului si de inchidere a pozitiei.
volume double Volumul solicitat, in loturi. De notat ca volumul real al afacerii va depinde de tipul executiei.
price double Pretul la care trebuie sa se ajunga ca ordinul sa fie executat. Pentru ordinele de piata se foloseste tipul TRADE_ACTION_DEAL, si nu e necesara definirea unui pret.
stoplimit double valoarea pretului, la care ordinul pending stopLimit va fi plasat, cand pretul atinge valoarea price (aceasta conditie este obligatorie). Pana atunci ordinul nu este plasat.
sl double Pretul Stop Loss in caz de evolutie nefavorabila a pretului.
tp double Pretul Take Profit in caz de evolutie favorabila a pretului.
deviation ulong Valoarea maxima a deviatiei pretului, specificata in puncte
type ENUM_ORDER_TYPE Tipul ordinului
type_filling ENUM_ORDER_TYPE_FILLING Tipul executiei ordinului
type_time ENUM_ORDER_TYPE_TIME Timpul executiei ordinului
expiration datetime Momentul expirarii ordinului (pentru ordinele de tip ORDER_TIME_SPECIFIED)
comment string Comentariul ordinului

Dupa cum se vede, o noutate in T5 este tichetul facut de utilizator, spre deosebire de MT4 unde serverul asigna tichete ordinelor. Pana la un punct, tichetul poate juca rol de magic secundar, sau chiar isi poate inversa rolul cu magicul, dar totusi sugerez folosirea momentului lansarii pe post de tichet.

Membrii MqlTradeResult:

Identificator Tip Descriere
retcode uint Codul rezultant intors de la server
deal ulong Tichetul afacerii, daca afacerea a fost confirmata. Este disponibil pentru tranzactiile de tip TRADE_ACTION_DEAL.
order ulong Tichetul ordinului, daca un tichet a fost plasat. Este disponibil pentru tranzactiile de tip TRADE_ACTION_PENDING
volume double Volumul afacerii, confirmat de broker. Depinde de tipul executiei ordinului
price double Pretul afacerii, confirmat de broker. Depinde de campul deviation si/sau de tipul tranzactiei.
bid double Pretul Bid de piata (recotat)
ask double Pretul Ask de piata (recotat)
comment string Comentariul brokerului la operatiune (de regula cuprinde descrierea operatiei)

Cel mai important camp aici este retcode , care este raspunsul serverului. Acesta preia sarcinile de la functia GetLastError() din MQL4. Pe baza acestui retcode vom scrie versiuni “de incredere” ale lui OrderSend() cum am facut si in MQL4, tratand din ce in ce mai multe erori de executie. Urmeaza deal si order, care arata sistemul pozitional chiar din structura. Ordinele care sunt trimise ca TRADE_ACTION_DEAL, adica ordinele de piata, nu au o perioada de viata propriu-zisa, pentru ca exista doar pana cand sunt acceptate de broker, adica maximum 1-2 secunde (asta presupunand ca brokerul chiar te uraste). De aceea tichetul lor, specificat de trader in structura MqlTradeRequest se intoarce pe campul deal , nu pe campul order.
volume e un un camp chiar interesant. Volumul se comporta in functie de cum a fost setata executia. De xemplu, daca ordinul nu poate fi executat in intregime, si campul spune exact cat anume a fost executat. Intrebarea ramane, daca un ordin pending are o executie partiala, cum va fi ea raportata in timp real ? OnTrade() nu are parametri ca sa raporteze executiile. Deisgur un ordin pending nu ar trebui sa aiba o executie partiala, pe Nivelul I. Pentru ca ordinul era deja acolo cand piata l-a atins pe linia de executie. Dar daca am fi pe Nivelul II, o mare parte din executiile ordinelor pending (care sunt, asa cum am zis mai inainte, langa piata) executiile sunt in cea mai mare parte partiale. Si OnTrade() trebuie sa fie imbunatatit ca sa trimita datele de executie in timp real catre programul apelant.
Campul pret este folositor, continand pretul confirmat. In MQL4 ar fi trebuit sa selectezi ordinul si sa fi extras pretul real de deschidere cu OrderOpenPrince(), asa ca acest camp scurteaza cautarea.
Campurile bid si ask au roluri mai mult informationale, la fel ca si comment.

Pozitii

Nu voi explica din nou cum functioneaza pozitiile, pentru ca am facut asta in Partea I a articolului. Prima functie care trebuie sa fie cunoscuta este PositionsTotal() care intoarce numarul de pozitii deschise. Similar cu OrderSelect() si OrderGetTicket() avem acum functiile echivalente pentru pozitii PositionSelect() si PositionGetSymbol(). Amandoua selecteaza o pozitie cu care sa se lucreze mai departe.

Functia PositionSelect() are urmatorul prototip:

1
2
3
4
bool  PositionSelect(
   string  symbol      // Simbol
   uint    timeout=0   // Timeout in milisecunde
   );

Chiar arata ca OrderSelect(), nu ? Solicita un simbol si un timeout. Similar si cu PositionGetSymbol(), care admite ca parametru index pozitiei in pozitiile curent deschise.
Apoi, urmeaza functiile de interogare a pozitiilor, pe acelasi model ca cele pentru ordine: PositionGetDouble(), PositionGetInteger(), PositionGetString(). Au cam acelasi prototip, cu diferenta ca parametrul principal e de tip
ENUM_POSITION_PROPERTY_DOUBLE, ENUM_POSITION_PROPERTY_STRING sau ENUM_POSITION_PROPERTY_INTEGER.

ENUM_POSITION_PROPERTY_DOUBLE

Identificator Descriere Tip rezultat
POSITION_VOLUME Volumul pozitiei double
POSITION_PRICE_OPEN Pretul de deschidere al pozitiei double
POSITION_SL Nivelul Stop Loss al pozitiei double
POSITION_TP Nivelul Take Profit al pozitiei double
POSITION_PRICE_CURRENT Pretul curent pentru instrumentul pozitiei double
POSITION_COMMISSION Comisionul double
POSITION_SWAP Swap (dobanda) cumulata double
POSITION_PROFIT Profitul curent double

Acum chiar trebuie sa intelegi de ce POSITION_PRICE_OPEN trebuie sa fie o medie ponderata. Sa zicem ca deschizi 1 lot de cumparare la 1.3000 si 3 loturi la 1.3300. Dupa ce faci asta, pozitia ta va fi de cumparare 4 loturi. Daca piata merge in jos 1.3100, vei fi in pierdere. Daca pozitia e de cumparare 4 loturi, cu deschidere la 1.3000, n-ar avea niciun sens sa fie in pierdere la 1.3100. De aceea pretul de deschidere trebuie sa fie o medie ponderata, pentru ca rezultatele sa aiba o interpretare corecta.

ENUM_POSITION_PROPERTY_INTEGER

Identificator Descriere Tip rezultat
POSITION_TIME Momentul deschiderii pozitiei datetime
POSITION_TYPE Tipul pozitiei ENUM_POSITION_TYPE (poate fi POSITION_TYPE_BUY sau POSITION_TYPE_SELL)
POSITION_MAGIC Numarul magic al pozitiei long

ENUM_POSITION_PROPERTY_STRING

Identificator Descriere Tip rezultat
POSITION_SYMBOL Simbolul pozitiei string
POSITION_COMMENT Comentariul pozitiei string

Dintre aceste proprietati, cele mai ciudate par a fi POSITION_MAGIC si POSITION_COMMENT. Aceste sunt proprietati legate de ordine, pentru ca fiecare ordin are propriul lui sens. Pozitia in sine este un rezultat al ordinelor. De unde rezulta ca POSITION_MAGIC si POSITION_COMMENT coincid cu ultima executie a unui ordin pe simbolul respectiv.

Istoric

MetaQuotes a inclus doua cai de citire a istoricului : afacerile (tranzactii incheiate), insemnand modificari trecute ale pozitiei, la fel ca si vechiul stil MQL4, istoricul ordinelor. Spre deosebire de istoricul ordinelor in MQL4, acum perioada studiata trebuie sa fie selectata cu HistorySelect(). Functia primeste doi parametri datetime: date_from and date_to. Asta face ca functia sa fie folositoare pentru cazul in care OnTrade() nu va fi modificat si nu va raporta care ordin este executat, pentru ca masa ordinelor care trebuie sa fie scanate devine foarte mica. Desigur, from_date poate fi zero, de unde rezulta ca tot istoricul va fi selectat. Dar e mai bine sa se tina o evidenta cu timpul cand s-a facut ultima scanare, astfel ca numai noile executii sa fie scanate, poate chiar dupa ultima executie. Pe de alta parte, to_date are un inteles interesant acum, pentru ca sunt doua functii care se ocupa cu timpul serverului. Una este din MQL4, si anume TimeCurrent(), care intoarce ultimul timp cunoscut al serverului, si una noua, TimeTradeServer(), care face acelasi lucru, dar are rezultate mai precise, pentru ca foloseste timpul local al computerului, dar da rezultate pe acelasi fus orar ca si TimeCurrent().

Odata ce selectia s-a facut, avem: numarul total de tranzactii incheiate, ce poate fi extras cu HistoryDealsTotal(), tichetul per index, selectabil cu HistoryDealGetTicket(), si functia obisnuita de selectie HistoryDealSelect() ; aceastea doua au aceeasi sintaxa ca OrderGetTicket() si OrderSelect(). Functiile de solicitare de date sunt similare cu functiile de la ordine, si astfel avem HistoryDealGetDouble, HistoryDealGetInteger(), HistoryDealGetString().

ENUM_DEAL_PROPERTY_DOUBLE

Identificator Descriere Tipul rezultatului
DEAL_VOLUME Volumul tranzactiei double
DEAL_PRICE Pretul tranzactiei double
DEAL_COMMISSION Comisionul tranzactiei double
DEAL_SWAP Swapul cumulativ la inchidere double
DEAL_PROFIT Profitul tranzactiei double

ENUM_DEAL_PROPERTY_INTEGER

Identificator Descriere Tipul rezultatului
DEAL_ORDER Numarul ordinului tranzactiei long
DEAL_TIME Momentul tranzactiei datetime
DEAL_TYPE Tipul tranzactiei ENUM_DEAL_TYPE (poate fi DEAL_TYPE_ ..BUY, ..SELL, ..BALANCE, ..CREDIT, ..CHARGE, ..CORRECTION)
DEAL_ENTRY Intrarea pozitiei ENUM_DEAL_ENTRY (poate fi DEAL_ENTRY_ ..IN, ..OUT, ..INOUT, ..STATE
DEAL_MAGIC Numarul magic al pozitiei (vezi ORDER_MAGIC) long

ENUM_DEAL_PROPERTY_STRING

Identificator Descriere Tipul rezultatului
DEAL_SYMBOL Simbolul tranzactiei string
DEAL_COMMENT Comentariul tranzactiei string

De exemplu, dupa ce am lansat urmatoarele ordine (manual) pe contul demo:

Sell EURUSD 0.1 lots @ 1.41548
Sell EURUSD 0.3 lots @ 1.41600
Buy EURUSD 0.5 lots @ 1.41647
Sell EURUSD 0.1 lots @ 1.41648

am rulat urmatorul script ca sa vad ce e in istoricul tranzactiilor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//+------------------------------------------------------------------+
//|                                                 History Test.mq5 |
//|                                       Copyright Bogdan Caramalac |
//|                                           http://mqlmagazine.com |
//+------------------------------------------------------------------+
#property copyright "Bogdan Caramalac"
#property link "http://mqlmagazine.com"
#property version "1.02"
 
#property script_show_inputs
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string EnumDealEntry(long e)
  {
   switch(e)
     {
      case DEAL_ENTRY_IN:
         return("DEAL_ENTRY_IN          ");
      case DEAL_ENTRY_INOUT:
         return("DEAL_ENTRY_INOUT  ");
      case DEAL_ENTRY_OUT:
         return("DEAL_ENTRY_OUT       ");
      case DEAL_ENTRY_STATE:
         return("DEAL_ENTRY_STATE  ");
      default:
         return("DEAL ENTRY UNKNOWN");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string EnumDealType(long t)
  {
   switch(t)
     {
      case DEAL_TYPE_BUY:
         return("DEAL_TYPE_BUY           ");
      case DEAL_TYPE_SELL:
         return("DEAL_TYPE_SELL          ");
      case DEAL_TYPE_BALANCE:
         return("DEAL_TYPE_BALANCE   ");
      case DEAL_TYPE_CREDIT:
         return("DEAL_TYPE_CREDIT    ");
      case DEAL_TYPE_CORRECTION:
         return("DEAL_TYPE_CORRECTION");
      default:
         return("DEAL TYPE UNKNOWN   ");
     }
  }
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
  {
   long ticket;
   int deals=HistoryDealsTotal();
   datetime from_date=0;
   datetime to_date=TimeTradeServer();
   HistorySelect(from_date,to_date);
   deals=HistoryDealsTotal();
   Print("Total history deals=",HistoryDealsTotal());
 
   for(int i=deals-1;i>=0;i--)
     {
      ticket=HistoryDealGetTicket(i);
      Print("   ",i,"      ",DoubleToString(HistoryDealGetDouble(ticket,DEAL_VOLUME),2)," ",
                EnumDealType(HistoryDealGetInteger(ticket,DEAL_TYPE))," ", 
                DoubleToString(HistoryDealGetDouble(ticket,DEAL_PRICE),SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))," ",
                EnumDealEntry(HistoryDealGetInteger(ticket,DEAL_ENTRY))," ",
                DoubleToString(HistoryDealGetDouble(ticket,DEAL_PROFIT),2));
     }     
   Print("Index  Volume           Type              Price                           Entry                     Profit");
  }
//+------------------------------------------------------------------+

Si rezultatul este:

Testare Deals History

Desigur, cum am spus mai devreme, vechiul stil al istoricului a fost pastrat. Functiile care lucreaza cu istoricul ordinelor sunt: HistoryOrdersTotal(), HistoryOrderSelect(), HistoryOrderGetTicket(), HistoryOrderGetDouble(), HistoryOrderGetInteger(), HistoryOrderGetString(). Toate se supun functiei HistorySelect(), exceptie facand HistoryOrderSelect(). Parametrii functiilor sunt aceiasi ca la functiile care lucreaza cu ordinele curente.

Leave a Reply