English Русский 中文 Español 日本語 Português
Die Grundlage der Programmierung eines Hedge Expert Advisor

Die Grundlage der Programmierung eines Hedge Expert Advisor

MetaTrader 4Beispiele | 9 Februar 2016, 09:36
1 853 0
chayutra sriboonruang
chayutra sriboonruang

Einführung

Ich werde eine Vorstellung von einem einfachen Hedge Expert Advisor geben. Die Big Note der Hedging EA Grundlagen:

  • Hedge (Finanzwesen) (Übersetzt aus der englischen Wikipedia, der freien Enzyklopädie)

    (Weitergeleitet von Hedging)

    In der Finanzwelt ist eine Absicherung (engl. Hedge) eine Investition, die speziell zum Verringern oder Aufheben des Risikos einer anderen Investition vorgenommen wird. Hedging ist eine Strategie, die entwickelt wurde, um das Auftreten eines unerwünschten Geschäftsrisikos zu minimieren. wobei es weiterhin einen Gewinn aus einer Geschäftstätigkeit ermöglicht. Typischerweise könnte ein Hedger z.B. in einen Finanzwert investieren, von dem er glaubt er liegt unter Preis, im Verhältnis zu seinem "Fairen Wert" (zum Beispiel ein Hypothekendarlehen, das er dann macht), und kombiniert dies mit einem Leerverkauf eines entsprechenden Finanzwerts oder Finanzwerten. Somit kümmert es den Hedger nicht, ob der Markt als Ganzes steigt oder fällt, sondern nur ob der unterbewertete Finanzwert in Bezug auf die Absicherung aufwertet. Holbrook Working, ein Pionier der Hedging-Theorie, nannte diese Strategie "Spekulation an der Basis"[1], wobei die Basis die Differenz zwischen dem theoretischen Wert der Absicherung und ihren tatsächlichen Wert ist (oder zwischen Spot und Futures Kursen in Workings Zeit).

    Eine Form der Risikobereitschaft gehört zum Wesen jeder Geschäftstätigkeit. Einige Risiken werden bei bestimmten Geschäften als "natürlich" betrachtet, wie das Risiko, dass der Ölpreis steigt oder fällt für Ölförder- oder Raffinerie-Unternehmen. Andere Formen von Risiko sind nicht erwünscht, können ohne Hedging/Absicherung aber nicht vermieden werden. Jemand, der einen Laden hat, zum Beispiel, kann sich um natürliche Risiken kümmern, wie das Risiko des Wettbewerbs, von schlechten oder unbeliebten Produkten, und so weiter. Das Risiko, dass das Inventar des Ladenbesitzers durch ein Feuer zerstört wird, in unerwünscht, allerdings kann es über eine Feuerversicherung-Police abgesichert werden. Nicht alle Absicherungen sind Finanzinstrumente: ein Hersteller, der in ein anderes Land exportiert, zum Beispiel, kann das Währungsrisiko bei Verkäufen abgesichert werden, indem Kosten mit der gewünschten Währung verbunden werden.
    lesen Sie hier mehr

  • Alles, was wir vom Server brauchen, muss durch die MarketInfo (string Symbol, int Typ) Funktion aufgerufen werden. Diese Funktion ermöglicht es uns, alle Daten über die im Chart-Fenster erscheinenden hinaus abzurufen. Dies ermöglicht uns außerdem jede Art von Order mit jedem Symbol, über das aktiv im Chart-Fenster angezeigt hinaus, zu senden. Und dies lässt uns die 2 Symbole einfach absichern (hedgen). Dank Gott und den MT4 Team-Mitgliedern, hilft es so viel.

  • Eine notwendige Sache bei der Absicherung, ist die Korrelation zwischen den 2 beobachteten Symbolen, die mit einigen kleinen Funktionen herausfinden, die unten beschrieben werden.

    Korrelation, in der Finanzwelt, ist das statistische Maß der Beziehung zwischen zwei Wertpapieren. Der Korrelation-Koeffizient liegt zwischen -1 und +1. Eine Korrelation von +1 bedeutet, dass zwei Währungspaare sich in 100% der Zeit in die gleiche Richtung bewegen. Eine Korrelation von -1 bedeutet, dass zwei Währungspaare sich in 100% der Zeit in entgegengesetzte Richtungen bewegen. Eine Korrelation von 0 bedeutet, dass die Beziehung zwischen den Währungspaare komplett zufällig ist. lesen Sie hier mehr


Alles oben genannt sind einfache Dinge, die Forex Hedger mit der Verwendung von MT4 Expert Advisors wissen müssen. Jetzt können wir anfangen einen Hedge/Absicherungs-EA zu erstellen.



Schritt für Schritt zur Programmierung des Hedge-EA

Schritt 1: Die Eingabe-Parameter

Zuerst, bevor wir anfangen den Hedge-EA zu schreiben, müssen wir zwei korrelierende Symbole auswählen. d.h.:

  • GBPUSD & EURUSD die sich immer in die gleiche Richtung bewegen,
  • EURUSD & USDCHF die sich immer in die entgegengesetzte Richtung bewegen,
  • * usw.

