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   Fájlműveletek


Fájlműveletek

 

Az MQL4-ben végrehajthatunk bizonyos fájlműveleteket. Szükségessé válhat, hogy információt írjunk egy fájlban vagy esetleg kiolvassunk egy fájlból.

Egy fájlt arra a célra is használhatunk, hogy információt közvetítsen egy másik programnak. Ebben az esetben a fájlt létrehozhatja az alkalmazási program és az a program, amelyik az információt felhasználja. Például egy számla történelmét kiírhatjuk egy fájlba egy alkalmazási program végrehajtásával. Ezt a fájlt később megnyithatja egy másik program (például: az Excel azért, hogy grafikont rajzoljon).

Más esetbe felmerül az igény arra, hogy egy alkalmazás információt kapjon a hírek érkezési idejéről. Egy végrehajtható program (például egy Expert Advisor) ki tudja olvasni ezt a korábban előkészített fájlból származó információt és grafikus meg tudja jeleníteni a képernyőn, vagy felhasználhatja kereskedelmi döntéseknél.

Fájlnevek és mappák

 

Egy munkafájl nevét az operációs rendszer követelményei szerint kell létrehozni. Minden fájlnév, amit az MQL4 használ, két részből áll: az állomány neve és az állomány kiterjesztése egy ponttal elválasztva, például: News.txt. Technikailag az állománynévnek nincs kapcsolata a fájltartalommal, úgyhogy az állománynevet és kiterjesztést a programozó önként megválaszthatja. Egy állománynevet általában úgy választunk meg, hogy az utaljon arra az információra, amit a fájl tartalmaz.

A legtöbb program automatikusan elindul a felhasználó PC-jén, ha az egérgombbal a fájlra duplán rákattintunk. Az állomány-kiterjesztés szerint betöltődik egyik vagy másik program, ami megjeleníti a fájltartalmat. Ezért az állomány-kiterjesztést arra a programra tekintettel kell megválasztani (ha ez szükséges) amelyik program majd használni fogja ezt a fájt.

A legtöbbször használt állománytípusok (a típust meghatározza a kiterjesztés) a következők:

- . txt - szövegállomány, megnyitásához használható programok: Notepad, Word, FrontPage, stb.;

- . csv – az Excel táblázatot felépítő fájlformátum;

- . htm – a z ilyen fájlokat a böngészőkben nyithatjuk meg,  Internet Explorer, Netscape Navigátor, , stb.

Van három mappa (alkönyvtárakkal) ahol a munkafájlokat tároljuk:

-  Terminal_folder\Experts\History\current broker\ -  az események naplózásának a mappája;

- Terminal_folder\Experts\Files\ - általános használatra;

- Terminal_folder\Tester\ Files\  - ide kerülnek a tesztelés során használt fájlok.

Egy munkafájlt elmenthetünk e mappák valamelyikébe, vagy ezek valamelyik almappájába. Ha a mappa a mentés pillanatában nem létezik, akkor azt automatikusan létre fogja hozni az ügyfélterminál. Az ügyfélterminál fájlműveletei az egyéb mappákban lévő fájlokat nem befolyásolják.

A fájlműveletek módjai

 

Egy alkalmazás és egy munkafájl közötti kölcsönhatásnak több módja van. Általában egy fájlt ugyanabban az időben több program is megnyithat (egy PC-n belül vagy a hálózaton keresztül több PC). Ugyanakkor a működési környezet csak egy programnak adja meg a teljes hozzáférést a fájlhoz, egyszerre több program olvashatja a fájlt, de írási joga csak egy programnak van. Például, ha a My_text.doc-ot már kinyitotta egy szövegszerkesztő, és azután egy másik program is meg akarja nyitni akkor a fájl megnyitása előtt egy értesítés fog megjelenni:


146. ábra. Megjelenik egy dialógusdoboz, ha egy program megpróbál elérni egy olyan a fájlt, amit már korábban kinyitott egy másik program.

Ez a technológia a garancia arra, hogy egy fájlt nem fog módosítani egyidejűleg két különböző program. Azért hogy egy alkalmazási program és egy fájl egymásra hasson, először meg kell nyitni azt a fájlt. A fájl megnyitásának módját a FileOpen() függvényben határozzuk meg.

Egy alkalmazási program egy időben több fájlt is megnyithat. Azért, hogy a program egyértelműen megkülönböztesse egyik fájlt a másiktól, minden nyitott fájl kap egy állományleírót.

File descriptor, állományleíró - a pillanatnyilag nyitott fájl egyedülálló azonosító száma.

