Sari la conținut

Trecerea la MQL5


Cityzen

Postări Recomandate

Topic deschis pentru cei care vor sa treaca de la mql4 la mql5.

 

Asa cum probabil stiti exista schimbari considerabile in noua versiune a limbajului de programare de la metaquotes. Desi sunt altii pe forum mai experimentati si cu mai multe cunostinte, am sa incep cu exemple simple ce iau in considerare diferentele dintre mql4 si mql5. Pe parcurs sper sa intervina si "specialistii" in domeniu iar daca pe parcurs mai apar intrebari sau probleme de rezolvat, sunt convins ca pana la urma se vor gasi si raspunsurile si solutiile.

Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

Marea majoritate a expertilor folosesc in concepte de trading parametrii fie de la indicatori fie de la valorile lumanarilor. Jonglarea cu astfel de parametrii se schimba in mql5. Daca inainte exista acces direct la astfel de valori prin functii de genul iClose, iHigh, iMACD, iStochastic etc. de data aceasta astfel de valori trebuie asociate intr-un handler si ulterior copiate intr-un buffer de tip array.

 

Incepem cu datele lumanarilor Open, Close, High, Low. In mql4 existau functii specifice ce returnau valorile dorite iHigh, iLow etc.

 

Urmatorul exemplu copiaza ultimele 70 valori pentru inchiderea, minimul si maximul lumanarilor

 

int i,j,count;
double 	Low[70], High[70], Close[70], Temp[70]; 
string symbol=EURUSD; // aceasta este perechea pentru care se copiaza valorile. symbol poate fi inlocuit cu NULL insa nu si pentru ea-uri multicurrency 
ENUM_TIMEFRAMES TF=PERIOD_CURRENT; //aceasta este perioada de timp pentru care se copiaza valorile. 
           		// PERIOD_CURRENT va returna time frame-ul curent al graficului insa poate fi inclocuit cu orice tf

//get lows--------------
  	CopyLow(symbol,TF,0,70,Temp);
  	i=0;j=69;
  	while (i<70)
 		{
 		Low[i]=NormalizeDouble(Temp[j],SymbolInfoInteger(symbol,SYMBOL_DIGITS));
 		i++;
 		j--;
 		}
  	//end get lows--------------
  	//get highs
  	CopyHigh(symbol,TF,0,70,Temp);
  	i=0;j=69;
  	while (i<70)
   		{
   		High[i]=NormalizeDouble(Temp[j],SymbolInfoInteger(symbol,SYMBOL_DIGITS));
   		i++;
   		j--;
   		}
  	//end get highs
  	//get close
  	CopyClose(symbol,TF,0,70,Temp);
  	i=0;j=69;
  	while (i<70)
   		{
   		Close[i]=NormalizeDouble(Temp[j],SymbolInfoInteger(symbol,SYMBOL_DIGITS));
   		i++;
   		j--;
   		}
  	//end get close

functiile de tip copy (CopyBuffer, CopyLow, CopyHigh etc.) copiaza valorile de la cap la coada si pentru inversarea lor am folosit un array temporar Temp.

Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

Acelasi lucru pentru un moving average se va face mai intai prin creerea unui handle si apoi prin copierea valorilor cu ajutorul CopyBuffer

 

Acest exemplu copiaza ultimele 20 de valori ale unei moving average smoothed de 13 cu shift de 8 calculata dupa pret median (H+L)/2

TF si symbol le recunoasteti din postul anterior.

 

int i,j,count;
double MA_Buffer_Temp[20], Ma_Buffer[20];
double MA_handle=iMA(symbol,TF,13,8,MODE_SMMA,PRICE_MEDIAN);

  	CopyBuffer(MA_handle,0,0,20,MA_Buffer_Temp);
  	i=0;j=19;
  	while (i<20)
        	{
        	MA_Buffer[i]=NormalizeDouble(MA_Buffer_Temp[j],2);
        	i++;
        	j--;
        	}
Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

O procedura ce returneaza tipul pozitiei, care va fi folosita in procesul de trimitere al unui ordin nou.

 

#define FLAT    	0
#define LONG    	1
#define SHORT   	2
 