In diesem Artikel werde ich mein eigenes Lieblings-Hedge-Paar wählen, und das ist EURJPY UND GBPJPY. Es bewegt sich immer in die gleiche Richtung, was es einfacher macht den Order-Typ der Absicherung einzustellen. Fangen wir an. Um mit der Erstellung eines Hedge-EA zu beginnen, machen wir uns unten mit den Eingabevariablen bekannt.


// this is to block the order sending function but 
// not to block the close function.
extern bool BlockOpening = false; 
 
extern string BaseSymbol = "EURJPY";//the 1st symbol 
 
extern string H_Symbol = "GBPJPY";//the 2nd symbol 
 
extern bool MoveSameWay = true;//they move the same way or not 
 
extern int CorPeriod = 5;//your favorite correlation period 
 
extern double BaseLotSize = 1.5;//1st symbol lotsize 
 
extern double H_LotsSize = 1.0;//2nd symbol lotsize 
 
extern double ExpectProfit$ = 137;//your expect profit in USD 
//your acceptable loss in USD in case any error occurred 
extern double AcceptableLoss$ = -77; 
 
extern string ExpectCor = "______";//your expect correlation to hedge 
//this is the upper expect cor value and has to be greater than "And" 
extern double Between = 1.05; 
 
extern double And = 0.9;//this is the lower expect cor level 
 
extern string MISC = "______";//some thing more 
 
extern int MagicNo = 318;//your favorite magic number 
 
extern bool ShowStatus = true;//to show the present hedging status 
//to play sound when SendH and CloseH function done 
extern bool PlayAudio = false;

Schritt 2: Die Variablendeklaration


Im Folgenden sind die in diesem EA verwendeten Variablen und ich werde nur die Variablen erklären, die notwendig sind, um zu verstehen wie der EAA funktioniert.


int BSP       // the spread of base symbol 
 
    , HSP      // the spread of hedge symbol 
 
    , gsp 
 
    , BOP = -1 // base symbol order type 
 
    , HOP = -1 // hedge symbol order type 
 
    , up = 0 
 
    , Hcnt = 0 
 
    , u = 0 
 
    , d = 0 
 
    , day = 0 
 
    , sent=0 
 
    , firstopen 
 
    , expire; 
 
double Lot 
 
       , BaseOpen // base symbol order open price 
 
       , HOpen    // hedge symbol order open price 
 
       , BPt      // base symbol Point value 
 
       , HPt      // hedge symbol Point value 
 
       , BSwapL   // base symbol swap long value 
 
       , BSwapS   // base symbol swap short value 
 
       , HSwapL   // hedge symbol swap long value 
 
       , HSwapS;  // hedge symbol swap short value 
 
 
bool SResult = false, BResult = false, H1.profitswap, 
     H2.profitswap, H3.profitswap; 
 
bool SwapMode = true, allmeetcor = false, BlockOpen = false, 
     buy,sell,cleared = false; 
 
string H1.string = "", H2.string = "", H3.string = "", 
       OrdComment = "", candletxt,tdstxt = "";

Schritt 3: Erhalten aller Notwendigen Statistic Parameter


Geben wir nun einige statistische Werte an, die im int() Teil deklariert werden.


//+------------------------------------------------------------------+ 
//| expert initialization function                                   | 
//+------------------------------------------------------------------+ 
 
int init() 
  { 
    //---- 
    BSP = MarketInfo(BaseSymbol,MODE_SPREAD); 
    HSP = MarketInfo(H_Symbol ,MODE_SPREAD); 
    BPt = MarketInfo(BaseSymbol,MODE_POINT); 
    HPt = MarketInfo(H_Symbol ,MODE_POINT); 
    BSwapL = MarketInfo(BaseSymbol,MODE_SWAPLONG); 
    BSwapS = MarketInfo(BaseSymbol,MODE_SWAPSHORT);
    HSwapL = MarketInfo(H_Symbol,MODE_SWAPLONG); 
    HSwapS = MarketInfo(H_Symbol,MODE_SWAPSHORT); 
//---- 
    return(0); 
  }

Schritt 4: Die Nützlichen Funktionen


Bevor wir zum lustigsten Teil kommen, auf den wir warten, die "start()" Funktion, beginnen wir mit den in diesem EA verwendeten Funktionen. Aber bitte beachten Sie, dass alle Funktionen außerhalb der start() Funktion verbeiben


1. Die Korrelationsfunktion

Zuerst müssen wir mit den Korrelationsberechnungs-Funktionen beginnen. Die folgenden Funktionen werden von einem Mann beezogen, der den kostenlosen Korrelation-Indikator (igorad2004@list.ru) zur Verfügung stellt, und ich habe sie zur leichteren Verwendung in unserem EA verändert, wodurch wir den Korrelationswert nicht mehr von einem äußeren Indikator aufrufen müssen. Gute Idee?


