péntek, június 18, 2010

Kezdjünk programozni

Átesett a blog némi ráncfelvarráson, mert elég lehangoló volt az egész, de talán most kicsit motiválóbb lesz, és Nektek is tetszeni fog.

Mostantól megpróbálok kicsit sűrűbben írni a blogba, mert a program írása közben is szeretném, ha tudnátok követni.
A következőkben írunk egy programot, amely kereskedni fog, méghozzá nyereségesen.
Megtanulunk egyszerűbb fogásokat, illetve olyan segédeszközöket készítünk - mellék termékként -, melyek a kézi kereskedésben is a segítségükre lehet. Kitalálunk egy jó kis Money Management stratégiát és tesztelünk, javítunk, okoskodunk és győzünk! Mert hát erről szól az egész! Nem?

Azt hiszem, hogy eleget filozofáltunk, el kellene kezdeni programozni.
Csapjunk a közepébe!

Hogy értsük is, hogy mit csinálunk, némi magyarázat előzetesen arról, amit csinálni fogunk.

A MetaTrader-ben alapvetően 6 különböző programfájlt készíthetünk, ebből 3 különféle van, ami futtatható programként viselkedik.
Mivel eleinte csak alap dolgokat fogunk csinálni, így nem tárgyaljuk egyenlőre a nem futtatható kódokat, koncentrálunk a futtatható kódokra!

FIGYELEM! Az itt leírt kódok működéséért, azok éles számlán való futtatásáért ezen blog írója nem vállal felelősséget! Bárki, aki követi az utasításokat, csakis kizárólag a saját felelősségére tegye! Éles számlán történő futtatása a tőke elvesztésével járhat! A leírt kódok kizárólag oktatási célokat szolgálnak.

A MetaTrader-ben 3 féle futtatható kódot írhatunk (kódnak nevezzük a program szövegét, az ember számára olvasható kódot, melyet le kell fordítanunk futtatható programmá, azaz a gép számára olvasható kóddá. Szokás forráskódnak is nevezni, mivel ez lesz a futó program forrása.) :
  1. Script : ezek olyan nagyon egyszerű programok, melyek egyetlen egyszer futnak le. Azután a program végrehajtásnak vége szakad.
  2. Indicator : ezek a kódok speciális programok, amelyek a chart-on indikátorként viselkednek. Meglehetősen bonyolult a programozása, ez később fogjuk tárgyalni, de tárgyaljuk mindenképpen, mert igen fontos. Az indikátorok eredményeit - akárcsak a beépített indikátorok eredményeit - fel tudjuk használni a kereskedő programjainkban, hogy döntéseket tudjunk hozni. De manuális kereskedésben is használhatjuk. Az indikátorokban nem használhatjuk a kereskedéssel kapcsolatos utasításokat.
  3. Expert Advisor : ezek az igazi kereskedő programok, ezek képezik az automatikus kereskedés gerincét. Egy chart-on csak egy futhat, és nem több! De a jó hír az, hogy több chart is nyitva lehet egyszerre...
Miután az automata kereskedéshez Expert Advisor-t (mostantól egyszerűen csak EA-t) kell futtatnunk, így ezzel folytatjuk, később pedig elkészítjük első indikátorunkat, menet közben pedig script írási tudásunkat is csiszolgatjuk.

Egy EA ugyanúgy működik, mint egy klasszikus program. Bemenete és kimenete van. Bemenete a különböző paraméterek, melyekkel beállítjuk a programunk működését, kimenete pedig a megkeresett (rossz esetben az elveszített) pénz.

Amikor egy EA-t szeretnénk futtatni, akkor hozzá kell csatolnunk egy chart-hoz. Kétféleképpen tehetjük ezt meg, az egyik az, hogy egérrel megfogjuk a bal oldali listából és ráhúzzuk a chart-ra.
A másik megoldás pedig az, hogy az EA-n nyomunk egy jobb egér gombot, és a "Chart-hoz csatol" menüpontot választjuk a felugró menüből.

Ekkor felugrik egy ablak, ahol be tudjuk állítani az EA bemeneti paramétereit, illetve a futtatásához szükséges egyéb paramétereket.

Próbáld csak ki. Ott a "Moving Average" EA az "Expert Advisor" lenyíló listában a Navigáció ablakban.
Ha ráhúzod a chart-ra, akkor máris ott az ablak. Két fül van, az "Általános" és a "Bemenő adatok".

Az "Általános" fülön néhány nagyon fontos beállítás van. Keretekre van osztva, melyek a következők:

Általános :
  • Long & Short pozíciók : itt szabályozhatod, hogy long (vásárlás), vagy short (eladás) illetve mindkettőt engedélyezed a program futása során. Függetlenül attól, hogy mit írtál a programodban, itt felülbírálhatod!
  • Riasztások : ezekkel nem kell most foglalkoznunk, ahogy van, úgy jó