//getposition type 
int GetPositionType(string symbol)
  {
   bool sel=PositionSelect(symbol);
   if (sel==false)
 	return(FLAT);
   else
	{
 	int p=PositionGetInteger(POSITION_TYPE);
 	if (p==POSITION_TYPE_BUY)
   	return(LONG);
 	else
   	return(SHORT);
	}
  }

In mql5 se schimba radical si felul in care se trimit ordere. Urmatoarea secventa trimite un ordin nou in piata. Functia ce calculeaza volumul nu este inclusa in acest post, se presupune ca ea exista deja. A nu se uita ca in mt5 nu poate exista decat o pozitie pe un singur simbol, astfel, aceasta procedura verifica daca exista deja o pozitie pe simbol si in functie de asta calculeaza volumul pentru noul ordin in cazul in care acesta e in sens invers fata de pozitia deja existenta.

 

#define FLAT    	0
#define LONG    	1
#define SHORT   	2

//order send
void OrderSend(string symbol,int operation)
  { 
   if (operation==FLAT) return; 
   MqlTradeRequest request;
   MqlTradeResult result;
   int p=GetPositionType(symbol);
   double current_volume,v0;
   if (PositionSelect(symbol)==true)
    	current_volume=PositionGetDouble(POSITION_VOLUME);
   else
    	current_volume=0;
   request.action=TRADE_ACTION_DEAL;
   request.symbol=symbol; 
   request.deviation=Slippage;
   request.type_filling=ORDER_FILLING_AON;
   request.type_time=ORDER_TIME_GTC;
   if (operation==LONG)
  	{
  	request.type=ORDER_TYPE_BUY;
  	request.price=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_ASK),SymbolInfoInteger(symbol,SYMBOL_DIGITS));
  	if (p==SHORT) request.volume=current_volume+Volume(symbol); 
 		else request.volume=Volume(symbol); 
  	}
   if (operation==SHORT)
  	{
  	request.type=ORDER_TYPE_SELL;
  	request.price=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_BID),SymbolInfoInteger(symbol,SYMBOL_DIGITS));
  	if (p==LONG) request.volume=current_volume+Volume(symbol); 
 		else request.volume=Volume(symbol); 
  	}
	OrderSend(request,result);  	
	PositionSetSLTP(symbol,StopLoss);
  }

 

Aceasta secventa este pentru a pune stop loss si take profit.

//sltp
void PositionSetSLTP(string symbol ,double sl, double tp)
  {
   bool todo;
   MqlTradeRequest request;
   MqlTradeResult result;   
   int p=GetPositionType(symbol);
   if (p==LONG||p==SHORT)
  	{
  	request.action=TRADE_ACTION_SLTP;
  	request.symbol=symbol;   
  	todo=false;
  	if (DoubleToString(sl,1)!="0.0")
    	{
 		todo=true;  	
   		request.sl=NormalizeDouble(sl,SymbolInfoInteger(symbol,SYMBOL_DIGITS));
    	}
  	if (DoubleToString(tp,1)!="0.0")
    	{
 		todo=true;  	
 		request.tp=NormalizeDouble(tp,SymbolInfoInteger(symbol,SYMBOL_DIGITS));
    	}
  	request.deviation=Slippage;   
  	if (todo==true)
    	OrderSend(request,result);
  	}
  }

Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

@Citizen

Precizez ca nu sunt "specialist". Dar am cateva intrebari.Intrebarile de mai jos sunt strict legate la postul #4.

1.Ce rost are functia GetPositionType avand in vedere ca funtia PositionGetInteger(POSITION_TYPE) face aproximativ acelasi lucru numai ca nu intoarce LONG,SHORT si FLAT?

2.long p=PositionGetInteger(POSITION_TYPE); De ce long?(8 bytes)Un int(4bytes) ar fi fost suficienti ba chiar short (2bytes) daca esti zgarcit ca mine.

Functia OrderSend este extrem de complicata si nu prea o inteleg