//+------------------------------------------------------------------+ 
//|  CORRELATION                                                     |
//+------------------------------------------------------------------+ 
double symboldif(string symbol, int shift) 
  { 
    return(iClose(symbol, 1440, shift) - 
           iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, 
               PRICE_CLOSE, shift)); 
  } 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double powdif(double val) 
  { 
    return(MathPow(val, 2)); 
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+ 
double u(double val1,double val2) 
  { 
    return((val1*val2)); 
  }
//+------------------------------------------------------------------+
//|  The real correlation function to call is here.                  |
//+------------------------------------------------------------------+
double Cor(string base, string hedge) 
  { 
    double u1=0,l1=0,s1=0; 
    for(int i = CorPeriod - 1; i >= 0; i--) 
      { 
        u1 += u(symboldif(base, i), symboldif(hedge, i)); 
        l1 += powdif(symboldif(base, i)); 
        s1 += powdif(symboldif(hedge, i)); 
      } 
    if(l1*s1 > 0) 
        return(u1 / MathSqrt(l1*s1)); 
  } 
//+------------------------------------------------------------------+

Die CorPeriod Variable wird extern als Eingabevariable sein, um uns zu ermöglichen sie anzupassen. Wen Sie die Korrelation zwischen zwei Symbolen berechnen möchten, rufen Sie einfach die Cor(string base,string hedge) Funktion auf wie diese Cor(EURJPY,GBPJPY). Es ist einfach, oder nicht?


2. Die Send Hedge Funktion

Ich denke, es ist einfacher zu handhaben, wie wir die Order durch die Erstellung der SendH Funktion unten, senden können.


//+------------------------------------------------------------------+
//| SEND HEDGE                                                       |
//+------------------------------------------------------------------+
bool SendH(string symbol, int op, double lots,
           double price, int sp, string comment, int magic) 
  { 
    if(OrderSend(symbol 
                 , op 
                 , lots 
                 , price 
                 , sp 
                 , 0 
                 , 0 
                 , comment 
                 , magic 
                 , 0 
                 , CLR_NONE) 
                 > 0) 
      {
        return(true); 
        if(PlayAudio)
            PlaySound("expert.wav"); 
      } 
    else 
      {
        Print(symbol, ": ", magic, " : " 
              , ErrorDescription(GetLastError())); 
        return(false); 
      } 
  } 
//+------------------------------------------------------------------+

Sie können hier mehr über die OrderSend Funktion lesen.

Diese ErrorDescription(GetLastError()) Funktion oben, lässt unseren EA sagen welcher Fehler auftrat, als die Trading-Funktion für uns gearbeitet hat. Um sie zu nutzen, müssen wir die "stdlib.mqh" Datei einfügen, indem wir den Code wie folgt platzieren:


//+------------------------------------------------------------------+ 
//|                                                     MyHedge.mq4  | 
//|                                                         myHedge  | 
//|                                     http://dailyh.blogspot.com/         | 
//+------------------------------------------------------------------+ 
#property copyright "myHedge" 
#property link "http://dailyh.blogspot.com/" 
#include <stdlib.mqh>
//+------------------------------------------------------------------+

Und um sie zu verwenden, rufen Sie einfach die "ErrorDescription() " Funktion auf, wie oben gezeigt.


3. Die Close Hedge Funktion

Über das Senden der Ordern hinaus, benötigen wir auch eine Funktion zum Schließen aller Hedging Ordern, wen sie den erwarteten Profit erreichen. Und so geht es:

//+------------------------------------------------------------------+
//|  CLOSE HEDGE                                                     |
//+------------------------------------------------------------------+
bool CloseHedge(int magic) 
  { 
   for(int i = OrdersTotal() - 1; i >= 0; i--) 
     { 
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && 
                      OrderMagicNumber() == magic) 
         { 
           if(OrderClose(OrderTicket() 
              , OrderLots() 
              , OrderClosePrice() 
              , MarketInfo(OrderSymbol(), MODE_SPREAD) 
              , CLR_NONE))
                SResult = true; 
         } 
     } 
   if(SResult)
     {
       return(true);
       if(PlayAudio)
         {
           PlaySound("ok.wav");
         }
     } 
   else 
       Print("CloseHedge Error: ", ErrorDescription(GetLastError())); 
   RefreshRates(); 
   // return(0); 
  } 
//+------------------------------------------------------------------+
Diese Funktion wird nur Positionen mit der gleichen Magic Number schließen, was bedeutet, dass sie ordern mit einer anderen Magic Number nicht stören wird. Keine Sache, über die man sich echte Sorgen machen müsste. Vor der Verwendung der Funktion müssen wir bestimmen " wie viel wir jetzt haben", mit der folgenden Funktion.
4. Die Feststellen des Gesamtprofit Funktion
//+------------------------------------------------------------------+
//|  TOTAL PROFIT                                                    |
//+------------------------------------------------------------------+ 
double TotalCurProfit(int magic) 
  { 
   double MyCurrentProfit = 0; 
   for(int cnt = 0 ; cnt < OrdersTotal() ; cnt++) 
     { 
       OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); 
       if(OrderMagicNumber() == magic) 
         { 
           MyCurrentProfit += (OrderProfit() + OrderSwap()); 
         } 
     } 
   return(MyCurrentProfit); 
  } 