A FileOpen() függvény vissza fog küldeni egy egész számot (ez az érték a 'handle' változó), ha egy fájlt sikeresen megnyitott. Ez az érték az állományleíró. A legtöbb függvény, amely fájlműveleteket hajt végre, a formális paraméterei között használja az állományleírót is.

FileOpen() függvény

 int FileOpen(string filename, int mode, int delimiter=';')

A függvényírásra és/vagy olvasásra megnyit egy fájlt. A függvény visszaküldi az állományleírót, vagy kudarc -1-et. A megnyitandó fájlok  a Terminal_folder\Experts \Files\ mappában vagy a Terminal_folder\Tester\Files\ mappában (EA tesztelés esetében) vagy ezek alkönyvtáraikban lehetnek.

Paraméterek:

filename - a fájl neve;

mode - a fájlmegnyitás módja; a következő értékek lehetnek : FILE_BIN, FILE_CSV, FILE_READ, FILE_WRITE (vagy ezek kombinációi);

delimiter - a csv-fájl elválasztójele. Ez alapból ';' .

A fájlmegnyitás FILE_READ módja azt jelenti, hogy a fájlt csak olvasásra fogja használni a program. Ha a megnyitás ebben a módban nem sikerült, ez azt jelenti, hogy ezzel a névvel nincs fájl a megadott helyen.

A FILE_WRITE módú megnyitásnak az a következménye, hogy a program egy írható fájlt fog megnyitni. Az ily módon megnyitott fájl egy nullahosszúságú fájl lesz. Még akkor is, ha a megnyitás előtt az ilyen nevű fájlnak volt tartalma ez az információ ki fogják törlődni. Az ilyen módú kísérlet sikertelen lesz, ha a fájlt korábban kinyitotta egy másik program (írás módban).

Egy fájlt megnyithatunk FILE_READ|FILE_WRITE módban is. Ekkor lehetőség van a fájl olvasására és írására is. Ezt a módot akkor használjuk, ha hozzá kell adni valamilyen információt ahhoz a fájlhoz, ami már tartalmaz egy másik információt. A fájlmegnyitás módjának megadása kötelező:  FILE_READ vagy FILE_WRITE, vagy a kombinációjuk.

A fájlmegnyitás FILE_BIN módja meghatározza, hogy a munkafájlt binárisként dolgozzuk fel. A fájlmegnyitás FILE_CSV módja a szövegként történő feldolgozást írja elő. A függvényben kötelező megadni a FILE_BIN vagy a FILE_CSV módot. FILE_BIN és FILE_CSV módok egyidejű használata tilos.

A függvényben  a FILE_READ, FILE_WRITE vagy a FILE_READ|FILE_WRITE módokat kötelező kombinálni a FILE_BIN vagy a FILE_CSV móddal. Például: a FILE_CSV|FILE_READ kombinációt arra használjuk, hogy kiolvassa az információt egy szöveges állományból, a FILE_BIN|FILE_READ|FILE_WRITE kombinációt pedig arra, hogy hozzáadjon egy bejegyzést egy bináris állományhoz.

Egyszerre 32-nél több fájlt nem lehet megnyitni egy végrehajtható modulon belül (alkalmazási program, Expert Advisor). Az egyik modulban megnyitott fájlok leíróit nem adhatjuk át egy másik modulba.

A fájlbejegyzések tartalma

 

A fájlba történő bejegyzéseket térköz nélkül írjuk a fájlba, a fájlmegnyitás minden kombinációjánál. A FILE_BIN módban az információ bejegyzéseket változatlanul hozzáadjuk az alakítandó fájlhoz. Az információ fajtájától függően, amit a fájlba írunk (és attól a függvénytől függően, amivel ezt végrehajtjuk) a ("\r\n") sorvégzáró karakterkombinációt is használhatjuk a bejegyzés csoportok között. Az információbejegyzéseket a FILE_CSV módban az elválasztó karakterekkel (általában ';') szeparáljuk, és a bejegyzés csoportokat (a bejegyzés sorait) a sorvégzáró karaktercsoportokkal ("\r\n") választjuk el egymástól).

File separator, elválasztót karakter - különleges szimbólum; a bejegyzésen belül elválasztja az információrészeket egymástól.

A fájl elválasztó karaktert arra használják, hogy a csv fájlban elválassza az egyes információ bejegyzéseket.

