Zadání pokynu a omezovač vstupů do EA (díl 4.)

V minulém díle jsme skončili v okamžiku, kdy jsme po zadání kódu pro odeslání příkazu do trhu obdrželi 5 errorových hlášek.

Povězme si nyní více o definici příkazu OrderSend.

OrderSend (symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color)

Příkaz má 11 parametrů, které daný příkaz definují a znamenají následující:

Symbol – definuje měnový pár, na kterém chceme pozici zadat. Zde jsme zadali příkaz Symbol (). Je zde možno definovat měnový pár textovým řetězcem a uvést konkrétně např. EURUSD či jiný pár. Problém je, že EA pak bude fungovat/zadávat příkazy pouze na tomto měnovém páru. Příkaz Symbol() sám přiřadí ten měnový pár z grafu, na který naši EA umístíme. Tím bude naše EA univerzální a použitelná pro libovolný měnový pár.

Cmd – definuje typ příkazu, tzn. zda půjde o příkaz typu market (okamžitý vstup do trhu), nebo o čekající pokyn typu LIMIT nebo STOP (více o typech příkazů v tomto článku). Každý typ má svůj kód, a nebo může být vyjádřen číslicí. Doporučujeme používat textové značení, lépe si ho pamatujete. Rozeznáváme tedy:

OP_BUY (nebo číselný kód:0) pro pokyn typu MARKET a typ pozice buy (long/nákup)

OP_SELL (1) pro pokyn typu MARKET a typ pozice sell (short/prodej)

OP_BUYLIMIT (2) pro pokyn typu LIMIT a typ pozice buy (long/nákup)

OP_SELLLIMIT (3) pro pokyn typu LIMIT a typ pozice sell (short/prodej)

OP_BUYSTOP (4) pro pokyn typu STOP a typ pozice buy (long/nákup)

OP_SELLSTOP (5) pro pokyn typu STOP a typ pozice sell (short/prodej)

V našem případě chceme vstupovat za market do pozice long, zadáme tedy OP_BUY.

Volume – definuje velikost pozice. Můžeme zadat „natvrdo“ např. 0.01 lotu, tak jako jsem to udělali my. Nicméně můžeme to opravit, aby byla EA více „flexibilní“. Místo 0.01 zadáme proměnou „Velikost_pozice“. Tuto novou proměnnou vydefinujeme jako externí proměnou, abychom jí mohli libovolně měnit. Jelikož velikost pozice může být desetinné číslo, použijeme datový typ double.

extern double Velikost_pozice = 0.01; // definice velikosti pozice pro obchodování

Price – je cena, za kterou chceme vstoupit. Pokud chceme vstoupit za MARKET volíme buď cenu Ask (pro buy/long) a nebo Bid (pro sell/short). U pokynů typu LIMIT nebo STOP zadáváme cenu v závislosti na pravidlech strategie, kterou programujeme. Ukážeme si to prakticky v některém z příštích dílů. V našem případě volíme cenu Ask.

Slippage – zde je možné zadat max. požadovanou odchylku při exekuci příkazu

Stoploss – zde zadáme cenu, na které chceme obchod ukončit, pokud se vyvíjí proti nám. Definovali jsem ho rovnicí Ask-SL. Ask znamená aktuální tržní cenu (za ní jsme do obchodu vstoupili) a tuto cenu snížíme o požadovaný stoploss. Proměnou SL jsme zatím nedefinovali. Definovali jsme pouze proměnnou StopLoss_v_pipech. Nemůžeme však použít Ask-StopLoss_v_pipech, neboť StopLoss_v_pipech je 200 pipů tzn. rovnice by počítala např. 1,3215 (aktuální market) – 200 a to se rovná -198,6785! Musíme tedy převést pipy do cenového vyjádření. Většinu z vás napadne upravit rovnici takto: Ask – StopLoss_v_pipech/10000. Není to špatně, ale má to řadu úskalí, jako to, že to funguje pouze u brokera se 4 místnou cenou. U pětimístného brokera by bylo potřeba přidat za 10.000 ještě jednu nulu. Druhý problém bude např. u USDJPY. Páry s japoncem bychom museli dělit pouze 100 (resp. 1000 u 5-ti místného brokera). Musíme tedy najít flexibilnější řešení a tím je použít příkaz Point. Ten vrátí hodnotu cenového vyjádření jednoho pipu pro daný měnový pár. Pro EURUSD u čtyřmístného brokera se Point = 0,0001, pro USDJPY = 0,01 atd. Správný zápis tedy je: Ask – StopLoss_v_pipech*Point

Tady navrhujeme definovat novou proměnnou SL = StopLoss_v_pipech*Point (datový typ double) a rovnici pak zjednodušit na Ask-SL. Oba zápisy fungují stejně, ale důvod je ryze praktický. SL se snadněji napíše (a u složitějších EA budeme nuceni používat tuto proměnnou vícekrát) a zároveň je celý kód přehlednější. Často to bývá praktické u složitějších a rozsáhlejších EA. Naprogramujete EA, která bude obsahovat několik pozic, a později se rozhodněte měnit způsob stanovení stoplossu. Pak musíte jít do každého příkazu a přepsat rovnici, která stoploss definuje. Kdežto v našem případě pouze změníte rovnici pro proměnnou SL a zbytek kódu měnit nemusíte.