//+------------------------------------------------------------------+


Wie die Close Funktion, müssen wir, um den Hedge-Profit zu wissen, nur die Ordern mit der selben Magic Number beobachten, um sie korrekt zu schließen. Um sie zu verwenden, schreiben Sie den Code wie folgt:

if(TotalCurProfit(318) > 100) 
    CloseHedge(318);

Alle Profitwerte werden in USD berechnet. In der Zeile oben, wen der Gesamtprofit von Ordern mit der Magic Number 318 größer als $100 ist, werden sie geschlossen. Das ist alles. Um Hedge Ordern zu öffnen, müssen wir wissen, dass keine Ordern mit dem gleichen Symbol und der gleichen Magic Number in dem Moment schwebend sind, in dem wir die Absicherung senden müssen. Dies kann durch diese Funktion bestimmt werden.



5. Anzahl der Existierenden Positionen Erhalten
//+------------------------------------------------------------------+
//| EXISTING POSITIONS                                               |
//+------------------------------------------------------------------+
int ExistPositions(string symbol, int magic) 
  { 
    int NumPos = 0; 
    for(int i = 0; i < OrdersTotal(); i++) 
      { 
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
                       && OrderSymbol() == symbol 
                       && OrderMagicNumber() == magic) 
          {  
            NumPos++; 
          } 
      }
    return(NumPos); 
 
  } 
//+------------------------------------------------------------------+ 

Sie kann wie folgt verwendet werden:


ExistPositions("GBPJPY",318)

Diese Funktion wird uns zurückgeben, "wie viele Eröffnungs-Ordern von GBPJPY mit der Magic Number 318 schwbend sind", in diesem Moment. Eine weitere Funktion um die Art der schwebenden Order festzulegen.


6. Den Order-Typ bestimmter Existierender Positionen feststellen

//+------------------------------------------------------------------+  
//| EXISTING OP POSITION                                             |
//+------------------------------------------------------------------+
int ExistOP(string symbol, int magic) 
  { 
    int NumPos = -1; 
    for(int i = 0; i < OrdersTotal(); i++) 
      { 
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
                       && OrderSymbol() == symbol 
                       && OrderMagicNumber() == magic) 
          {  
            NumPos = OrderType();
          } 
      } 
    return(NumPos); 
  } 
//+------------------------------------------------------------------+

Diese Funktion gibt den Ganzzahlwert der Order-Art zurück, für das bestimmte Symbol und die Magic Number, die im Moment schwebend sind. Wenn die schwebende Order für GBPJPY OP_BUY ist, ist der zurückgegebene Wert &quor;0". Diese Funktion funktioniert nicht nur zusammen mit den Trading-Funktionen. Sie arbeitet auch mit einer Funktion zur Anzeige des aktuellen Absicherungs-Status. Diese Funktion nennt sich "OP2Str".



7. Anzeigen des Trading Status

//+------------------------------------------------------------------+
//| Transform OP Value To string                                     |
//+------------------------------------------------------------------+ 
string OP2Str(int op) 
  { 
    switch(op) 
      { 
        case OP_BUY : return("BUY"); 
        case OP_SELL: return("SELL"); 
        default : return("~~"); 
      } 
  }
//+------------------------------------------------------------------+

Hier gibt es nicht viel zu sagen, ich denke, es zeigt bereits wie es funktioniert.


8. Schließen aller bestimmten Ordertypen

Eine weitere Methode, um jede einzelne Order, im Falle eines Fehlers, direkt zuschließen, wenn die Absicherung gesendet oder geschlossen wird.


//+------------------------------------------------------------------+
//| CLOSE SCRAP                                                      |
//+------------------------------------------------------------------+ 
bool CloseScrap(string sym, int op, int magic) 
  { 
    for(int i = OrdersTotal() - 1; i >= 0; i--) 
      { 
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
           && amp; OrderMagicNumber() == magic 
           && OrderSymbol() == sym 
           && OrderType() == op) 
          { 
            if(OrderClose(OrderTicket() 
               , OrderLots() 
               , OrderClosePrice() 
               , MarketInfo(OrderSymbol(), MODE_SPREAD) 
               , CLR_NONE))
                BResult = true; 
          } 
      } 
    if(BResult)
      {
        return(true);
        if(PlayAudio)
          {
            PlaySound("ok.wav");
          }
      } 
    else 
        Print("CloseScrap Error: ", ErrorDescription(GetLastError())); 
    RefreshRates(); 
    // return(0); 
  }
i.e., CloseScrap("GBPJPY",OP_BUY,318) : dies wird nur schwebende Long "GBPJPY" mit der Magic Number 318 schließen. Es ist einfach. Eine letzte Funktion, die man kennen sollte.

9. Anzeigen jedes Boolean Status den Sie wollen
//+------------------------------------------------------------------+
//| Translate bool to string                                         |
//+------------------------------------------------------------------+
string bool2str( bool boolval) 
  { 
    if(boolval == true) 
        return("Yes"); 
    if(boolval == false)
        return("No"); 
  }
//+------------------------------------------------------------------+