A közös elv a bejegyzések írásakor, hogy azokat bármilyen fájlba is írjuk, a karakterek között nem hagyunk térközt. Vagyis, a bejegyzés folytonos szimbólum sorozatból áll. A fájlokat többféle program is olvashatja (a megvalósítási szabályoktól függően) és különböző formában jeleníti meg a képernyőn. Például: itt van a  File_1.csv fájl:
int FileOpen(string filename, int mode, int delimiter=';')

A File_1.csv fájlt a különböző programokban különböző alakban láthatjuk:


147. ábra. File_1 ábrázolása különböző programokban  (File_1.csv).

Ebben az esetben az \r\n szimbólumkombinációt mindkét program (Excel és Notepad) szövegformázó karakterekként értelmezte: a karaktereket az \r\n kombináció után a következő sorba írta, és magát az \r\n kombinációt nem jeleníti meg a szerkesztőablakban. Ugyanakkor az Excel táblázatkezelő a ";" szimbólumot oszlop elválasztóként értelmezte, vagyis az információk elválasztójaként. Figyeljük meg, hogy a ";" szimbólumot nem mutatja az Excel. A Jegyzettömb egy szövegszerkesztő. Ez a program  nem teszik lehetővé az információ felosztását oszlopokba, ezért a ";" szimbólumot nem értelmeztek bejegyzés elválasztóként, hanem azt az információ részeként értelmezte, ezért azt is kiírta a képernyőre.

A nevezett karaktereket (";" és \r\n) elválasztó karakterként használja az MQL4.


148. ábra. A bejegyzések variációja a fájlműveletek során.

148. ábrán a különböző kiterjesztésű fájlokba írt információ szerkezetét láthatjuk. A legfelső sorban a csv-fájlok láthatók, az alsó három sor pedig a bináris állományok szerkezete. Ezeket a fájlokat a rájuk jellemző speciális szabályok szerint hozza létre és írja a függvény.

A bejegyzések a csv fájlban string értékek (string típusúak) elválasztó karakterrel vagy sorvég karakterekkel tagolva. Mindkét tagolási módszert a bejegyzett értékrész végeként értelmezik olvasás közben az MQL4 erre alkalmas beépített függvényei. A string értékek különböző hosszúságúak lehetnek és nem tudjuk, hogy hány karaktert tartalmaznak, ezért a kiolvasásukat a következő  elválasztó karakterig végezzük.

A fájlbejegyzések másik típusát a bináris állományok képviselik, a bináris állományokat elválasztó karakterek nélkül írjuk. Az ilyen bejegyzéseknek rögzített hosszuk van a különböző adat típusokhoz: 4 byte az "int", "bool", "datetime" és "color"típusokhoz, és 8 byte (vagy 4 byte, az írás paramétereitől függően) a "double" típusú adatokhoz. Ebben az esetben az elválasztó karakterekre nincs szüksége, mert az olvasást a beépített függvény az adattípusra jellemző bejegyzés hosszal hajtja végre.  Az utolsó (a legalsó a 148. ábrán) bináris állomány string típusú adatokat tartalmaz amelyeket sorvég karakterekkel tagolunk.

File pointer, fájlmutató – az a hely a fájlban, ahol a következő érték olvasását kezdjük.

A fájlmutatót kurzorként képzelhetjük el. A fájlmutató meghatározza a fájlban elfoglalt helyet. Az olvasás alatt a fájlmutató  jobbra mozdul egy vagy több pozíciót.

36. Feladat: Olvassa ki a fontos hírekkel kapcsolatos információt egy fájlból, és jelenítse azt meg grafikus objektumokkal a charton (függőleges vonallal) a bejelentés időpontjának megfelelően.

Legyen a Terminal_Folder\Experts\Files\  mappában lévő  News.csv  fájl tartalma a következő:


149. ábra. A News.csv. munkafájl tartalma.  News.csv.

Ebben az esetben a fájl öt eseménnyel kapcsolatos információt tartalmaz, ami különböző országokban fog történni különböző időpontokban. Mindegyik sor két bejegyzést tartalmaz. Az első bejegyzés az esemény bekövetkeztének idejét jelző string érték. A második bejegyzés az esemény szöveges leírása. A második bejegyzés első három szimbóluma tartalmazza a pénznemet (országot) amelyre az esemény hatással lehet.

A feladat megoldása két részből áll. Először is ki kell olvasnunk az információt a munkafájlból azután a grafikus objektumok koordinátáiként kell használnunk a megkapott értékeket. Az információ olvasását a FileReadString() függvény hajtja végre.

FileReadString() függvény

 string FileReadString(int handle, int length=0)