3.request.symbol=SymbolsTable[asset_index].Symbol; .Aici da eroare.Cine e asset_index?(nu prea il vad declarat pe nicaieri.De ce ai nevoie sa ii trimiti lui request.symbol chestia aia cand symbol este parametru al functiei tale?Nu ar trebui ca symbol sa fie acelasi lucru cu SYmbolTable(asset_index].Symbol.Aici ar mai fi intrebari dar cred ca nu am inteles eu rolul functiei si de acea nu mai pun nici o intrebare.

Functia PositionSetSLTP

4.De ce e nevoie la if-ul ala sa folosesti functia aia cu DoubleToString cand puteai sa compari cu 0.0?Daca simbolul e de forma x.xx sau x.xxx (2 sau 3) zecimale si trimit SL sau TP ca 1.22 sau 1.223 functia nu prea o sa seteze nimic pt ca nu o sa intre in if-urile alea.

 

//Later

Se pare ca la patru am gresit pt ca daca pretul este cu mai putine zecimale functia DoubleToString umple cu zerouri pana numarul are numarul de zecimale specificat ca parametru al functiei , dat tot nu este inregula la preturile cu 5 zecimale.

Editat de Mangusta
Link spre comentariu
Distribuie pe alte site-uri

Mangusta multumesc ca m-ai verificat si ca ma corectezi. Eu te consider specialist.

1. Este utila cand vrei sa verifici direct daca este flat, adica daca nu este nici o pozitie. PositionGetInteger(POSITION_TYPE) vad ca are doar doua variante pentru buy si sell, nici nu stiu daca nu da eroare in caz ca nu exista pozitie deschisa.

2. ai dreptate. un int este suficient, cat despre order send... este de doua ori mai simpla fata de cea care am avut-o initial. Presupun ca stii deja de unde o aveam si nu mai fa pe modestul ca stim toti ca esti programator bun, nu ca mine.

3. secventele sunt copiate dintr-un ea mai complex si modificate pentru a fi simplificate. In procesul de modificare/simplificare se pare ca am sarit peste unele. Acum am modificat si nu ar trebui sa mai dea eroare.

4. Ce bine ca m-ai atentionat. :) O sa modific.

 

Eu sunt incepator. Am facut doar un pas. Topicul l-am deschis pentru cei ca mine care sunt la inceputurile in mql5. Multumesc inca o data pentru interventie si sper sa o mai faci. Sincer eu personal m-as fi bucurat daca altcineva ar fi inceput un astfel de topic, altcineva ca si tine sau tradelover care sunteti intradevar programatori. Am vazut ca nu se inghesuie lumea si de aceea m-am gandit sa deschid eu subiectul cu ce mi-a reusit pana acum. Eram convins ca sunt altii care vad si inteleg lucrurile mai bine ca si mine dar mi-am asumat aceasta raspundere deoarecere chiar consider ca e un subiect foarte important din care multi ca mine ar putea sa invete ceva folositor.

Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

@Cityzen

Am vazut si eu ca nu prea se inghesuie lumea la mql si de aceea stau pe bara si ma uit.Imi e greu sa deschid un topic despre lucrurile pe care le stiu despre mql5 pentru ca imi e ca o sa postez numai eu si o sa fac un monolog de toata frumusetea.Pentru monologuri scriu articole pe mqlmagazine :). Dar raspund cu toata placerea cand posteaza cineva in sectiunea mql pe forum.

 

Ce nu imi place la functia PositionSetSLTP.Nu imi place ca este void.Eu as fi facut-o int si sa imi intoarca result.retcode ca sa stiu si eu daca OrderSend a fost executat cu succes.Sau daca ar fi void as fi "semnalat" eroarea din interiorul functiei in caz de exsita.

 

Cum as fi facut eu functia :

#define POSITION_TYPE_FLAT 3
int GetPositionType(string symbol)
  {
   if (PositionSelect(symbol)==false)
        return(POSITION_TYPE_FLAT);
   else
        {
        return(PositionGetInteger(POSITION_TYPE));
        }
  }

Functia mea este mai rapida decat a ta si consuma cu un byte mai putin :D .Este mai rapida pt ca nu am 2 if-uri si nu am mai consuma byteul pt ca nu declar variabila "sel".

In principiu desi timpul de executie este la mai putin de jumate decat functia originala nu am castigat mare lucru pt ca timpul este insesizabil pt calculatoarele din ziua de azi.Daca folosesc functia intr-o bucla castig ceva timp.La un expert o secuda este importanta pentru ca intr-o secunda pretul se schimba de zeci de ori ,desi brokerul ca sa faca trafic mai mic de date trimite doar o parte dintre cotatii.

Editat de Mangusta
Link spre comentariu
Distribuie pe alte site-uri

Imi place foarte mult cum gandesti. Vezi exact la asta ma gandeam cand am deschis topicul. Ma bucur daca oameni mai specialisti isi fac timp sa se implice aici pe forum, mai invatam si noi cate ceva.

 

Eu am simplificat functia aia order send dar acum vad ca de fapt poate sa fie si mai simpla.

 

Referitor la order send este bucata asta:

 

if (p==LONG&&operation==FLAT)
    	{   	
   		request.volume=current_volume;
 		request.type=ORDER_TYPE_SELL; 		
 		 request.price=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_BID),SymbolInfoInteger(symbol,SYMBOL_DIGITS));  		
    	}
  	if (p==SHORT&&operation==FLAT)
    	{
   		request.volume=current_volume;
 		request.type=ORDER_TYPE_BUY; 		
 		 request.price=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_ASK),SymbolInfoInteger(symbol,SYMBOL_DIGITS));  		
    	}

Nu pot sa o inlocuiesc cu

if (operation==flat) return;

??

Editat de Cityzen
Link spre comentariu
Distribuie pe alte site-uri

Trebuie sa inlocuiesti daca vrei sa nu iti dea eroarea 10014 | TRADE_RETCODE_INVALID_VOLUME | Invalid volume in the request.O sa trimiti ordin cu volum=0.

 

Te sfatuiesc sa rescrii codul functiei OrderSend de la 0 sau sa il parcurgi.Are multe greseli.O sa ridic eu cateva intrebari.

1.Care diferenta intre if (operation==flat) return; si if (operation==FLAT);.Daca vor sa reprezinte acelasi lucru sa stii ca 'FLAT' nu este acelasi lucru cu 'flat'.Intr-un cod precedent am aflat cine este 'FLAT'.Pt ca nu il vad definit 'flat' cred ca este o constanta definica cu #define.(daca nu e crapa codul)

Din cate imi dau eu seama LONG reprezinta si un tip de ordin si un tip de pozitie.Te sfatuiesc sa schimbi conceptul ca o sa il incurci.

Fa update la codul functie te rog ca nu imi sunt clare unele lucruri.Fa update dupa ce trece de compilator daca se poate daca nu spune unde da erori.

Link spre comentariu
Distribuie pe alte site-uri

  • Moderators

.. eu personal m-as fi bucurat daca altcineva ar fi inceput un astfel de topic, altcineva ca si tine sau tradelover care sunteti intradevar programatori...

 

Sorry ca trebuie sa va dezamagesc, eu la MQL5 sund deocamdata in faza in care imi dau seama de capacitatile lui, dar departe de a fi un profesionist. Abia il invat si eu, ba chiar pot spune ca am invatat uunele chestii noi chiar din discutiile voastre anterioare, pentru care va multumesc cu toata sinceritatea. Imi este destul de greu sa ma despart de MT4, precum spuneam anterior, am o gramada de tools-uri, indicatori, biblioteci, etc. scrise in MQL4, ar lua mult timp sa le portez, in plus prefer sa astept visual-testerul de la MT5 inainte de a face pasii decisivi. Daca nu era ATC-ul probabil ca personal, inca nu comentam nimic de MT5 inca, pana nu ma mana nevoia de la spate, cum am facut si cand am trecut de la 3.8 la 4, pana nu au renuntat brokerii la 3.8, si nu am mai avut ce face, nu m-am urnit la 4. Stiti chestia aia, sunt greu batranii de pornit... hihi...

Link spre comentariu
Distribuie pe alte site-uri

Alătură-te conversației

Poți posta acum și să te înregistrezi mai târziu. Dacă ai un cont, autentifică-te acum pentru a posta cu contul tău.

Vizitator
Răspunde la acest subiect...

×   Alipit ca text avansat.   Alipește ca text simplu

  Doar 75 emoji sunt permise.

×   Linkul tău a fost încorporat automat.   Afișează ca link în schimb

×   Conținutul tău precedent a fost resetat.   Curăță editor

×   Nu poți lipi imagini direct. Încarcă sau inserează imagini din URL.

  • Navigare recentă   0 membri

    • Nici un utilizator înregistrat nu vede această pagină.
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.