Nichts Besonderes, diese Funktion ist zur Anzeige des Boolean Status einiger Parameter, wie dem BlockOpening Wert. Wenn sie ihn auf true festlegen, wird die Funktion "Yes" auf ihrem Bildschirm zurückgeben. Sie wird "No" zurückgeben, wenn Sie ihn auf false festlegen. Das ist alles über die benötigten Funktionen. Genießen wir nun die Programmierung des Hedging-Vorgangs.


Schritt 5: Der Kern des Expert Advisor

Beginnen Sie hiermit:

//+------------------------------------------------------------------+ 
//| expert start function                                            | 
//+------------------------------------------------------------------+ 
int start() 
  {

Dann bestimmen Sie den Korrelationsbereich.

if(Cor(BaseSymbol, H_Symbol) > Between || 
   Cor(BaseSymbol, H_Symbol) < And) 
// Block opening when the correlation is out of 
// expected range. 
    BlockOpen = true; 
else 
    BlockOpen = false;
Als nächstes legen Sie die Art der Absicherung fest (dies ist nur ein Beispiel), in diesem Artikel werde ich den Trading-Stil mit dem Swap-Wert wählen, und dann werde ich nur auf die Weise traden, auf die ich jeden Tag durch den Swap verdienen kann.

// if they move the same way we will open long & short 
if(MoveSameWay) 
  { 
    if(((BSwapL*BaseLotSize) + (HSwapS*H_LotSize)) > 0) 
      {  
        BOP = OP_BUY; 
        HOP = OP_SELL; 
      } 
    else 
        if(((BSwapS*BaseLotSize) + (HSwapL*H_LotSize)) > 0) 
          { 
            BOP = OP_SELL; 
            HOP = OP_BUY; 
          } 
  } // end MoveSameWay
// if the move the opposite way we will open short & short or long & long
else 
  { 
    if(((BSwapL*BaseLotSize) + (HSwapL*H_LotSize)) > 0) 
      { 
        BOP = OP_BUY; 
        HOP = OP_BUY; 
      } 
    else 
        if(((BSwapS*BaseLotSize) + (HSwapS*H_LotSize)) > 0) 
          { 
            BOP = OP_SELL; 
            HOP = OP_SELL; 
          } 
  }

Nun ist es Zeit die Absicherung zu senden:


// if they meet the correlation range and 
// you're not blocking them
if(!BlockOpen && !BlockOpening)  
  { 
    if(BOP == OP_BUY) 
    // define the opening price    
        BaseOpen = MarketInfo(BaseSymbol, MODE_ASK); 
    else 
        BaseOpen = MarketInfo(BaseSymbol, MODE_BID); 
    if(HOP == OP_BUY)
        HOpen = MarketInfo(H_Symbol, MODE_ASK); 
    else 
        HOpen = MarketInfo(H_Symbol, MODE_BID); 
    // In case there is no any swap condition to gain 
    // from BOP & HOP will be -1.
    if(BOP >= 0 && HOP >= 0) 
      {
        if(ExistPositions(BaseSymbol, MagicNo) == 0 && 
           ExistPositions(H_Symbol, MagicNo) == 0) 
          { 
            SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, 
                  BSP, "COR : " +
                  DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), 
                  MagicNo); 
            SendH(H_Symbol, HOP, H_LotsSize, HOpen, HSP, 
                  "COR : " +
                  DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), 
                  MagicNo); 
          } 
        else // in case ping failed or requote 
          { 
            if(ExistPositions(BaseSymbol, MagicNo) == 1&&
               TotalCurProfit(MagicNo)>AcceptableLoss$) 
              { 
                CloseScrap(BaseSymbol, ExistOP(BaseSymbol, 
                           MagicNo), MagicNo); 
              } 
            else 
                if(ExistPositions(H_Symbol, MagicNo) == 1&&
                   TotalCurProfit(MagicNo) > AcceptableLoss$) 
                  { 
                    CloseScrap(H_Symbol, ExistOP(H_Symbol, 
                               MagicNo), MagicNo); 
                  } 
          } 
 
      }
    else // if one of BOP and HOP is less than 0
      {
        string swaptxt = "No Swap Condition To Gain From :" + 
                   "pls modify one or more input parameter(s).";
      }
  }


Dann schließen Sie diese, wenn sie den erwarteten Profit erreicht haben.


if((TotalCurProfit(MagicNo) > ExpectProfit$)
  {
    CloseHedge(MagicNo);
  }

Und etwas unterhaltsamer: der ShowStatus Teil.

    if(ShowStatus)
      {
        Comment("\nCorrel: " + DoubleToStr(Cor(BaseSymbol
                , H_Symbol), 2)
                , "\nBlockOpen : " + bool2str(BlockOpen 
                || BlockOpening)
                , "\n" + swaptxt
                , "\n~~~~~~~"
                , "\nB/H [sp] : " + BaseSymbol + " [" 
                + BSP + "]" + " / " 
                + H_Symbol+" ["+HSP+"]"
                , "\nCurOp [Lots]: " 
                + OP2Str(ExistOP(BaseSymbol, MagicNo)) 
                + " [" + DoubleToStr(BaseLotSize, 2) + "]"
                + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) 
                + " [" 
                + DoubleToStr(H_LotsRatio*BaseLotSize, 2) + "]"
                , "\nCurPF [Expect]: $" 
                + DoubleToStr(TotalCurProfit(MagicNo), 2) 
                + " [$"+DoubleToStr(ExpectProfit$, 2) + "]");
      }
    else 
        Comment("");