TakeProfit – zde zadáme cenu, na které chceme vystoupit, když jde obchod naším směrem. V našem případě to uděláme analogicky, jako u SL. Nadefinujeme novou proměnnou PT = Profit_Target_v_pipech* Point a do OrderSend zapíšeme výstupní cenu jako Ask+PT. Pokud nechceme stanovit žádný PT, můžeme doplnit pouze 0. To použijeme v případech, kdy budeme pozici uzavírat buď na základě nějakého naprogramovaného trailing stopu či dle splnění jiných specifických podmínek (ukážeme si v některém z dalších dílů).

Obdobně lze použít nulu (= nezadání cílové ceny) i u SL. Úmyslně jsem to v předchozím odstavci nezmínili, neboť jsme přesvědčeni, že žádný obchod by neměl být bez SL. Ale technicky to možné je. Dávejte si na to pozor! Víme, že někdo SL nepoužívá a má v EA naprogramované ukončení příkazu při splnění některých podmínek a tím chrání svůj účet. Upozorňuji, že je to nebezpečné. Může se například stát, že zadáte příkaz (je bez SL). Pak dojde k výpadku proudu a váš počítač se vypne. V tom okamžiku vaše EA nefunguje, a ačkoliv nastali podmínky pro ukončení obchodu, váš obchod se neukončí, neboť EA není funkční. Když se pak dostanete k počítači, můžete být Váš obchod v daleko větší ztrátě!

Comment – slouží pro zadání komentáře. Nemusí se zde nic zadávat, nicméně my to používáme, neboť tento text se tak objevuje v MT4 jako komentář k obchodu. Pokud obchodujete na jednom účtu více strategií/EA, hodně vám to usnadní orientaci, který obchod patří ke které EA. Opět využijeme definici pomocí nové proměnné, kterou pojmenujeme „Text“. Jelikož se jedná o textovou proměnnou, použijeme pro její definici datový typ string. Text musí být v uvozovkách.

string Text = „Moje první strategie“

Text „Moje první strategie“ můžeme dát přímo do OrderSend, ale zase platí, že u složitějších EA by bylo náročně text na všech místech přepisovat v případě změny …

Magic – zde se zadává tzv. magické číslo. Nehledejte v tom nic mystického. Toto číslo pomáhá při identifikaci jednotlivých příkazů zadaných na vašem účtu, resp. k identifikace příslušnosti příkazu k dané EA. Vysvětlíme si to a ukážeme později. Můžeme napsat natvrdo číslo např. 1122, ale my opět použijeme zápisu přes proměnnou definovanou jako Magic_number …

Expiration – zde můžeme definovat dobu platnosti pokynu. Lze pouze pro čekající pokyny, což není náš případ, neboť mi jsme vstupovali za market. Jak definovat délku platnosti pokynu si ukážeme později, až si budeme zkoušet čekající pokyny.

Arrow_color – zde můžeme napsat barvu, např. „Blue“ či „Red“ atd. Pokud zde uvedeme nějakou barvu, tak když se pokyn zadá, tak se v grafu objeví šipka dle zvolené barvy. My toto používáme a zadáváme si modrou barvu pro LONG a červenou pro SHORT. Je to spíše grafická pomůcka a nemá to žádný vliv na zadávaný pokyn.

Doufáme, že teď již složitému zápisu OrderSend(Symbol(),OP_BUY,0.01,Ask,0,Ask-SL,Ask+PT,Text,Magic_number,0,Blue) rozumíte. Z výkladu je také patrné, že errory, které se objevily, jsou důsledek toho, že jsme použili proměnné, které jsme neměli definované a to: SL, PT, Magic_number a Text. Chybí ještě definovat proměnnou „ticket“. To je proměnná, kterou přiřadíme k příkazu OrderSend. Pokud by se při používání EA pokyn v reálu nezadal, proměnná ticket dosáhne hodnoty -1 a to lze využít pro zjištění důvodu, proč se příkaz nezadal (ale to si ukážeme později).

Aby bylo vše jasné, podívejme se, jak vypadá naše EA po posledních úpravách. Musíme doplnit definice proměných SL, PT, Magic_nuber, Text a ticket. Nesmíme zapomenout definovat ještě novou externí proměnnou Velikost_pozice, jak jsme se rozhodli výše. Doplníme kód a stiskneme „Compile“.

V červených polích vidíte naše poslední úpravy a dole informaci o tom, že již nemáme žádné chyby.