A függvény kiolvassa a fájlból az információt az aktuális pozícióból. Ez ugyanúgy történik a CSV-nék és a binárisnál is. A sort addig fogja olvasni, amíg az elválasztójellel nem találkozik a szövegállományban. A bináris állományokból meghatározott számú szimbólumot fog olvasni. Ha a hiba információra vagyunk kíváncsiak, hívnunk kell a GetLastError() függvényt.

Paraméterek:

handle - az az állományleíró, amit visszaküld a FileOpen() függvény;

length – az olvasandó karakterek száma.

A szükség hírekkel kapcsolatos információt csak egyszer kell feldolgozni a kereskedés kezdetén, tehát ebben az esetben a 36. feladat megoldásához egy scriptet kell használnunk. A  timetablenews.mq4 script feladata az, hogy kiolvassa az információt a fájlból és ábrázolja azt grafikus objektumokkal a szimbólumablakban.
//--------------------------------------------------------------------
// timetablenews.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------- 1 --
int start() // Spec. function start()
{
//--------------------------------------------------------------- 2 --
int Handle, // File descriptor
Stl; // Style of vertical line
string File_Name="News.csv", // Name of the file
Obj_Name, // Name of the object
Instr, // Name of the currency
One,Two, // 1st and 2nd name of the instr.
Text, // Text of event description
Str_DtTm; // Date and time of the event (line)
datetime Dat_DtTm; // Date and time of the event (date)
color Col; // Color of the vertical line
//--------------------------------------------------------------- 3 --
Handle=FileOpen(File_Name,FILE_CSV|FILE_READ,";");// File opening
if(Handle<0) // File opening fails
{
if(GetLastError()==4103) // If the file does not exist,..
Alert("No file named ",File_Name);//.. inform trader
else // If any other error occurs..
Alert("Error while opening file ",File_Name);//..this message
PlaySound("Bzrrr.wav"); // Sound accompaniment
return; // Exit start()
}
//--------------------------------------------------------------- 4 --
while(FileIsEnding(Handle)==false) // While the file pointer..
{ // ..is not at the end of the file
//--------------------------------------------------------- 5 --
Str_DtTm =FileReadString(Handle);// Date and time of the event (date)
Text =FileReadString(Handle);// Text of event description
if(FileIsEnding(Handle)==true) // File pointer is at the end
break; // Exit reading and drawing
//--------------------------------------------------------- 6 --
Dat_DtTm =StrToTime(Str_DtTm); // Transformation of data type
Instr =StringSubstr(Text,0,3);// Extract first three symbols
One=StringSubstr(Symbol(),0,3);// Extract first three symbols
Two=StringSubstr(Symbol(),3,3);// Extract second three symbols
Stl=STYLE_DOT; // For all - dotted line style
Col=DarkOrange; // For all - this color
if(Instr==One || Instr==Two) // And for the events of our..
{ // .. symbol..
Stl=STYLE_SOLID; // .. this style..
Col=Red; // .. and this color of the vert. line
}
//--------------------------------------------------------- 7 --
Obj_Name="News_Line "+Str_DtTm; // Name of the object
ObjectCreate(Obj_Name,OBJ_VLINE,0,Dat_DtTm,0);// Create object..
ObjectSet(Obj_Name,OBJPROP_COLOR, Col); // ..and its color,..
ObjectSet(Obj_Name,OBJPROP_STYLE, Stl); // ..and style..
ObjectSetText(Obj_Name,Text,10); // ..and description
}
//--------------------------------------------------------------- 8 --
FileClose( Handle ); // Close file
PlaySound("bulk.wav"); // Sound accompaniment
WindowRedraw(); // Redraw object
return; // Exit start()
}
//--------------------------------------------------------------- 9 --

A változókat a 2-3 blokkban írjuk le. A fájl megnyitását és a megnyitási kísérlet eredményének az elemzését a 3-4 blokkban hajtjuk végre. A fájlt a FileOpen() függvény segítségével nyitjuk meg:

 Handle=FileOpen(File_Name,FILE_CSV|FILE_READ,";");// File opening

A fájl megnyitása nem mindig sikeres. Ez előfordul, ha a fájl a megadott névvel nem létezik. Amikor a fájlmegnyitás sikertelen (az állományleíró egy negatív szám) a szükséges szöveges üzenetet megjelenítjük a felhasználónak és a start() függvény végrehajtása véget ér.