Abschließen mit dem Ende jedes EA.

 return(0);
}


Step 6: Alles Versammelt

Hier können Sie sehen, wie myHedge.mq4 aussieht.


//+------------------------------------------------------------------+
//|                                                      MyHedge.mq4 |
//|                                                          myHedge |
//|                                      http://dailyh.blogspot.com/ |
//+------------------------------------------------------------------+
#property copyright "myHedge"
#property link "http://dailyh.blogspot.com/"
//----
#include <stdlib.mqh>
// this is to block the order sending function but not to block the 
// close function.
extern bool BlockOpening = false;
extern string BaseSymbol = "EURJPY"; // the 1st symbol
extern string H_Symbol = "GBPJPY";   // the 2nd symbol
extern bool MoveSameWay = true; // they move the same way or not
extern int CorPeriod = 5; // your favorite correlation period
extern double BaseLotSize = 1.5; // 1st symbol lotsize
extern double H_LotSize = 1.0; // 2nd symbol lotsize
extern double ExpectProfit$ = 137; // your expect profit in USD
// your acceptable loss in USD in case any error occurred
extern double AcceptableLoss$ = -77; 
extern string ExpectCor = "______"; // your expect correlation to 
// hedge this is the upper expect cor value and has to be greater 
// than "And"
extern double Between = 1.05;
extern double And = 0.9; // this is the lower expect cor level
extern string MISC = "______"; // some thing more
extern int MagicNo = 318; // your favorite magic number
extern bool ShowStatus = true; // to show the present hedging status
// to play sound when SendH and CloseH function done
extern bool PlayAudio = false; 
//----
int BSP  // the spread of base symbol
    ,HSP // the spread of hedge symbol
    ,gsp
    ,BOP = -1 // base symbol order type
    ,HOP = -1 // hedge symbol order type
    ,up = 0
    ,Hcnt = 0
    ,u = 0
    ,d = 0
    ,day = 0
    ,sent = 0
    ,firstopen
    ,expire;
double Lot
       ,BaseOpen // base symbol order open price
       ,HOpen // hedge symbol order open price
       ,BPt // base symbol Point value
       ,HPt // hedge symbol Point value
       ,BSwapL // base symbol swap long value
       ,BSwapS // base symbol swap short value
       ,HSwapL // hedge symbol swap long value
       ,HSwapS; // hedge symbol swap short value
bool SResult = false, BResult = false, H1.profitswap, H2.profitswap, 
     H3.profitswap;
bool SwapMode = true, allmeetcor = false, BlockOpen = false, buy, 
     sell, cleared = false;
string H1.string = "", H2.string = "", H3.string = "", 
       OrdComment = "", candletxt,tdstxt = "";
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   BSP = MarketInfo(BaseSymbol, MODE_SPREAD);
   HSP = MarketInfo(H_Symbol, MODE_SPREAD);
//----
   BPt = MarketInfo(BaseSymbol, MODE_POINT);
   HPt = MarketInfo(H_Symbol, MODE_POINT);
//----
   BSwapL = MarketInfo(BaseSymbol, MODE_SWAPLONG);
   BSwapS = MarketInfo(BaseSymbol, MODE_SWAPSHORT);
//----
   HSwapL = MarketInfo(H_Symbol, MODE_SWAPLONG);
   HSwapS = MarketInfo(H_Symbol, MODE_SWAPSHORT);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   if(Cor(BaseSymbol, H_Symbol) > Between || 
      Cor(BaseSymbol, H_Symbol) < And)
   // Block opening when the correlation is out of expected range.
       BlockOpen = true;
   else 
       BlockOpen = false;
//----
   if(MoveSameWay)
     {
       if((BSwapL*BaseLotSize) + (HSwapS*H_LotSize) > 0)
         {
           BOP = OP_BUY;
           HOP = OP_SELL;
         }
       else 
           if((BSwapS*BaseLotSize) + (HSwapL*H_LotSize) > 0)
             {
               BOP = OP_SELL;
               HOP = OP_BUY;
             }
     }
   else
     {
       if((BSwapL*BaseLotSize) + (HSwapL*H_LotSize) > 0)
         {
           BOP = OP_BUY;
           HOP = OP_BUY;
         }
       else 
           if((BSwapS*BaseLotSize) + (HSwapS*H_LotSize) > 0)
             {
               BOP = OP_SELL;
               HOP = OP_SELL;
             }
     }
   if(!BlockOpen && !BlockOpening)
     {
       if(BOP == OP_BUY) 
           BaseOpen = MarketInfo(BaseSymbol, MODE_ASK);
       else            
           BaseOpen = MarketInfo(BaseSymbol, MODE_BID);
       if(HOP == OP_BUY)
           HOpen = MarketInfo(H_Symbol, MODE_ASK);
       else
           HOpen = MarketInfo(H_Symbol, MODE_BID);
       // In case there is no any swap condition that we can gain from.
       if(BOP >= 0 && HOP >= 0) 
         {
           if(ExistPositions(BaseSymbol, MagicNo) == 0 && 
              ExistPositions(H_Symbol,MagicNo) == 0)
             {
               SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, BSP, 
                     "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 
                     2), MagicNo);
               SendH(H_Symbol, HOP, H_LotSize, HOpen, HSP, "COR : " + 
                     DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo);
             }     
           else // in case ping failed or requote
             {
               if(ExistPositions(BaseSymbol, MagicNo) == 1 && 
                  TotalCurProfit(MagicNo) > AcceptableLoss$)
                 {
                   CloseScrap(BaseSymbol, ExistOP(BaseSymbol, 
                              MagicNo), MagicNo);
                 }
               else 
                   if(ExistPositions(H_Symbol, MagicNo) == 1 && 
                      TotalCurProfit(MagicNo) > AcceptableLoss$)
                     {
                       CloseScrap(H_Symbol, ExistOP(H_Symbol, 
                                  MagicNo), MagicNo);
                     }
             }
         }
       else
         {
           string swaptxt = "No Swap Condition To Gain From : pls " + 
                            "modify one or more input parameter(s).";
         }
     }
   if(TotalCurProfit(MagicNo) > ExpectProfit$)
     {
       CloseHedge(MagicNo);
     }
   if(ShowStatus)
     {
       Comment("\nCorrel: "+DoubleToStr(Cor(BaseSymbol, H_Symbol), 2)
               , "\nBlockOpen : " + bool2str(BlockOpen || BlockOpening)
               , "\n" + swaptxt
               , "\n~~~~~~~"
               , "\nB/H [sp] : " + BaseSymbol + " [" + BSP + "]" + 
                 " / " + H_Symbol + " [" + HSP + "]"
               , "\nCurOp [Lots]: " + OP2Str(ExistOP(BaseSymbol, 
                 MagicNo)) + " [" + DoubleToStr(BaseLotSize, 2) + "]"
                 + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) + " [" + 
                 DoubleToStr(H_LotSize, 2) + "]"
               , "\nCurPF [Expect]: $" + 
                 DoubleToStr(TotalCurProfit(MagicNo), 2) + " [$" + 
                 DoubleToStr(ExpectProfit$, 2) + "]");
     }
   else 
       Comment("");
   return(0);
  }
//+------------------------------------------------------------------+
//| CORRELATION                                                      |
//+------------------------------------------------------------------+
double symboldif(string symbol, int shift)
  {
   return(iClose(symbol, 1440, shift) - 
          iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, PRICE_CLOSE, shift));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double powdif(double val)
  {
   return(MathPow(val, 2));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double u(double val1, double val2)
  {
   return((val1*val2));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Cor(string base, string hedge)
  {  
   double u1 = 0, l1 = 0, s1 = 0;
   for(int i = CorPeriod - 1; i >= 0; i--)
     {
       u1 += u(symboldif(base, i), symboldif(hedge, i));
       l1 += powdif(symboldif(base, i));
       s1 += powdif(symboldif(hedge, i));
     }
   if(l1*s1 > 0) 
       return(u1 / MathSqrt(l1*s1));
  }
//+------------------------------------------------------------------+
//| SEND HEDGE                                                       |
//+------------------------------------------------------------------+
bool SendH(string symbol, int op, double lots, double price, int sp, 
           string comment, int magic)
  {
   if(OrderSend(symbol
                ,op
                ,lots
                ,price
                ,sp
                ,0
                ,0
                ,comment
                ,magic
                ,0
                ,CLR_NONE)
                >0)
     {
       return(true);
       if(PlayAudio)
           PlaySound("expert.wav");
     }
   else 
     {
       Print(symbol, ": ", magic, " : "
             ,ErrorDescription(GetLastError()));
       return(false);      
     }      
  }
//+------------------------------------------------------------------+
//| CLOSE HEDGE                                                      |
//+------------------------------------------------------------------+
bool CloseHedge(int magic)
  {  
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {         
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && 
                      OrderMagicNumber() == magic)
         {
           if(OrderClose(OrderTicket()
                         , OrderLots()
                         , OrderClosePrice()
                         , MarketInfo(OrderSymbol(), MODE_SPREAD)
                         , CLR_NONE))
               SResult = true;
         }
     }
   if(SResult)
     {
       return(true);
       if(PlayAudio)
         {
           PlaySound("ok.wav");
         }
     }
   else 
       Print("CloseHedge Error: ", ErrorDescription(GetLastError()));
   RefreshRates();
//  return(0);
  }  
//+------------------------------------------------------------------+
//| TOTAL PROFIT                                                     |
//+------------------------------------------------------------------+
double TotalCurProfit(int magic)
  {   
   double MyCurrentProfit = 0;
   for(int cnt = 0; cnt < OrdersTotal(); cnt++)
     {
       OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
       if(OrderMagicNumber() == magic)
         {
           MyCurrentProfit += (OrderProfit() + OrderSwap());
         }   
     }
   return(MyCurrentProfit);
  }
//+------------------------------------------------------------------+
//| EXISTING POSITION                                                |
//+------------------------------------------------------------------+
int ExistPositions(string symbol,int magic) 
  {
   int NumPos = 0;
   for(int i = 0; i < OrdersTotal(); i++) 
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == symbol
          && OrderMagicNumber() == magic)
         { 
           NumPos++;
         }
     }
   return(NumPos);
  }
//+------------------------------------------------------------------+
//| EXISTING OP POSITION                                             |
//+------------------------------------------------------------------+
int ExistOP(string symbol,int magic) 
  {
   int NumPos = -1;
   for(int i = 0; i < OrdersTotal(); i++) 
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == symbol
          && OrderMagicNumber() == magic)
         { 
           NumPos = OrderType();
         }
     }
   return(NumPos);
  }
//+------------------------------------------------------------------+
//| Transform OP Value To string                                     |
//+------------------------------------------------------------------+
string OP2Str(int op)
  {
   switch(op)
     {
       case OP_BUY : return("BUY");
       case OP_SELL: return("SELL");
       default     : return("~~");
     }
  }
//+------------------------------------------------------------------+
//| CLOSE SCRAP                                                      |
//+------------------------------------------------------------------+
bool CloseScrap(string sym,int op,int magic)
  {  
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {         
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) 
          && OrderMagicNumber() == magic
          && OrderSymbol() == sym
          && OrderType() == op)
         {
           if(OrderClose(OrderTicket()
                         , OrderLots()
                         , OrderClosePrice()
                         , MarketInfo(OrderSymbol(), MODE_SPREAD)
                         , CLR_NONE))
               BResult = true;
         }
     }
   if(SResult || BResult)
     {
       return(true);
       if(PlayAudio)
         {
           PlaySound("ok.wav");
         }
     }
   else 
       Print("CloseScrap Error: ", ErrorDescription(GetLastError()));
   RefreshRates();
//  return(0);
  }  
//+------------------------------------------------------------------+
//| Translate bool to string                                         |
//+------------------------------------------------------------------+
string bool2str(bool boolval)
  {
   if(boolval == true) 
       return("Yes");
   if(boolval == false)
       return("No");
  }
//+------------------------------------------------------------------+

Fazit

Dies ist nur ein Beispiel eines einfachen Hedge Expert Advisor. Sie müssen ihn modifizieren, um ihn an Ihren Absicherungsstil anzupassen. Ich bin sicher, dass es da draußen viel Absicherungsstile gibt. Und bitte beachten Sie, dass diese Art von EA nicht mit dem Strategie-Tester getestet werden kann, durch seine eigenen Beschränkungen. Sie müssen ihn live testen. Unten ist das Beispielergebnis eines Hedge-EA.


Und die ShowStatus Funktion wird wie folgt sein:


Ich hoffe Sie genießen meinen Artikel und hoffe sehr, dass er Ihnen hilft Ihren eigenen Hedge-EA zu erstellen.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/1479

Beigefügte Dateien |
myHedge.mq4 (13.75 KB)
Handelssignal über RSS Feed senden Handelssignal über RSS Feed senden
This is my idea how to send your trade signaDies ist meine Idee Ihr Handelssignal als RSS Feed zu senden, ein erstklassiger Weg, um mit Ihren Community-Mitgliedern sofort zu kommunizieren.l as RSS FEEDS , a famous way to communicate with your community's members right now.
Kann der Forex Markt Vorhergesagt werden? Wie Erstellt man seine Eigene Forex Strategie? Kann der Forex Markt Vorhergesagt werden? Wie Erstellt man seine Eigene Forex Strategie?
Jeder, der anfängt in Forex zu arbeiten, versucht diese Frage zu beantworten. Aber nicht jeder findet die Antwort, aich nach vielen Jahren harter Arbeit und Suche. Ich persönlich habe diese Frage beantwortet, sowie viele andere Fragen in diesem Artikel. Als Ergebnis dieser Anworten wurde ein Weg zur Schaffung einer effizienten Handelsstrategie bestimmt.
Praktische Verwendung eines Virtual Private Server (VPS) für Autotrading Praktische Verwendung eines Virtual Private Server (VPS) für Autotrading
Autotrading mit VPS. Dieser Artikel ist besonders für Autotrader und Autotrading-Unterstützer gedacht.
Automatisierte Auswahl des Broker Unternehmen für einen Eiffizienten Betrieb von Expert Advisors Automatisierte Auswahl des Broker Unternehmen für einen Eiffizienten Betrieb von Expert Advisors
Es ist kein Geheimnis, dass wir für einen effizienten Betrieb von Expert Advisors ein geeignetes Broker-Unternehmen finden müssen. Dieser Artikel beschreibt einen Systemansatz für diese Suche. Sie werden sich mit dem Vorgang der Erstellung eines Programms mit dll für die Arbeit mit verschiedenen Terminals vertraut machen.