9. MQL4 - Moje první strategie (1/2)

Napsal Geafer 31.08.2010 18:21 Sekce MQL4

V tomto díle si společně napíšeme vlastní strategii. Začneme nejprve vytvořením knihovny s pomocnými funkcemi pro obchodování.

 

TradeLib - Knihovna pro práci s pokyny

Ještě než začneme psát hlavní část strategie, napíšeme si pomocnou knihovnu obecných funkcí pro práci s pokyny, kterou můžeme kdykoli použít při vývoji dalších strategií. Kompletní souboru je ke stažení na konci kapitoly. Pro ty, co si jej chtějí vytvořit sami, následuje postup.

 

1.     Vytvoření souboru

Začneme vytvořením Include skriptu. V MetaEditoru založte nový skript kliknutím v menu na File -> New, nebo klávesovou zkratkou Ctrl+N a v průvodci vyberte položku Include (*.MQH). Include soubory jsou sady funkcí, které lze připojit k jiným skriptům.

[obrázek]

Klikněte na tlačítko Další a v dialogu vyplňte jméno skriptu TradeLib.

[obrázek]

Veškeré komentáře, které průvodce vygeneroval, můžete smazat a ponechat kód ve stavu, jaký zobrazuje obrázek.

[obrázek]

 

2.     Funkce IsTicketOpen()

Tato funkce zjistí, zda je konkrétní pokyn ještě otevřen, nebo ne. Může se stát, že se pokyn zavře překročením ceny StopLoss nebo TakeProfit, případně pokyn zavře broker. Potom je třeba vědět, zda lze s pokynem ještě něco vykonávat v rámci obchodu.

// Zjistí, zda je pokyn otevřený
// ticketId = identifikátor pokynu
bool IsTicketOpen(int ticketId)
{
   if(OrderSelect(ticketId, SELECT_BY_TICKET))
   {
      return(OrderCloseTime() == 0);
   }
   else
   {
      return(false);
   }  
}

Funkce přejímá jeden parametr a to ID pokynu a vrací True , pokud je pokyn otevřen, jinak False. Tělo funkce se skládá z podmínky, kde pomocí funkce OrderSelect() vybereme konkrétní pokyn dle jeho ID. Pokud funkce proběhne v pořádku, zjistíme pomocí funkce OrderCloseTime(), zda je datum zavření pokynu nastaveno nebo ne. Pokud není, pokyn je ještě otevřen.

 

3.     Funkce OpenTicket()

Tato metoda provede otevření pokynu a vrátí jeho ID. Metoda uvažuje pouze přímé pokyny. Pokud potřebujete otevřít čekající pokyn, je třeba si do knihovny napsat svou vlastní podporu.

// Otevře nový pokyn
// symbol = identifikace měnového páru
// isBuy = pokud je True, nakupuje se, jinak se prodává
// lots = počet lotů, které se má obchodovat
// slPips = počet pipů pro nastavení ceny stoploss
// tpPips = počet pipů pro nastavení ceny takeprofit
int OpenTicket(string symbol, bool isBuy, double lots, int slPips, int tpPips)
{
   double price;  // preferovaná cena
   int op;        // typ operace
   // cena stoplossu
   double slPrice = getPipPrice(symbol, slPips, isBuy, true);
   // cena takeprofitu
   double tpPrice = getPipPrice(symbol, tpPips, isBuy, false);
   
   // nastavíme preferovanou cenu a typ operace
   if(isBuy)
   {
      price = MarketInfo(symbol, MODE_ASK);
      op = OP_BUY;
   }
   else
   {
      price = MarketInfo(symbol, MODE_BID);
      op = OP_SELL;
   }
   
   int ticketId = OrderSend(symbol, op, lots, price, 0, slPrice, tpPrice, NULL, 0, 0, CLR_NONE);
   
   // pokud se pokyn nepodaří otevřít, vypíšeme číslo chyby do logu
   if(ticketId == -1)
   {
      Print("Otevírání pokynu: Chyba č. ", GetLastError());
   }
   
   return(ticketId);
}

Nejdříve si nadeklarujeme pár proměnných jako je preferovaná cena a typ operace. Pak stanovíme cenu pro stoploss a takeprofit. K tomu použijeme pomocnou funkci getPipPrice(), kterou si popíšeme později. Dále nastavíme cenu a typ operace. V kódu se pro vás objevuje nová funkce MarketInfo(). Tato funkce zjišťuje informace o cenách a vrací stejné informace jako předdefinované proměnné (Ask, Bid, Digits, atd.). Ale protože píšeme obecnou funkci, nemůžeme se spoléhat na to, že jiný skript bude uvažovat stejný měnový pár, jaký by vrátila funkce Symbol(). Proto naše funkce vyžaduje zadat, pro jaký měnový pár se daná operace má vykonat a pomocí funkce MarketInfo() si již zjistíme, co potřebujeme. Po nastavení správných cen, již zavoláme funkce pro otevření pokynu OrderSend(). Pokud se nepodaří otevřít pokyn, zalogujeme chybu, pro případné pozdější zkoumání.

 