Élő kereskedés :
  • Élő kereskedés engedélyezése : itt mondhatod meg, hogy a programod végezhet-e élő kereskedést. Ha demó számlával tesztelgetsz, akkor a demó számlán fog "éles" kereskedéseket végezni azzal a pénzzel, amit a demó számlára kaptál. a viszont élő, azaz valódi pénzzel rendelkező számlád van, akkor a TE pénzeddel kereskedik!
  • Kézi megerősítés kérése : Ha nem vagyunk biztosak a programunk sikerében, akkor bepipálhatjuk, ekkor minden kötés előtt kézzel meg kell erősíteni, hogy mehet a pozíció nyitás. Ezzel persze elveszítjük az automatizáltságod, de legalább a mi döntésünk is benne van...
Biztonság :
  • Itt mindenféle rejtélyes dolgot lehet beállítani, hagyjuk úgy, ahogy van, nem érdekes most a beállítás.
A "Bemenő adatok" fülön pedig a programunk paraméterei vannak, ha a "Moving Average" EA-t húztad a grafikonra, akkor "Lots", "MaximumRisk" és ehhez hasonlókat látsz.

Mielőtt azonban futtatni kezdenénk bámilyen EA-t, legelőször is szedjük ízeire, vesézzük ki!

Ha a "Moving Average" EA-t kiválasztjuk a listában és nyomunk egy jobb egérgombot rajta, akkor a felugró menüből válasszuk ki a "Módosítás" menüpontot.
Ekkor a program megnyitja a MetaEditor nevű programot, amellyel a programjainak fogjuk szerkesztgetni ezentúl.

Ez egy tökéletes környezet a programjaink fejlesztéséhez, mert egy kódszerkesztőt, fordítót és súgót is magában foglaló rendszert ad a kezünkbe, amellyel igen hatékonyan lehet programot írni.

Ha minden jól megy, akkor láthatjuk a Moving Average.mq4 forráskódját, azaz magát az olvasható programot. A forráskódok fájl kiterjesztése mindig mq4, a lefordított program neve ugyanaz marad, de a kiterjesztése ex4 lesz.

Ha jól megfigyeljük, akkor a program kódja a következő részekből áll :
  • fejléc
  • init() függvény
  • start() függvény
  • deinit() függvény
  • egyéb függvények
A fejlécet mindjárt kitárgyaljuk, most legelőször a következő részek lényegét kell megértenünk.
Az init() függyvény a programunk indulásakor fut le, egyetlen egyszer. Egész konkrétan akkor fut le, amikor a paraméter ablak bezárul egy OK-val.

Ennek a fügvénynek a párja a deinit() függvény, amely a program leállításakor, újraindításakor fut le egyetlen egyszer.

E két függvénnyel óvatosan kell bánnunk, mert ha a bróker, vagy a VPS szolgáltató (erről is részletesen beszélgetünk majd) újraindít egy karbantartás miatt, akkor ezek a függvények lefuthatnak és ha nincsenek jól megírva, akkor komoly problémákat okozhatnak.
A deinit() függvény például vizsgálhatja a program leállításának okát a UninitializeReason() függvény segítségével, hogy miért állt le a program.
Ezek az okok sokfélék lehetnek, amelyekre mindre másképpen reagálhat a programunk. Lássuk csak :
  • REASON_REMOVE - Az EA-t eltávolítottuk a chart-ról, ez ugye egyértelmű. Ez az EA-k klasszikus végrehajtás megszakítása.
  • REASON_RECOMPILE - Újrafordítottuk az EA-t. Ennek elvileg csak fejlesztés közben szabadba előfordulnia, egy éles környezetben ez nem fordulhat elő. A lényeg, hogyha egy EA-t újrafordítunk, legtöbbször az a célra vezető, ha eltávolítjuk a chart-ról és utána újra rádobjuk az egérrel, mert előfordulhat, hogy nem úgy működik egy újrafordítás után, ahogy azt elvárjuk és ahogy kellene. Ha levesszük a chart-ról az EA-t és újra rádobjuk, ezeket a problémákat a legtöbbször ki tudjuk kerülni, meg tudjuk oldani.
  • REASON_CHARTCHANGE - A chart megváltozott. Vagy egy másik instrumentum került rá, vagy az időtávot változtattuk meg. Ez igen fontos lehet, mert ha egy EA-t egy bizonyos instrumentumra, vagy időtávra optimalizáltuk, komoly veszteséget termelhet a program, ha megváltoznak a körülmények a chart-on.
  • REASON_CHARTCLOSE - bezártuk az aktuális chart-ot, természetesen ilyenkor meg kell szakítani a program működését, mivel nincs értelme tovább futnia. Ekkor kapjuk ezt a kódot, hogy tudjuk nem más okból jött létre a program megszakítás.
  • REASON_PARAMETERS - A futó EA-nak megváltoztattuk valamelyik paraméterét. Ez mindig hatással van az EA életére, ezért ez egy nagyon fontos jelzés. Ilyenkor ugyanis újraindul az EA az új paraméterekkel. Nagyon nagyon fontos ok, tehát erre komolyan oda kell figyelnünk, amikor írjuk az EA-t.
  • REASON_ACCOUNT - Megváltozott a számlaszám, amelyen a chart-okat megjelenítjük, illetve ahol az EA fut. Ez gondolom nem is kell magyaráznom, hogy miért és mennyire fontos. Ha a számlaszámunk megváltozik, akkor megváltozhatnak a pozíció nyitási feltételek, a tőke nagysága, és akár maga a bróker is lehet teljesen más. Tehát ne higgyük, hogy ez elhanyagolható tényező lenne.
Természetesen azok az EA-k, melyek ezekkel a kódokkal törődnek, már nagyon profi programok, egyenlőre nem is fogunk ilyen programokat írni, esetleg nagyon elvétve foglalkozunk ezekkel a paraméterekkel.
Amivel legelőször foglalkozunk, az leginkább a jó stratégia kialakítása és leprogramozása, hogy nyereséget érjünk el. Hiszen ezért csináljuk az egészet.

A legfontosabb része a programunknak a start() függvény. Itt történik minden (legalábbis a dolgok 99%-a), ami a stratégiánk működését képviseli, illetve ami a kereskedéseinket illeti.
Ezt a függvény a MetaTrader minden egyes tick beérkezésekor lefuttatja egyszer. (azt ugye nem kell megmagyaráznom, hogy a tick az az esemény, amikor valamilyen tranzakció történik a piacon az adott instrumentummal, amely árváltozást okoz. Minden időtávon ugyanakkor érkeznek a tick-ek.)

Abban a pillanatban, amikor érkezik egy tick, a start() függvényünk lefut és vagy történik valami közben, vagy nem. Vagy pozíciót nyitunk, vagy nem. Vagy lezárjuk azt, vagy nem. Tulajdonképpen az egész stratégiánkat itt kódoljuk le. Ez a leglényegesebb része a programunknak. Éppen ezért, ha bármikor is az EA törzsére, vagy a futó kódra célozgatunk ebben a blogban, akkor erre a függvényre kell gondolnunk elsősorban.

A fejléc is igen fontos része a programunknak, mert bizony a fejlécben rengeteg maradandó tulajdonságát határozzuk meg az EA-nak. A fejlécünk tovább tagolódik, ennek megfelelően a következőket találjuk itt :
  • A program információs része, itt kommentek formájában tárolhatjuk a forráskódunkban a program nevét, verzióját, az esetleges tovább fejlesztési ötleteinket, és szinte bármit, amit csak akarunk.
  • Fordítási direktívákat, vagyis megmondhatjuk a fordító programnak, hogy amikor lefordítja a forráskódunkat a gép számára értelmes kóddá, akkor azt milyen egyéb feltételekkel hajtsa végre. Olyanokra kell itt gondolni, mint pl. a végleges kódba fixen beégetett információk (copyright infók, a szerző elérhetőségei link formájában, stb.), vagy a jó kis függvény könyvtárunkat is használja, vagy azt, hogy megmutassa-e a felhasznált indikátorokat, stb. Ezekkel meg fogunk ismerkedni hamarosan, mert minden programban szükség van ezekre. Nem túl bonyolult, nem kell megijedni tőle. Szeretetre méltó kis okosságok ezek.
  • Include-ok, melyek egy nem futtatható forráskódot illesztenek be a programunkba. Erről később beszélünk majd, a komolyabb fejlesztések során vesszük hasznát, kezdéshez egyáltalán nem foglalkozunk velük, vagy csak érintőlegesen.
  • Az úgynevezett extern változók, melyek tulajdonképpen a programunk bemenő adatainak való változók definíciói. Ez jelenti a programunk kapcsolatát a külvilággal.
  • Globális változók, melyeket egy programozással foglalkozó fejlesztőnek talán nem kell bemutatni. Azokról a változókról van szó, melyeket minden függvényünk, és maga a program törzse (start() függvény) is lát, írhatja, olvashatja.
  • Konstansok, melyek a teljes EA-ra vonatkoznak, tulajdonképpen olyan változók, melyek értékeit nem lehet megváltoztatni. Ezek leginkább a forráskód olvashatóságát javítják.
Az egyéb függvények azok a függvények, melyeket a start() függvényből hívunk meg és a program végrehajtás folyamán fontos tevékenységet végző program modulok, egységek. Ezt szinte mindig használni fogjuk. Ez nagyon fontos része lesz a programunknak. Már-már haladó szint, de mivel nélkülözhetetlen, fontos dolog.

Következő bejegyzés alkalmával már részletesebben kitárgyaljuk a megvalósítandó stratégiát, a pozíció nyitását és zárását, illetve belekóstolunk egy kicsit a Money Management-be is.
Szóval nekiesünk a kódolásnak!