Radu MetaTrader a blogja | További ingyenes és hasznos eszközök MetaTraderhez | Kérdésed merült fel? Kérdezz!
MQL4 Könyv tartalomjegyzék | Stratégiák programozása MetaTrader platformra | Fogalomtár | Gyakran Ismételt Kérdések

MQL4 könyv    Beépített függvények   String függvények


String függvények

 

A string értékekkel végzett leggyakoribb műveletet az összeadást (összefűzést) megtárgyaltuk az Operations and Expressions (Problem 3részben. Néhány esetben szükség van a string értékekkel végrehajtott egyéb műveletekre is. Az MQL4-ben van néhány függvény a string típusú változókkal végrehajtott műveletekre. Vizsgáljuk meg néhányuk használatát a lenti példán keresztül!
35. feladat: Színezd az utolsót 100 bár gyertyáját a következők szerint: a fekete gyertyákat pirosra, fehér gyertyákat kékre.

Egy gyertyát két vonallal lehet kiszínezni: egy vékony vonallal meg kell rajzolni a gyertya árnyékát, egy vastag vonallal pedig ki kell tölteni a gyertyatestet. Ebben az esetben, nem tudjuk használni egy egyéni indikátor vonalait sem, mert a rajzolt vonalaknak függőlegeseknek kell lenniük, vagyis e vonalak felépítéséhez két árkoordinátát kell meghatározni (ugyanazzal az idő koordinátával), azonban az indikátorvonalak esetén minden bárhoz csak egy árérték tartozhat. Tehát a probléma megoldása az, hogy különálló függőleges vonalakat rajzolunk az OBJ_TREND függvénnyel, meghatározott koordinátákkal, vonalstílussal és színekkel, (lásd: Grafikus objektumok).

Ebben az esetben egy EA alkalmazási programot használunk, de általában az algoritmust megvalósíthatjuk egy egyéni indikátorban is. Az egész algoritmus egyszerű. Az ábrát egyből ki kell színezni, mikor az EA-t csatoljuk a szimbólumablakhoz (az init() végrehajtása alatt). A programnak a grafikus objektumok helyzetében bekövetkező minden változást követnie kell (a felhasználó véletlenül törölheti vagy elmozdíthatja őket) minden tick érkezésekor, ha szükséges vissza kell állítani az objektumokat. Minden objektumot, amit a program létrehozott, törölni kell, amint a programot eltávolítjuk (deinit()).

A felhasználó egyéb objektumokat is létrehozhat a szimbólumablakban amíg ez az EA dolgozik, regressziós csatornát, Fibo szinteket, támaszvonalakat, stb. Ez az algoritmus lehetővé teszi, hogy megkülönböztessünk a felhasználó által létrehozott és a program által létrehozott objektumokat. Ez különösen a program befejezésekor fontos: csak a program által megalkotott objektumokat szabad eltávolítani, a felhasználó által létrehozott objektumoknak változatlanoknak kell maradniuk. A grafikus objektumoknak vannak olyan tulajdonságaik, amik megegyezhetnek más objektumok tulajdonságaival. Minden objektumot konkrétan azonosíthatunk az egyedi azonosító nevével (ugyanazon név többszörös  használata tilos).

Az objektumnak ajánlott olyan nevet választani, hogy az hasznos információt tartalmazzon, amely név jelzi az objektum helyét és tulajdonságait. Például egy objektumnév tartalmazhat egy olyan prefixumot, ami  megkülönböztet egy program által létrehozott objektumot más objektumoktól. Ebben az esetben ez a ”Paint_”. Azon kívül meg kell különböztetni a felhasználó által létrehozott objektumokat az egyéb objektumtól. Az egyszerű sorszámozás (Paint_1, Paint_2) nem használható. Ha ezt a módszert használjuk az objektumok számozására, akkor nem állapíthatjuk meg belőle pl. azt, hogy a Paint_73 objektumot melyik báron kell megjeleníteni. Arra a bárra, amelyen most a Paint_73 indexű objektum, az új bár érkezésekor a Paint_74 objektum kerül, majd a következő új bár kezdetekor a  Paint_75, stb. Ebben az esetben törölni kellene, és újra kellene számolni minden objektumot minden egyes új bár kezdetekor. Ez a megoldás (bár ez lehetséges) nyilvánvalóan nagyon durva és erőforrás-pazarló.

Minden objektumot a bár nyitás ideje alapján nevezünk el, ami megegyezik az objektum időkoordinátájával. Azon kívül minden bárra két vonalat kell rajzolni, egy vékonyat és egy vastagot. Legkényelmesebb a nevek követésére, ha az objektumokat a program nevezi el:

Az objektum neve = Paint_2_2007.03.22 16:40, ahol:

Paint_ - előtag, ami jelzi, hogy az objektumot a program hozta létre;

2_ - a rajzolandó objektumazonosító száma, (értéke 1vagy 2 lehet);

2007.03.22 16:40 - időkoordináta, ami egyértelműen jelzi a bárt, amelyre az objektumot rajzolni kell.

A Paint_ és a 2_ a Prefix illetve Nom_Lin változók értékei. Az időkoordinátákat a bárok nyitási idejének string típusú értékre konvertálással kapjuk a következő függvénnyel:

TimeToStr() függvény

string TimeToStr(datetime value, int mode=TIME_DATE|TIME_MINUTES)

A függvény átalakítja az 1970.01.01. –óta másodpercekben eltelt időt (datetime típust) a meghatározott dátum/idő formátumra (string típusra).

Paraméterek:

value - a másodpercekben eltelt idő 1970. január 1. 00:00 óta;

mode – a kimenő adat formátuma. Egy egyszerű vagy összetett flag:

TIME_DATE  - a kimenő adat formátuma yyyy.mm.dd;

TIME_MINUTES - a kimenő adat formátuma  hh:mi;

TIME_SECONDS - a kimenő adat formátuma hh:mi:ss.

 

Nézzük, hogy a strings.mq4 EA hogyan kezeli gyertyák színezését és hogyan használja a TineToStr() függvényt ebben a programban:
//--------------------------------------------------------------------
// strings.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------- 1 --
extern int Quant_Bars=100; // Number of bars
datetime Time_On;
string Prefix ="Paint_";
//--------------------------------------------------------------- 2 --
int init() // Spec. function init()
{
int Ind_Bar; // Bar index
Time_On=Time [Quant_Bars]; // Time of first coloring
for(Ind_Bar=Quant_Bars-1; Ind_Bar>=0; Ind_Bar--)// Bars cycle
{
Create(Ind_Bar,1); // Draw a thin line
Create(Ind_Bar,2); // Draw a thick line
}
WindowRedraw(); // Image redrawing
return; // Exit init()
}
//--------------------------------------------------------------- 3 --
int start() // Spec. function start()
{
datetime T1, T2; // 1 and 2 time coordinates
int Error,Ind_Bar; // Error code and bar index
double P1, P2; // 1 and 2 price coordinates
color Col; // Color of created object
//--------------------------------------------------------------- 4 --
for(int Line=1; Line<=2; Line++) // Line type cycle
{
string Nom_Lin =Line + "_"; // String with the line number
// string Nom_Lin = DoubleToStr(Line,0)+"_";// Can be so
for(Ind_Bar=0; ;Ind_Bar++) // Bar cycle
{
//--------------------------------------------------------------- 5 --
datetime T_Bar= Time[Ind_Bar];// Bar opening time
if (T_Bar < Time_On) break; // Don't color out of borders
string Str_Time=TimeToStr(T_Bar); // Time string
string His_Name=Prefix+Nom_Lin+Str_Time;// Object name
//--------------------------------------------------------------- 6 --
T1=ObjectGet(His_Name,OBJPROP_TIME1);// t1 coord. query
Error=GetLastError(); // Error code receiving
if (Error==4202) // If there is no object :(
{
Create(Ind_Bar,Line); // Object creating function call.
continue; // To the next iteration
}
//--------------------------------------------------------------- 7 --
T2 =ObjectGet(His_Name,OBJPROP_TIME2); // t2 coord. query
P1 =ObjectGet(His_Name,OBJPROP_PRICE1);// p1 coord. query
P2 =ObjectGet(His_Name,OBJPROP_PRICE2);// p2 coord. query
Col=ObjectGet(His_Name,OBJPROP_COLOR); // Color query
if(T1!=T_Bar || T2!=T_Bar || // Incorrect coord. or color:
(Line==1 && (P1!=High[Ind_Bar] || P2!= Low[Ind_Bar])) ||
(Line==2 && (P1!=Open[Ind_Bar] || P2!=Close[Ind_Bar])) ||
(Open[Ind_Bar] Close[Ind_Bar] && Col!=Red) ||
(Open[Ind_Bar]==Close[Ind_Bar] && Col!=Green) )
{
ObjectDelete(His_Name); // Delete object
Create(Ind_Bar,Line); // Create correct object
}
//--------------------------------------------------------------- 8 --
}
}
WindowRedraw(); // Image redrawing
return; // Exit start()
}
//--------------------------------------------------------------- 9 --
int deinit() // Spec. function deinit()
{
string Name_Del[1]; // Array declaring
int Quant_Del=0; // Number of objects to be deleted
int Quant_Objects=ObjectsTotal(); // Total number of all objects
ArrayResize(Name_Del,Quant_Objects);// Necessary array size
for(int k=0; k<=Quant_Del; i++) // Delete objects with names..
ObjectDelete(Name_Del[i]); // .. that array contains
return; // Exit deinit()
}
//-------------------------------------------------------------- 10 --
int Create(int Ind_Bar, int Line) // User-defined function..
{ // ..of objects creation
color Color; // Object color
datetime T_Bar=Time [Ind_Bar]; // Bar opening time
double O_Bar=Open [Ind_Bar]; // Bar open price
double C_Bar=Close[Ind_Bar]; // Bar close price
double H_Bar=High [Ind_Bar]; // Bar maximum price
double L_Bar=Low [Ind_Bar]; // Bar minimum price

string Nom_Lin =Line + "_"; // String - line number
// string Nom_Lin = DoubleToStr(Line,0)+"_";// Can be so
string Str_Time=TimeToStr(T_Bar); // String - open time.
string His_Name=Prefix+Nom_Lin+Str_Time;// Name of created object
if (O_Bar < C_Bar) Color=Blue; // Choosing the color depending on..
if (O_Bar >C_Bar) Color=Red; // .. parameters of the bar
if (O_Bar ==C_Bar) Color=Green;

switch(Line) // Thin or thick line
{
case 1: // Thin line
ObjectCreate(His_Name,OBJ_TREND,0,T_Bar,H_Bar,T_Bar,L_Bar);
break; // Exit from switch
case 2: // Thick line
ObjectCreate(His_Name,OBJ_TREND,0,T_Bar,O_Bar,T_Bar,C_Bar);
ObjectSet( His_Name, OBJPROP_WIDTH, 3);// Style
}
ObjectSet( His_Name, OBJPROP_COLOR, Color); // Color
ObjectSet( His_Name, OBJPROP_RAY, false); // Ray
ObjectSetText(His_Name,"Object is created by the EA",10);// Description
return; // Exit user-defined function
}
//-------------------------------------------------------------- 11 --

A grafikus objektumok létrehozására a Create() felhasználói függvényt (10-11 blokk) használjuk a programban. Az Ind_Bar változó jelzi annak a bárnak az indexét, amelyen az objektumot létre kell hozni, a Line az objektum száma (1 vagy 2), a paramétereit ebben a függvényben kapja.

Az objektum neve három összetevőből áll:

 string His_Name = Prefix+Nom_Lin+Str_Time;// Name of created object

A Prefix változó értékét a programozó a program fejrészében adja meg, és az nem változik meg a program végrehajtása alatt:

string Prefix = "Paint_";

A Nom_Lin változó értéke számítások eredménye:

 string Nom_Lin = Line + "_"; // String - line number
// string Nom_Lin = DoubleToStr(Line,0)+"_";// Can be so

Itt az egész szám típusú változó típusa (a számítás alatt a kifejezés első része) átváltozik a magasabb prioritású string típussá. Végül a Nom_Lin a Lin változó értékétől függően 1_ vagy a 2_ értékeket kap.

Az  Str_Time változó értékének kiszámításához az adat átalakító TimeToStr() függvényt használjuk:

 string Str_Time = TimeToStr(T_Bar); // String - open time

Vedd észre, hogy a TimeToStr() függvénynek alapértelmezett értéke van. Ebben az esetben a következő értékekre van szükség: yyyy.mm.dd hh, nem szükséges a másodpercek használata, mert a minimális időkeret 1 perc.

Az objektum nevét alkotó Str_Time változó kiszámítására a következő módszert alkalmazhatjuk:

 string Str_Time = T_Bar;

Ebben az esetben a Str_Time érték egyenlő az1970.01.01. óta eltelt másodpercek számával. Azért, hogy a különbséget lássuk, írjunk és futtassunk egy olyan programot, ami a következő kódot tartalmazza:

int init()
{
string String_Time = TimeToStr(Time[0]); // Time in the format
string String_Sec = Time[0]; // Number of seconds
Alert("String_Time = ",String_Time," String_Sec = ",String_Sec);
return;
}

A következő üzenet (a nulla bár nyitási ideje) a programvégrehajtás során fog megjelenni a képernyőn:

String_Time = 2007.03.22 19:10 String_Sec = 1174590600

strings.mq4 EA első alternatívája sokkal informatívabb, ezért ezt a változatot részesítjük előnyben (a két alternatíva az algoritmus szempontjából egyenértékű).

A His_Name objektumot a Create() felhasználói függvény következő soraiban hozzuk létre. Ez tartalmazza a bár nyitás idejével kapcsolatos információt, és a bár jellemzőjétől függő "Line" paramétert, ami a vonal színét jellemzi. Szintén létrehozásra kerül az objektumok leírása minden egyes objektum esetén az"Object is created by EA" tartalommal.

A Create() függvényt a programban két helyről hívjuk: az init() különleges függvényből az objektumok legelső létrehozásakor, és a start() különleges függvényből az objektum újbóli létrehozására, ha azokat törölte vagy módosította  a felhasználó. Az objektum neveket a start() függvényben (4-6) ugyanazon módszerrel  alakítjuk, ki mint  a program többi részében.

A szóban forgó objektumok első koordinátáját a 6-7 blokkban határozzuk meg. Ha az objektum ekkor nem található meg, azt létre fogja hozni a Create() függvény. Ha az objektum létezik, a másik koordinátáját is meghatározza program és ellenőrzi, hogy az objektum paraméterei megfelelnek-e a bár paramétereinek (7-8 blokk). Az objektum törölve lesz es újra létre lesz hozva (ugyanazzal a névvel) a helyes tulajdonságokkal, ha bármilyen hibás illesztés van.

Egy másik feladat, amit a deinit() függvény végrehajtása alatt meg kell oldani: csak azokat az objektumokat szükséges törölni, a szimbólumablakban lévő összes objektum közül, amelyeket ez a program hozott  létre. Ennek a feladatnak a megoldása két lépésben történik: az első lépésben minden törlendő objektum nevét tároljuk a Name_Del[] tömbben, azután őket egy ciklusban törölni fogjuk. Az összes létező objektum számának meghatározására (beleértve a program által, és a felhasználó által kézzel létrehozott objektumokat is) az ObjectsTotal() függvénnyel határozzuk meg:

 int Quant_Objects=ObjectsTotal(); // Total number of ALL objects

A kiszínezendő bárok számát egy külső változóban határozza meg a felhasználó, ezért nem tudjuk előre, hogy hány objektumot kell törölni. Ezért azt a string tömböt, amelyik a törlendő objektumok nevét fogja tartalmazni 1 elemértékre, inicializáljuk. Később programozási módszerrel meghatározzuk az összes létező objektum számát és a tömb elemek számát erre az értékre növeljük.

 ArrayResize(Name_Del,Quant_Objects);// Necessary array size

Hogy megkülönböztessük azokat az objektumokat, amelyeket az EA hozott létre a deinit() függvény tartalmaz egy olyan ciklust, ami elemzi minden objektum nevét.

 string Obj_Name = ObjectName(k); // Querying name of the object

Az a sajátosság, ami megkülönbözteti az EA-nk által létrehozott objektumokat az összes többi objektumtól a névben szereplő Paint_ prefixum. Az objektum nevének elemzéséhez ki kell keresnünk az objektum nevének az elejét (ebben az esetben 6 karaktert) a string változóból és össze kell hasonlítani ezt az értéket a Prefix változóval. Ha azonosak, ezt az objektumot törölni kell. Ha nem, akkor nem kell törölni.

 

StringSubstr() függvény

string StringSubstr(string text, int start, int length=0)

A függvény kiemeli  a megadott pozíciónál kezdődő meghatározott hosszúságú részt a stringből, A függvény visszaküldi a kiemelt rész másolatát. Különben egy üres karakterláncot küld vissza.

Paraméterek:

text - az a string, amiből a string részt ki kell  emelni;

start - a kiemelendő rész kezdeti pozíciója. Értéke 0-tól StringLen(text)-1-ig terjedhet;

length - a kiemelendő rész hossza. Ha ennek a paraméternek az értéke kisebb vagy egyenlő mint 0, vagy nincs megadva, a szövegrészt a megadott pozíciótól a string végéig kiemeljük.

A szóban forgó példában a szövegrész (string részletet) a következőképpen nyerjük ki az objektum névből:

 string Head=StringSubstr(Obj_Name,0,6);// Extract first 6 symbols

Ebben az esetben a nullától számított első 6 karaktert kinyerjük az Obj_Name string változóból. Jegyezd meg: minden index számozása (bárok, tömbök), a megbízások listája 0-val kezdődik, míg a számszerűsített számolás 1-gyel kezdődik.

A kiemelt részt (egy string értéket) kapja a Head string változó. Ha az objektum nevet (és magát az objektumot) a szóban forgó EA hozta létre a kiemelt rész értéke Paint_ lesz. Ha egy másik értéket kapunk, akkor azt nem az EA hozta létre. Például a ”StdDev Channel 23109” név kiemelt része StdDev lesz, és a "Fibo 22800" –ból kiemelt Fibo 2 lesz.

A következő sorban a Head változó értékét összehasonlítjuk a Prefix változóval:

 if (Head == Prefix) // The object beginning..
{ // .. with Paint_ is found

Ha ezek az értékek egyelőek egymásnak, akkor az objektum nevét hozzáadjuk a Name_Del[] tömbhöz a törlendő objektumok nevei közé. A következő ciklusban mindegyik objektum, aminek a neve a tömbben található törlésre kerül (meg kell jegyezni, hogy lehetetlen az első ciklus alatt törölni az objektumokat, mert ebben az esetben az objektumok mennyisége és számozása változni fog a ciklusban minden egyes objektum törlése után és ez néhány objektum kihagyásával végződik).

A chart a strings.mq4 EA végrehajtása alatt a következő lesz:


142. ábra: Chart színezett grafikus objektumokkal  (strings.mq4).

A bárokat kiszínező vonalakon túl két másik olyan objektumunk is van, amit a felhasználó kézzel helyezett el, ahogy a 142. ábrán látható a regressziós csatorna és a Fibo szintek. Azokat az objektumokat, amiket az EA hozott létre, törölni fogjuk, amint az EA végrehajtása kész, azok az objektumok, amiket a felhasználóhozott létre, maradni fognak a szimbólumablakban. Ezt az eredményt a string függvények használatával értük el. Ezek a függvények lehetővé teszik a string értékek létrehozását, beleértve a grafikus objektumok neveit is.

String függvények


Függvény Rövid leírás
StringConcatenate Létrehoz egy stringet az adott paraméterekből és visszaküldi azt. A paraméterek bármilyen típusúak lehetnek. A paraméterek száma nem lehet több 64-nél.
StringFind String-részlet kereső. Visszaküldi annak a pozíciónak a számát ahol a string részlet kezdődik, vagy -1-et, ha a string részletet nem találja.
StringGetChar Visszaküldi annak a karakternek az értékét, ami a stringben a megadott pozíciónál található.
StringLen Visszaküldi a karakterek számát a stringben.
StringSetChar Kicseréli a stringben a meghatározott pozíciójú karaktert és visszaküldi a módosított stringet.
StringSubstr A függvény kiemeli azt a meghatározott hosszúságú részt a stringből, ami a megadott pozíciónál kezdődik. A függvény visszaküldi a kiemelt rész másolatát. Ha nem sikerül egy üres karakterláncot küld vissza.
StringTrimLeft A függvény kivágja a kocsi- visszaugrás-karaktereket, szóközöket és tabulálás szimbólumokat a string bal oldali részéről. A függvény visszaküldi a módosított string másolatát, ha lehetséges. Különben egy üres karakterláncot küld vissza.
StringTrimRight A függvény kivágja a kocsi- visszaugrás-karaktereket, szóközöket és tabulálás szimbólumokat a string jobb oldali részéről. A függvény visszaküldi a módosított string másolatát, ha lehetséges. Különben egy üres karakterláncot küld vissza.

Adat átalakítási függvények


Függvény Összefoglaló információ
CharToStr Átalakítja az ASCII karakter kódját ASCII karakterré.
DoubleToStr A double típusú számot átalakítja stringé a meghatározott tizedes pontossággal.
NormalizeDouble Kerekíti double típusú számot a megadott tizedes értékre. A  StopLoss, TakeProfit és a függőben levő megbízások kívánt értékeit a megadott pontosság szerint kell normalizálni, a megkívánt pontosság a Digits változó értéke.
StrToDouble A függvény átalakítja a string típusú számábrázolást „double" típusú számmá (kétszeres-pontosságú formátum lebegőponttal).
StrToInteger A függvény átalakítja a string típusú számábrázolást egész számmá, "int" típusú számmá (integer).
StrToTime A függvény átalakítja az időt és/vagy dátumot ”yyyy.mm.dd [hh:mi]” formátumban tartalmazó  string értéket datetime szám típusra (az 1970.01.01. óta eltelt másodpercek számára).
TimeToStr Az 1970.01.01.óta eltelt, másodpercekben kifejezett időt átalakítja ”yyyy.mm.dd hh:mi” string típusú formátumba.