4.     Pomocná funkce getPipPrice()

Tato funkce spočítá cenu StopLoss a TakeProfit na základě počtu bodů, které uživatel zadal.

// Vrátí cenu pro daný počet pipů vůči aktuální ceně
// symbol = identifikace měnového páru
// pips = počet pipů
// isBuy = určuje, zda se jedná o nákup
// isSL = určuje, zda se jedná o SL, jinak je to TP
double getPipPrice(string symbol, int pips, bool isBuy, bool isSL)
{
   double price;        // obchodní cena
   double result = 0;   // výsledná hodnota
   
   if(pips > 0)
   {
      // funkce defaultně počítá cenu pro SL
      // pokud se jedná o TP, otočíme znaménko pro výpočet
      if(isSL == false)
         pips = pips * (-1);
         
      if(isBuy)
      {
         price = MarketInfo(symbol, MODE_ASK);
         result = NormalizeDouble(price - pips * MarketInfo(symbol, MODE_POINT), 
MarketInfo(symbol, MODE_DIGITS));    
      }
      else
      {
         price = MarketInfo(symbol, MODE_BID);
         result = NormalizeDouble(price + pips * MarketInfo(symbol, MODE_POINT), 
MarketInfo(symbol, MODE_DIGITS));
      }
   }

   return(result);   
}

Pomocí funkce MarketInfo() si zjistíme potřebné hodnoty a pak dle vzorce vypočítáme cenu na základě předaných parametrů.

 

5.     Funkce CloseTicket()

Když už máme otevřený pokyn, je třeba napsat funkci, která jej také zavře. Funkce zavírá celý objem obchodu. Pokud potřebujete částečné zavírání pokynu, je třeba si funkci upravit nebo napsat novou.

// Pokusí se zavřít pokyn. Vrací 0, pokud je vše v pořádku, jinak vrací číslo chyby
// ticketId = identifikace pokynu
int CloseTicket(int ticketId)
{
   if(IsTicketOpen(ticketId))
   {
      double price;  // preferovaná cena zavření
     
      // nastavíme preferovanou cenu dle typu operace
      if(OrderType() == OP_BUY)
         price = MarketInfo(OrderSymbol(), MODE_BID);
      else
         price = MarketInfo(OrderSymbol(), MODE_ASK);
         
      if(OrderClose(ticketId, OrderLots(), price, 0, CLR_NONE))
      {
         return(0);
      }
      else
      {
         // chyba při zavírání
         Print("Zavírání pokynu: Pokyn č. ", ticketId, " se nepodařilo zavřít. Chyba č. ", 
GetLastError());
         return(2);
      }
   }
   else
   {
      // Pokyn je již zavřen nebo nebyl nalezen
      Print("Zavírání pokynu: Pokyn č. ", ticketId, " již nelze zavřít");
      return(1);
   }
}

Nejdříve zjistíme, zda je pokyn otevřen. K tomu se nám hodí funkce IsTicketOpen(), která zároveň provede výběr pokynu. Pokud je pokyn otevřen, zjistíme typ operace, nastavíme cenu a pomocí funkce OrderClose() pokyn zavřeme. V případě, že operace neproběhne v pořádku, zapíšem chybu do logu.


6.     Funkce IsTimeToTrade()

Tato funkce zjistí, zda je čas pro otevírání pokynů. V parametrech přejímá kritéria času v jednom rozptylu. Funkci lze např. napsat, tak, aby kontrolovala sérií časových rozmezí, ale pro náš příklad bohatě postačí.

// Určuje, zda je čas pro obchodování
// startHour = hodina pro zahájení obchodování
// startMinute = minuta pro zahájení obchodování
// stopHour = hodina pro ukončení obchodávní
// stopMinute = minuta pro ukončení obchodování
bool IsTimeToTrade(int startHour, int startMinute, int stopHour, int stopMinute)
{
   // zjistíme aktuální čas
   datetime currentTime = TimeCurrent();

   // převedeme si časy na minuty   
   int start = startHour * 60 + startMinute;
   int stop = stopHour * 60 + stopMinute;
   int current = TimeHour(currentTime) * 60 + TimeMinute(currentTime);
   
   return(current >= start && current <= stop);
}

Ve funkci si převedeme čas na minuty a porovnáme, zda spadá mezi zadané limity.

 

7.     Funkce TrailStopLoss()

Tato funkce má za úkol posouvat cenu StopLoss daného pokynu na základě zadaných parametrů.