Zdálo by se, že již máme práci hotovou, ale ještě chybí jedna věc, aby byla EA funkční, a to „omezovač vstupů“. To je náš laický název souboru operací, které zajistí, aby se náš pokyn zadal pouze jednou. Proč nějaký omezovač potřebujeme? EA funguje tak, že když ji zaktivujeme, běží od prvního řádku kódu až na konec, kde je příkaz return. Vrátí se zpátky na začátek a „jede“ znovu. Tento cyklus zopakuje několikrát za vteřinu. V okamžiku, kdy jsou splněny podmínky pro vstup do trhu (v našem případě neděle, 23 hodin a 0 minut) zadá se příkaz. Během minuty však EA udělá několik cyklů a pokaždé by došlo k zadání pokynu. To samozřejmě nechceme, chceme zadat jen jeden pokyn. Musíme tedy do našeho kódu naimplementovat „omezovač vstupů“.

V platformě MT4 může být zadáno např. deset pokynů. My potřebujeme zjistit, zda některý z nich už není zadaný pokyn z naší EA. Pokud ne, necháme EA, aby ho zadala. Pokud však již pokyn zadán bude, chceme zabránit tomu, aby se zadal pokyn znovu. První co potřebujeme vědět je, kolik pokynů je momentálně zadáno v platformě MT4. K tomu použijeme příkaz OrdersTotal(), ten nám řekne, že momentálně je to např. 10 pokynů. Teď tedy musíme jít pokyn po pokynu a zjistit, zda je či není z naší EA. Zavedeme si počítadlo (proměnnou q), kde q bude 1, 2, 3, … 10 a pak chceme testovat pro příkaz 1, zda je jeho Magic number shodné s magic number naší EA … pak to samé pro příkaz 2 … 3 … až 10. Pokud ani v jednom případě nenajdeme pokyn s naším magic number, tak bude program pokračovat dál a zadá se pokyn. Pokud však nalezneme jeden pokyn se shodným magic number, tak vložíme příkaz return a dál program nepustíme, a bude se muset vrátit na začátek. Teoreticky víme, co chceme a teď to musíme přetvořit do kódu.

Pro výběr pokynu použijeme příkaz OrderSelect(q, SELECT_BY_POS, MODE_TRADES). q je pořadové číslo, druhý parametr je způsob výběru. Zde jsou dvě možnosti SELECT_BY_TICKET (výběr podle čísla ticketu) nebo SELECT_BY_POS (výběr podle pořadí pokynu). Použijeme tedy SELECT_BY_POS. Třetí parametr má také dvě možnosti: MODE_TRADES (vybírá z aktivních či čekajících pokynů) nebo MODE_HISTORY (vybírá z ukončených nebo zrušených příkazů). Nás zajímají ty aktivní, takže zadáme MODE_TRADES. Tímto příkazem jsme vybrali pokyn dle jeho pořadí a zjistíme, zda jeho magic number je shodné, a to příkazem OrderMagicNumber(). Tento příkaz zjistí hodnotu magic number vybraného příkazu. A teď už můžeme sestavit podmínku:

if(OrderSelect(q, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber()==Magic_number) {return(0);}

Jinak řečeno když u vybraného pokynu (v pořadí q = 1,2, … 10) je magic number rovno našemu magic number potom se vrať na začátek programu.

Nicméně ještě musíme vyřešit to počítadlo. K tomu použijeme operátor for. Začneme s q = 0 a pak zvýšíme q na 1, následně na 2 … Kdy skončíme? Nevíme přeci kolik příkazů v platformě MT4 bude v jakém okamžiku? Můžeme nastavit mezní hodnotu pro q = 1000, neboť tolik pokynů v jednom okamžiku mít na účtu nebudeme, ale to bychom program zbytečně zahlcovali velkým množstvím operací. Využijeme proto příkaz OrdersTotal(), ten (jak již víme) zjistí aktuální počet pokynů v platformě. Zápis počítadla by pak vypadal takto:

for(q = 0; q < OrdersTotal(); q++) { }

Jinak řečeno začínám od nuly a přičítáme vždy jedničku. Pokud bude q méně než aktuální počet pokynů v platformě, tak vykonám příkazy v závorce.

Teď spojíme počítadlo s předchozí podmínkou a omezovač vstupů je hotov. Pozor na konci vzniknou dvě závorky. Pokud tam dáte jen jednu, EA nebude fungovat.

Doplníme omezovač do naší EA a celý kód zkontrolujeme. Při kontrole jsme objevili ještě dva nedostatky, které opravíme. Vydefinovali jsme novou externí proměnnou Velikost_pozice, ale zapomněli jsem ji dát do kódu zadání pokynu OrderSend. Druhou věc, kterou ještě změníme je podmínka vstupu, kdy m == 0. Někteří brokeři otevřou trh s malým zpožděním (říkali jsme si to v minulém díle) takže upravíme podmínku na m < 5.

Nezapomeňte kliknout na Compile a naše první EA je hotová. V příštím díle se podíváme, jak se chová EA v platformě MT4, otestujeme ji a ukážeme si jak zkontrolovat v grafu, zda EA dělá to, co skutečně chceme.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *