Tehát FOREX robotunk már készen van nagyjából, bár igazából még csak a pozíció nyitásokat beszéltük meg. Arról volt szó, hogy pozíció zárás nem is lesz benne, hiszen stop-loss-t fogunk beállítani, ez fogja zárni a pozíciónkat, méghozzá úgy, hogy az árhoz minél közelebb húzzuk.
A folyamatos ár után húzott - követő - stopunkat addig húzogatjuk, amíg a stop-loss a kötési ár fölé/alá (függően attól, hogy long, vagy short pozíciónk van) kerül, lehetőleg minél jobban.
Ekkor, ha az ár visszaesik, akkor a stop-loss ugyan bezárja a pozíciót, de ekkor már nyereséges lesz.
Na, jó, de hogyan lehet ezt csinálni?
A dolog rém egyszerű, a Parabolic trendchaser egyéni indikátort fogjuk ügyesen felparaméterezni, és az ő jelzéseire állítjuk be a stop-loss-t. Sajnos ez nem lesz mindig lehetséges, de erről majd picit később.
Mindenek előtt, a programunk elején, közvetlenül a start() függvény elejére illesszünk be egy új sort, ahol három új változót fogunk felvenni.
Tehát a start() függvényünknek így kell kezdődnie :
A három double változó feladat lesz a stop-loss kiszámítása és húzása. Az első két int változó feladata a pozíció nyitások lebonyolítása, a ticket számát tartalmazza és az esetleges hibakódot.int start()
{
int err, ticket;
double stoploss, ParUp, ParDn;
No, de nézzük csak hogyan kell a stopot húzni.A teljes kód a következőképpen néz ki, a jelentését mindjárt meg is beszéljük :
orders=OrdersTotal();Az OrdersTotal() függvény elárulja nekünk, hogy mennyi nyitott pozíció van ezen a számlán, minden devizapáron.
if (orders != 0)
{
for(pos=0;pos
{
if(OrderSelect(pos, SELECT_BY_POS,MODE_TRADES))
{
ParUp=iCustom(NULL,0,"Parabolic trendchaser", false, 0.06,0.1,7,0,0,1);
ParDn=iCustom(NULL,0,"Parabolic trendchaser", false, 0.06,0.1,7,0,1,1);
if (OrderType() == OP_BUY && OrderSymbol() == Symbol() && ParDn != 0)
{
stoploss = ParDn;
if (OrderModify(OrderTicket(),OrderOpenPrice(), stoploss, OrderTakeProfit(),0,Blue))
Print("Stop-loss módosítva!");
else
{
Print("Stop-loss nem módosult! ", DoubleToStr(stoploss,5));
Print("Hibaüzenet : ",ErrorDescription(GetLastError()));
}
}else if (OrderType() == OP_SELL && OrderSymbol() == Symbol() && ParUp != 0)
{
stoploss = ParUp;
if (OrderModify(OrderTicket(),OrderOpenPrice(), stoploss, OrderTakeProfit(),0,Blue))
Print("Stop-loss módosítva!");
else
{
Print("Stop-loss nem módosult! ", DoubleToStr(stoploss,5));
Print("Hibaüzenet : ",ErrorDescription(GetLastError()));
}
}
}else
Print("Nem sikerült húzni a Stop-Loss-t, nem találom a pozíciót!");
}
}
A legelső if utasítás arról gondoskodik, hogy csakis kizárólag akkor foglalkozzunk a stop húzással, ha van nyitott pozíciónk.
Ezután egyesével végig szaladunk egy for ciklus segítségével a pozíciókon. A ParUp és a ParDn értékek kiszámításával kezdjük, hiszen nemsokára szükségünk lesz rá. Ezek adják majd a stop szinteket.
A következő if utasítással azt vizsgáljuk, hogy :
- Long pozíció-e az éppen vizsgált soron következő pozíció
- Az aktuális chart-nak megfelelő devizapáron köttetett-e (képzeljük csak el, ha egy EURUSD-n futó programunk lezárná az EURHUF long pozíciónkat... Kellemetlen lenne...)
- És azt is vizsgáljuk, hogy van-e kiszámított érték egyáltalán, mert ha nincs, akkor minek túráztatjuk magunkat
Figyeljük meg, hogy az aktuális adatokat kikérjük a pozícióról és azokat vissza is írjuk az OrderModify() függvénybe, tehát csak a stopot módosítjuk. (tehát az OrderTicket() függvény megmondja az aktuálisan kiválasztott pozíciónk ticket számát, az OrderOpenPrice() elárulja milyen áron nyitottuk a pozíciót, ha van take profit beállítva, akkor az OrderTakeProfit() ezt is elárulja. Mindezeket visszaírjuk a módosításba eredeti formájukban, tehát nem bántjuk őket, így tudjuk csak stop-loss-t módosítani)
Természetesen vizsgáljuk a visszatérési értékét a függvénynek, tehát ha igaz értékkel tér vissza, akkor közöljük a program felhasználójával, hogy sikerült, ha pedig nem sikerült, azt is közöljük, de a hiba okát is kiírjuk, erre való az ErrorDescription(GetLastError()) összefüggés.
Az igazsághoz persze az is hozzátartozik, hogy a programunk elejére be kell szúrnunk még két sort, ahhoz, hogy a hibakiírás működhessen, mégpedig ezt a két sort :
Ezekkel biztosíthatjuk, hogy az előbb említett hibakezelő függvények működhessenek.#include <stderror.mqh>#include <stdlib.mqh>
Érdemes a többi include utasítás alá beilleszteni, ha van. De mindenképpen a többi #-kal kezdődő sorokhoz.
A short pozíciónál ugyanez az eljárás, de ott a Parabolic trendchaser indikátor felső pöttyének az értékét fogjuk beállítani.
A FOREX robotunk még nem az igazi, összeraktuk, készre csiszoltuk, de még nem políroztuk fel, ugyanis vannak még szépség hibái.
Például az, hogyha a Parabolic trendchaser indikátor éppen nem mutat alul pöttyöt, csak felül (mert ugye ez is egy Parabolic SAR rokon és vagy fönt, vagy lent vannak pöttyei), akkor nem húz stopot a program.
Akkor sem fog stopot húzni, hogyha túlságosan közel vagyunk pillanatnyi árhoz.
Ezeket az eseményeket le kell kezelnünk, különben stop nélkül maradunk és nem, vagy túl későn lesz lezárva a pozíciónk, amiből komoly veszteségek származhatnak.
Mindenesetre ez a kis program jól szemlélteti, hogy hogyan érdemes nekifeszülni egy ilyen program megírásának és mire érdemes gondolni közben.
A következő post-ban a legutóbbi két esemény kezelésével foglalkozunk, megoldást keresünk rá, szemléltetve a MetaTrader további lehetőségeit.
Ezután a teljes programkódot közzéteszem, hogyha valakinek nincs kedve az egészet begépelni, vagy ha esetleg lemaradt, akkor egyben láthatja a kódot.
Telis-tele lesz megjegyzésekkel, hogy mi miért van, így talán azok is követni tudnak majd, akik eddig nem olvasták el az összes post-ot.
Ha pedig mindenki a kezébe kaparintotta a működő robotot, jöhet a tesztelés, melynek fázisait szintén végignézzük, illetve a fejlesztés további szakaszai jönnek, a veszteségek kiküszöbölése és egy jó kis money management kerül bele.