A fájl sikeres megnyitása esetén a vezérlést megkapja a "while" ciklusoperátor (4-8 blokk). A fájlból való adatok olvasása (5-6 blokk), az adatok átalakítása és az elemzése (6-7 blokk) és a koordinátákkal és paraméterekkel rendelkező grafikus objektum létrehozása a legutolsó kiolvasott információnak megfelelően történik (7-8 blokk) mindegyik ismétlésnél.

A "while" ciklus végrehajtása addig folytatódik, amíg a fájlmutató el nem éri a fájl végét, vagyis információ nem  marad a fájlmutató jobb oldalán. A FileIsEnding() függvény feladata, hogy elemezze a fájlmutató pozícióját.

FileIsEnding() függvény

bool FileIsEnding(int handle)

A függvény visszaküldi a TRUE értéket, ha a fájlmutató a fájl végén van, különben FALSE-ot küld vissza. Hibainformációt, a GetLastError() függvény segítségével kapunk. A GetLastError() függvény az ERR_END_OF_FILE (4099) hibát fogja vissza küldeni abban az esetben, ha a fájl az olvasás alatt ér véget.

Paraméterek:

handle - állományleíró, amit a FileOpen() függvény küld vissza.

 

A jelen megoldás (timetablenews.mq4) lehetővé teszi, hogy bármennyi bejegyzés lehet a News.csv fájlban. Az említett példában (149. ábra) a News.csv fájl öt bejegyzést tartalmaz, ami öt eseményhez tartozik (hírek). Általában a bejegyzések száma 0-tól 20-30-ig terjedhet, az adott napon történő eseményektől függően.

A bejegyzés olvasása a fájlból (abból amelyiket a "handle" változó kijelölt) az 5-6 blokkban történik:

 Str_DtTm =FileReadString(Handle);// Date and time of the event (date)
Text =FileReadString(Handle);// Text of event description
if(FileIsEnding(Handle)==true) // File pointer is at the end
break; // Exit reading and drawing

Az  5-6 blokk első és második soraiban addig olvassuk az információt a fájlból, amíg a legközelebbi elválasztóval nem találkozunk. A harmadik és negyedik sorban ellenőrizzük, hogy a fájlmutató a sor végén van-e. Ha nem, akkor a ciklusban a grafikus objektumokat ki fogjuk alakítani a két kiolvasott string érték szerint. Ha kezdetben tudnánk a bejegyzések számát, a harmadik és negyedik sorban lévő elemzés végrehajtására nem lenne szükség. Ebben az esetben megadnánk az ismétlések számát a ciklusban (pl.: 5) és nem hajtanánk végre a bejegyzések számára vonatkozó ellenőrzést.

Azonban a bejegyzések száma ebben az esetben ismeretlen. Ugyanakkor ebben a példában minden eseményt két érték ír le, amelyek a következő formátumú sort alkotják: érték; elválasztót karakter; érték; sorzáró karakter. Ebben az esetben feltételezzük, hogy ha van első bejegyzés (első érték a sorban) akkor a második is létezik; és ha nincs első bejegyzés, akkor a második sem létezik, ezért kijelezendő esemény nincs és nem szükséges a grafikus objektumot létrehozni. Ha az egyik vagy mindkét bejegyzés hiányzik, a fájlmutató a fájl végre ér (arra a helyre a fájlban, ahol a mutató jobb oldalán nincsenek adatok) az olvasási kísérlet során. A 3-4 blokkban végrehajtott ellenőrzés segít felfedezni ezt a tényt. Ha az ellenőrzés elmaradna (az 5-6 blokk utolsó két sora), akkor fölösleges objektumokat hozna létra a program. Csak a "while" ciklusoperátor feltételének teljesülése után kerül a vezérlés a 8-9 blokkba.

Az adat, amit a fájlból kiolvastunk string típusú. Ahhoz, hogy a megkapott értékeket grafikus objektumok létrehozására használhassuk, át kell alakítani az adatokat a szükséges adattípusra. A 6-7 blokkban, az első (a következő sorból olvasott) értéket alakítjuk át datetime típusra és a későbbiekben ezt az értéket fogjuk használni a megfelel az eseményt jelző grafikus objektum koordinátájaként. A második string érték első három karakterét összehasonlítjuk a szimbólum nevében szereplő első és második deviza nevével. Ha van egybeesés, akkor azalapján a grafikus objektum megkapja a megfelelő paramétereket: a vonalstílus: folytonos és a szín: piros (7-8 blokk). Egyéb esetekben az objektumokat narancssárga pontozott vonallal ábrázoljuk. Megfigyelhetjük a script végrehajtásának az eredményét:


150. ábra. Grafikus objektumok a  timetablenews.mq4 végrehajtása után a szimbólumablakban.

Ezt a scriptet bármilyen szimbólumablakban végrehajthatjuk. Azonban minden ablakban  folytonos piros vonallal ábrázolva jelennek meg azok az események, amik érintik az ablak devizáit, és pontozott narancssárga vonallal azok amelyek másik szimbólumok eseményeivel kapcsolatosak. Az objektumok leírásának megjelenítésére kapcsoljuk be az „Objektum leírások megjelenítése” opciót az ablak Tulajdonságok-ban  (F8) => Általános fül.

A korábban megnyitott fájlt a 8-9 blokkban a feladat megoldása után bezárjuk, mivel minden szükséges objektumot létrehoztunk. A fájlt a következő okok miatt kell bezárni: először azért, hogy ne terheljük fölöslegesen a PC-erőforrásokat, másodszor pedig azért, hogy lehetővé tegyük másik programoknak, hogy hozzáférjenek a fájlhoz írás módban. Ezért ajánlott bezárni a fájlt, amint minden információt kiolvastunk (vagy írtunk) és a használata már nem szükséges. A fájl befejezését a FileClose() függvény hajtja végre.

FileClose() függvény

 void FileClose(int handle)

A függvény bezár egy olyan fájlt, amit korábban a FileOpen() függvény nyitott meg.

Paraméterek:

handle – állományleíró, amit a FileOpen()függvény küldött vissza.

 

Azért hogy a gyakorlatban használni tudjuk a timetablenews.mq4 scriptet valamilyen módszerrel létre kell hozni azt a fájlt, ami tartalmazza az adott időszak bejelentéseinek időpontját. Ezt a fájlt létrehozhatjuk bármilyen szövegszerkesztővel, azonban ebben az esetben fennáll a hiba lehetősége (néha egy elválasztó karaktert hibásan helyezünk el). A vizsgáljuk meg e fájl létrehozását egy MQL4 program segítségével.

37. feladat: Írjuk meg annak az EA-nak a kódját, ami létrehozza a fontos bejelentéseket tartalmazó fájlt.

Általában egy EA-val létre lehetne hozni egy olyan fájt, ami korlátlan számú hír bejelentési időpontját tartalmazza. A bemutatandó  createfile.mq4 programmal egy olyan munkafájlt hozhatunk létre, ami ötnél nem több esemény információját tartalmazhatja.

//--------------------------------------------------------------------
// createfile.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------- 1 --
extern string Date_1=""; // 2007.05.11 10:30
extern string Text_1=""; // CHF Construction licenses
extern string Date_2=""; // 2007.05.11 12:00
extern string Text_2=""; // GBP Refinance rate,2%,2.5%
extern string Date_3=""; // 2007.05.11 13:15
extern string Text_3=""; // EUR Meeting of G10 banks governors
extern string Date_4=""; // 2007.05.11 15:30
extern string Text_4=""; // USD USA unemployment rate
extern string Date_5=""; // 2007.05.11 18:30
extern string Text_5=""; // JPY Industrial production
//--------------------------------------------------------------- 2 --
int start() // Spec. function start()
{
//--------------------------------------------------------------- 3 --
int Handle, // File descriptor
Qnt_Symb; // Number of recorded symbols
string File_Name="News.csv"; // File name
string Erray[5,2]; // Array for 5 news
//--------------------------------------------------------------- 4 --
Erray[0,0]=Date_1; // Fill the array with values
Erray[0,1]=Text_1;
Erray[1,0]=Date_2;
Erray[1,1]=Text_2;
Erray[2,0]=Date_3;
Erray[2,1]=Text_3;
Erray[3,0]=Date_4;
Erray[3,1]=Text_4;
Erray[4,0]=Date_5;
Erray[4,1]=Text_5;
//--------------------------------------------------------------- 5 --
Handle=FileOpen(File_Name,FILE_CSV|FILE_WRITE,";");//File opening
if(Handle==-1) // File opening fails
{
Alert("An error while opening the file. ",// Error message
"May be the file is busy by the other applictiom");
PlaySound("Bzrrr.wav"); // Sound accompaniment
return; // Exir start()
}
//--------------------------------------------------------------- 6 --
for(int i=0; i<=4; i++) // Cycle throughout the array
{
if(StringLen(Erray[i,0])== 0 || // If the value of the first or..
StringLen(Erray[i,1])== 0) // ..second variable is not entered
break; // .. then exit the cycle
Qnt_Symb=FileWrite(Handle,Erray[i,0],Erray[i,1]);//Writing to the file
if(Qnt_Symb < 0) // If failed
{
Alert("Error writing to the file",GetLastError());// Message
PlaySound("Bzrrr.wav"); // Sound accompaniment
FileClose( Handle ); // File closing
return; // Exit start()
}
}
//--------------------------------------------------------------- 7 --
FileClose( Handle ); // File closing
Alert("The ",File_Name," file created.");// Message
PlaySound("Bulk.wav"); // Sound accompaniment
return; // Exit start()
}
//--------------------------------------------------------------- 8 --

A kezdeti információkat a program elején (1-2 blokk) string típusú külső változókban helyezzük el. A többi változót a 3-4 blokkban hozzuk létre és írjuk le. A feldolgozás egyszerűbbé tételéért az adatokat az Erray[][] tömbbe helyezzük el. Minden eseményt (a híreket jellemező információ) a kétdimenziós tömb két eleme képvisel. A tömb méretét (a tömbben lévő elemek számát) a hírek száma határozza meg, ebben az esetben ez 5. Azért, hogy az adatbevitel során a hibás működést elkerüljük, az example_news.set fájlt létrehozó EA -t  demó-számlán futtassuk, az EA által létrehozott fájlnak a Terminal_folder\presets  mappába kell kerülnie.

A fájlmegnyitás az 5-6 blokkban történik. Ha a művelet nem sikerül, akkor a start() függvény véget ér, és a felhasználó megkapja a megfelelő üzenetet. Ha a fájlt sikeresen megnyitottuk, akkor a vezérlés át fog kerülni a 6-7 blokkban lévő ciklusoperátorhoz. A bemenő adatok számát, az Erray tömb méretét és az ismétlések számát, ha szükséges megnövelhetjük.

Mindegyik ismétlésnél ellenőrizzük, hogy van-e bemenő adat. Az Erray tömb elemeinek hosszát ezért megvizsgáljuk. Ha közülük valamelyiknek a hossza nulla, akkor azt úgy értékeljük, hogy az aktuális és a következő események hiányoznak, ezért az aktuális ismétlés megszakad. A tömb elemértékeinek a fájlba írása addig folytatódik, amíg az üres elemértéket megtaláljuk. Az értékeket a csv fájlba a FileWrite() függvény írja.

FileWrite() függvény

 int FileWrite(int handle, ...)

A függvény feladata az információk csv fájlba írása, az információk közötti elválasztók automatikus elhelyezését is beleértve. A "\r\n" sorzáró jelet az információ írása után adju khozzá a fájlhoz. A számszerű információt átalakítjuk szöveges formátumba a végrehajtás során (lásd: Print() függvény). A függvény visszaküldi az írott szimbólumok számát vagy negatív értéket, ha hiba történik.

Paraméterek:

handle - állományleíró, amit a FileOpen() függvény küld vissza;

... - az adatokat vesszővel választjuk el. A paraméterek száma nem lehet több 63-nál.