// Provede posunutí ceny StopLoss
// ticketId = ID pokynu
// pipsDiff = počet pipů, po kolika se má posunout SL
// pips = počet pipů, na kolik se má nastavit SL
// useBE = určuje, jestli se má při prvním posunu nastavit SL na BE
void TrailStopLoss(int ticketId, int pipsDiff, int pips, bool useBE)
{
   if(IsTicketOpen(ticketId))
   {
      string symbol = OrderSymbol();
      double pointValue = MarketInfo(symbol, MODE_POINT);
      double openPrice = OrderOpenPrice();
      double slPrice = OrderStopLoss();
      double currentPrice;
      double newSL = 0;
      
      // zjistíme aktuální cenu
      if(OrderType() == OP_BUY)
      {
         currentPrice = MarketInfo(symbol, MODE_ASK);
         if(useBE && (openPrice > slPrice))
         {
            // zjistíme, zda je čas posunout SL na BE
            if(currentPrice > (openPrice + pointValue * pipsDiff))
               newSL = NormalizeDouble(openPrice, MarketInfo(symbol, MODE_DIGITS));
         }
         else
         {
            // zjistíme, zda je čas posunout SL
            if(currentPrice > (slPrice + pointValue * pipsDiff + pointValue * pips))
               newSL = NormalizeDouble(currentPrice - pointValue * pips, 
MarketInfo(symbol, MODE_DIGITS));
         }
      }
      else
      {
         currentPrice = MarketInfo(symbol, MODE_BID);
         if(useBE && (openPrice < slPrice))
         {
            // zjistíme, zda je čas posunout SL na BE
            if(currentPrice < (openPrice - pointValue * pipsDiff))
               newSL = NormalizeDouble(openPrice, MarketInfo(symbol, MODE_DIGITS));
         }
         else
         {
            // zjistíme, zda je čas posunout SL
            if(currentPrice < (slPrice - pointValue * pipsDiff - pointValue * pips))
               newSL = NormalizeDouble(currentPrice + pointValue * pips, 
MarketInfo(symbol, MODE_DIGITS));
         }
      }
      
      if(newSL > 0)
      {
         if(OrderModify(ticketId, openPrice, newSL, OrderTakeProfit(), 0, CLR_NONE) == false)
         {
            Print("Chyba při posouvání ceny StopLoss, chyba č. ", GetLastError());
         }
      }
   }
}

Nejdříve zjistíme, zda je pokyn otevřen, poté zjistíme potřebné hodnoty pro výpočet nové ceny SL. Pokud je parametr useBE nastaven na True, nastavuje se cena SL na BE (Break Even – cena na hranici otevírací ceny, kdy obchodník již nemůže přijít o svou investici) a to pouze pokud je cena SL stále pod otevírací cenou. Poté se již matematicky vypočítá nová hodnota SL a upraví pokyn.

Kompletní soubor TradeLib.mqh si můžete stáhnou zde.

 

Sdílej na Google Buzz Delicious pošli na vybrali.sme.sk

 


Diskuse ke článku

Diskuse je přístupná pouze pro registrované uživatele.
Přihlásit se | Nová registrace

Autor Geafer

avatar
Zdeněk Hübner, člen teamu FXstreet.cz
Hodnocení autora:

Kategorie blogu

Kurzy obchodování

úno
4
Začínáme s FOREXEM - Efektivní seminář online – webinář

Nový exkluzivní online seminář. Získejte kompletní přehled o základech obchodování na Forexu a načerpejte forexové know-how v pohodlí domova. Zahrňte nás dotazy, na něž byste se na live semináři báli zeptat.

úno
25
Juniorská škola tradingu - Forex I-II (Praha)
Juniorská škola tradingu - Forex I-II je určený pro začínající tradery. Pokud toho o Forexu zatím moc nevíte ale máte chuť začít něco nového, naučit se úspěšně obchodovat.

Led
1
Profesionálem na Forexu - kurz pro pokročilé tradery
Seminář Profesionálem na Forexu - kurz je určený pro absolventy juniorské školy Forexu a pokročilé FX tradery.  
Sleva: Absolventi semináře Juniorská škola tradingu  mají tento seminář za 3.600,-Kč.
Led
1
Praktický workshop technické analýzy + profi obchodní systémy na Forexu

FXstreet.cz představuje nový exkluzivní seminář s hostem - Patrikem Urbanem, který působil jako profesionální trader na Wall Streetu. Praktické použití technické analýzy a metody profesionálních traderů.

Literatura

Kniha FOREX obálka
Jak se stát FOREXOVÝM obchodníkem - Ondřej Hartman

Server FXstreet přichází s jedinečnou novinkou - knihou, která vás naučí, jak vydělávat na největším a nejoblíbenějším finančním trhu světa - Forexu. Obsahuje vůbec nejkomplexnější informace, rady a tipy, které doposud o obchodování na měnových trzích v ČR a SK vyšly.

raghee horner.jpg
Novinka: kniha "Forex tradingem k maximálním ziskům" od Raghee Horner vychází v češtině!

Nejúspěšnější kniha Raghee Horner v češtině. Kniha představuje vynikající návod pro začínající a středně pokročilé obchodníky a obsahuje velmi konkrétní obchodní techniky, oblíbené cenové patterny, vstupy, výstupy a množství dalších rad, tipů a zkušeností.

krotitele trhu 2.jpg
Krotitelé trhů - Inspirujte se příběhy George Sorose, Warrena Buffetta a Paula Volckera

Krotitelé trhů George Soros a Warren Buffett patří mezi nejlepší investory všech dob. Vy se z jejich příběhů můžete poučit. Podívejte se na dění na finančních trzích pohledem světových osobností.


reklama