A "double", "int" típusú adatokat automatikusan átalakítjuk string értékké (a "color", "datetime" és "bool" típusú adatokat  egész (int ) adatoknak  tekintjük és szintén stringé alakítjuk, a string típusú adatokat átalakítás nélkül, ahogy vannak úgy írjuk. A tömböket nem adhatjuk meg paraméterekként; a tömbök értékeit elemenként kell megadni. 

A szóban forgó példában az információt a következő módon írjuk a fájlba:

 Qnt_Symb=FileWrite(Handle,Erray[i,0],Erray[i,1]);//Writing to the file

Az elválasztót (azt a szimbólumot, amit elválasztóként használunk, a FileOpen() fájlnyitó függvényben megadtuk, (ebben az esetben: ';') és az Erray[i,0] értékek után fogjuk írni a fájl írása során. A "\r\n" sorzáró jelet automatikusan elhelyezi a FileWrite() függvény a függvényvégrehajtás végén, vagyis az írás végén. A „for" ciklus mindegyik végrehajtásakor egy bejegyzést fog írni. Minden új bejegyzés attól a pozíciótól kezdődik, ahol az előző bejegyzés elválasztóját elhelyezte. Azután az Erray következő elemeinek az értékeit fogja írni a fájlba (az elemeket indexe 1-el növekszik minden ismétlésnél).

Ha az aktuális bejegyzés fájlba írása sikeres a vezérlés elvégzi a következő ismétlést. Ha a fájlban írás sikertelen, a FileClose() függvény a fájlt be fogja zárni, és a felhasználó értesítése után a start() függvény befejezi a működését. Ha minden fájlba írást sikeresen végrehajtottunk, akkor a "for" ciklusnak vége van, és a vezérlést a 7-8 blokkban megkapja a FileClose() fájlbezáró-függvény. Ebben az esetben a sikeres fájllétrehozásról látunk üzenetet és azután a start() függvény végrehajtása véget ér. A 149. ábrán látható News.csv fájl létrehozása után az EA végrehajtás kész.

 

Fájlműveleteket végrehajtó függvények

Függvény Összefoglaló információ
FileClose A korábban a  FileOpen() függvénnyel megnyitott fájl bezárása.
FileDelete A fájl törlése. Csak azokat a fájlokat törölhetjük, amelyek a terminal_folder\experts\files mappában, vagy tesztelés esetén a terminal_folder\tester\files mappában vagy ezek almappáiban találhatók.
FileFlush Kiírja a fájl input-output bufferben lévő információt a merevlemezre.
FileIsEnding TRUE-t küld vissza, ha a fájlmutató a fájl végén van, minden más esetben visszaküldi a FALSE-ot. Ha a fájl végét a fájlolvasás alatt érjük el, a  GetLastError() függvény az ERR_END_OF_FILE (4099) hibát  fogja visszaküldeni.
FileIsLineEnding Visszaküldi a TRUE-t, ha a fájlmutató a CSV fájlban a sorvégén van. Különben visszaküldi a FALSE-ot.
FileOpen Megnyit egy fájlt olvasásra vagy írásra. A függvény visszaküldi a megnyitott fájl állományleíróját, ha a megnyitás nem sikerül, akkor -1-et.
FileOpenHistory Megnyit egy fájlt az aktuális hitory mappában (termial_folder\history\server_name) vagy az alkönyvtáraiban. A függvény visszaküldi a megnyitott fájl állományleíróját,vagy ha a megnyitás nem sikerül, akkor -1-et.
FileReadArray A függvény a bináris állományból a meghatározott számú elemet olvassa ki egy tömbbe. A tömbnek az olvasás előtt elegendő méretűnek kell lennie. A függvény visszaküldi a ténylegesen kiolvasott elemek számát.
FileReadDouble A függvény lebegőponttal olvassa a dupla pontosság számot (double) a bináris állomány aktuális pozíciójából. A szám mérete a következő lehet: 8 byte (double) és 4 byte (float).
FileReadInteger A függvény kiolvassa az egész számot a bináris állomány aktuális pozíciójából. A szám mérete a következő lehet: 1, 2 vagy 4 byte. Ha a szám méretét nem adtuk meg, meg fogja próbálni azt 4 byte-os egész számként olvasni.
FileReadNumber Számot olvas a CSV fájl aktuális pozíciójától addig, amíg elválasztóval nem találkozik. Csak csv fájloknál alkalmazhatjuk.
FileReadString A függvény olvassa a fájlból a stringet az aktuális pozíciótól. Ezt alkalmazhatjuk a csv és a bináris fájloknál is. A szövegállományt addig fogja olvasni, amíg elválasztóval nem találkozik. A bináris állományokból a meghatározott számú szimbólumot fogja kiolvasni.
FileSeek A függvény új pozícióba mozgatja a fájlmutatót, az elmozdulás kiindulási pontja a fájl kezdete, vége vagy az aktuális pozíciója. A következő olvasás vagy írás az új pozícióból kezdődik. Ha a mutató mozgatása sikeresen megtörtént, a függvény vissza fogja küldeni a TRUE-t, más esetben a FALSE-t.
FileSize A függvény byte-okban küldi vissza a fájl méretét.
FileTell A függvény visszaküldi a fájlmutató elmozdulását a fájl kezdetéből.
FileWrite A függvény az információt csv fájlba írja, az elválasztót automatikusan elhelyezi az információk között. A sorzáró jelet "\r\n" akkor kapja meg a fájl amikor az írás kész. A számszerű adatot az eljárás alatt átalakítja string formátumba. A függvény visszaadja az írott szimbólumok számát vagy egy negatív értéket, ha hiba történik.
FileWriteArray A függvény egy tömb értékeit írja bináris állományba.
FileWriteDouble A függvény lebegőpontos számot ír a bináris állományba.
FileWriteInteger A függvény egész számot ír a bináris állományba.
FileWriteString A függvény bejegyzést ír a bináris állományba az aktuális pozíciótól. Visszaküldi a ténylegesen írott byte-ok számát vagy egy negatív értéket, abban az esetben ha hiba történt.