
Wie man einen einfachen EA für mehrere Währungen mit MQL5 erstellt (Teil 2): Indikator-Signale: Multi-Zeitrahmen Parabolic SAR Indikator
Einführung
Die Definition eines Mehr-Währungs-EA in diesem Artikel ist ein Expert Advisor oder Handelsroboter, der mehr als 1 Symbolpaar von nur einem Symbolchart aus handeln kann (z.B. Aufträge eröffnen, schließen und verwalten, Trailing Stop Loss und Trailing Profit), wobei in diesem Artikel der Expert Advisor 30 Paare handeln wird. Dieses Mal werden wir nur 1 Indikator verwenden, nämlich Parabolic SAR oder iSAR in mehreren Zeitrahmen von PERIOD_M15 bis PERIOD_D1
Wir alle wissen, dass der Handel mit mehreren Währungen, sowohl auf dem Handelsterminal als auch auf dem Strategietester, mit der Leistung, den Fähigkeiten und den Möglichkeiten von MQL5 möglich ist.
Daher ist das Ziel, die wesentlichen Bedürfnisse der Händler, die effiziente und effektive Handelsroboter wollen zu erfüllen, sodass durch den Rückgriff auf die Stärken, Fähigkeiten und Einrichtungen, die von der sehr zuverlässigen MQL5, können wir eine einfache Mehr-Währungs-EA, die in diesem Artikel verwendet Indicator Signals erstellen: Multi-Zeitrahmen Parabolic SAR oder iSAR Indikator.
Pläne und Eigenschaften
1. Handel mit Währungspaaren.
Dieser Mehr-Währungs-EA ist für den Handel mit einem der folgenden Symbole oder Paare vorgesehen:
Für Forex:
EURUSD,GBPUSD,AUDUSD,NZDUSD,USDCAD,USDCHF,USDJPY,EURGBP,
EURAUD, EURNZD, EURCAD, EURCHF, EURJPY, GBPAUD, GBPNZD, GBPCAD,
GBPCHF,GBPJPY,AUDNZD,AUDCAD,AUDCHF,AUDJPY,NZDCAD,NZDCHF,
NZDJPY, CADCHF, CADJPY, CHFJPY = 28 Paare
Plus 2 Metallpaare: XAUUSD (Gold) und XAGUSD (Silber)
Insgesamt sind es 30 Paare.
Anmerkung: Alle diese Symbole oder Paare sind Symbole oder Paare, die üblicherweise von Brokern verwendet werden. Daher funktioniert dieser Mehr-Währungs-EAs nicht mit Brokern, deren Symbol- oder Paarnamen Präfixe oder Suffixe enthalten.
2. Indikatoren.
Der Mehr-Währungs-EA verwendet 1 Indikatorsignal, aber mit 5 Zeitrahmen, und zwar PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4 und PERIOD_D1.
In diesem Expert Advisor wird kein fester Zeitrahmen für die Berechnung der Indikatorsignale verwendet, sodass es nicht notwendig ist, den Zeitrahmen für die Signalberechnung zu bestimmen.
Das bedeutet, dass der FXSAR_MTF_MCEA Expert Advisor auf jedem Zeitrahmen von PERIOD_M1 bis PERIOD_MN1 eingesetzt werden kann und FXSAR_MTF_MCEA weiterhin Signale auf Basis von iSAR PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4 und PERIOD_D1 berechnet.
Diese fünf Zeitrahmen des Parabolic SAR bestimmen das Signal für das Eröffnen von Aufträge.
Um Aufträge zu schließen, wenn das Signal schwächer wird, verwenden Sie den iSAR-Indikator PERIOD_M15, vorausgesetzt, der Auftrag befindet sich in der Gewinnphase.
Und für Trailing-Stop und Trailing-Profit verwenden wir den iSAR-Indikator PERIOD_H1.
Die Formel und die Bedingung der Strategie für die iSAR Signale:
UP = (PRICE_LOW[0] ist größer als iSAR Line) oder PRICE_LOW[0] > iSAR[0]
DOWN = (PRICE-HIGH[0] ist kleiner als iSAR Line) oder PRICE-HIGH[0] < iSAR[0]
Wo wir ein KAUF- oder VERKAUFS-Signal erhalten:
Die fünf Zeitrahmen des iSAR-Indikators müssen insgesamt 5 x UP für BUY und 5 x DOWN für SELL betragen.
Eine Illustration des iSAR-Indikators von BUY und SELL ist in Abbildung 1 zu sehen.
3. Handels- & Auftragsmanagement
Das Handelsmanagement dieses Mehr-Währungs-EAs verfügt über mehrere Optionen:
1. Stop-Loss-Aufträge.
- Optionen: Use Order Stop Loss (Yes) or (No) (Stop-Loss-Auftrag verwenden, Ja oder Nein)
Wenn die Option (No) für Use Stop-Loss für Aufträge verwenden ausgewählt ist, werden alle Aufträge ohne Stop-Loss eröffnet.
Bei der Option Use Order Stop Loss (Yes), gibt es eine weitere Option: Use Automatic Calculation Stop Loss (Yes) or (No) (Autom. Berechnung des Stop Loss verwenden, Ja oder Nein)
Wenn die Option Automatische Berechnung Stop Loss (Ja), dann wird die Stop-Loss-Berechnung automatisch durch den Experten durchgeführt.
Wenn die Option Automatische Berechnung des Stop Loss (Nein) gewählt wurde, muss der Händler den Stop-Loss-Wert in Pips eingeben.
Wenn die Option Use Order Stop Loss (No) gewählt wurde, dann wird der Experte für jede geöffnete Order prüfen, ob die Signalbedingung noch gut ist und die Order
mit Gewinn aufrechterhalten werden kann ODER ob die Signalbedingung sich abgeschwächt hat und die Order geschlossen werden muss, um den Gewinn zu sichern
oder ob die Signalbedingung die Richtung umgekehrt hat und die Order mit Verlust geschlossen werden muss.
2. Take-Profit-Aufträge.
- Optionen: Take-Profit verwenden, Ja (Yes) oder Nein No)
Wenn die Option Use Order Take Profit (No) ausgewählt ist, werden alle Aufträge ohne Take Profit eröffnet.
Bei der Option Use Order Take Profit (Yes) gibt es die weitere Option: Take-Profit automatisch berechnen, Ja (Yes) oder Nein (No).
Wenn die Option Automatische Berechnung Order Take Profit (Ja), dann wird die Berechnung der Take Profit Order automatisch vom Experten durchgeführt.
Wenn die Option Automatic Calculation Order Take Profit (No), gewählt wurde, muss der Händler den Order-Take-Profit-Wert in Pips eingeben.
3. Trailing Stop und Trailing Take-Profit
- Optionen: Use Trailing SL/TP (Yes) or (No) (Nachlaufende SL/TP verwenden, Ja oder Nein)
Wenn die Option Use Trailing SL/TP (No) gewählt wurde, wird der Experte keinen Trailing-Stop-Loss und keinen Trailing-Take-Profit durchführen. Wenn die Option Nachlaufende SL/TP verwendet wird (Ja), gibt es wieder die Option: Use Automatic Trailing (Yes) or (No) (Autom. Nachlauf verwenden, Ja oder Nein). Wenn Sie die Option Use Automatic Trailing (Yes) wählen, wird der Trailing-Stop vom Experten unter Verwendung des Parabolic SAR-Wertes PERIOD_H1 ausgeführt, wobei gleichzeitig ein Trailing-Profit auf Basis des variablen Wertes TPmin (Trailing Profit Value) gemacht wird. Bei der Option Use Automatic Trailing (No) wird der Trailing-Stop vom Experten anhand des Wertes in der Eingabeeigenschaft ausgeführt.
Anmerkung: Der Experte führt einen Trailing-Take-Profit gleichzeitig mit einem Trailing-Stop aus.
4. Manuelle Auftragsverwaltung.
Um die Effizienz in diesem Mehr-Währungs-EA zu unterstützen, werden mehrere manuelle Klick-Buttons hinzugefügt.
1. Set SL / TP All Orders (Setzen von SL / TP bei allen Aufträgen)
Wenn der Händler-Eingabeparameter Use Order Stop Loss (No) und/oder Use Order Take Profit (No) einstellt,
Wenn der Händler jedoch beabsichtigt, Stop-Loss oder Take-Profit für alle Aufträge zu verwenden, dann werden mit einem einzigen Klick auf die Schaltfläche „Set SL / TP All Orders“ (SL / TP für alle Aufträge setzen) alle Aufträge geändert und ein Stop-Loss und/oder Take-Profit angewendet.
2. Close All Orders (Alle Aufträge schließen)
Wenn ein Händler alle Aufträge schließen möchte, dann werden mit einem einzigen Klick auf die Schaltfläche „Close All Orders“ alle offenen Aufträge geschlossen.
3. Close All Orders Profit (Alle Aufträge im Gewinn schließen)
Wenn ein Händler alle Positionen, die bereits profitabel sind, mit einem einzigen Klick auf die Schaltfläche „Close All Orders Profit“ schließen möchte, dann
dann werden alle offenen Aufträge, die bereits rentabel sind, geschlossen.
5. Verwaltung von Aufträgen und Symbolen.
Für Mehr-Währungs-EAs, die 30 Paare mit nur einem Chart-Symbol handeln, ist es sehr effektiv und effizient, wenn eine Schalttafel für alle Symbole vorhanden ist, sodass Händler Charts oder Symbole mit nur einem Klick wechseln können.
Umsetzung der Planung im Programm MQL5
1. Eingabe des Programmkopf und der Eigenschaften.
Header-Datei MQL5 einbinden
//+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\AccountInfo.mqh> //-- CTrade mc_trade; CSymbolInfo mc_symbol; CPositionInfo mc_position; CAccountInfo mc_account; //---
Die Enumeration YN wird für die Optionen (Ja) oder (Nein) in den Experteneingabeeigenschaften verwendet.
enum YN
{
No,
Yes
};
Die Enumeration zur Bestimmung der Losgröße
//-- enum mmt { FixedLot, // Fixed Lot Size DynamLot // Dynamic Lot Size }; //--
Eigenschaften der Eingabe des Experten:
//--- input group "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter input mmt mmlot = DynamLot; // Money Management Type input double Risk = 10.0; // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%) input double Lots = 0.01; // Input Manual Lot Size FixedLot //--Day Trading On/Off input group "=== Day Trading On/Off ==="; // Day Trading On/Off input YN ttd0 = No; // Select Trading on Sunday (Yes) or (No) input YN ttd1 = Yes; // Select Trading on Monday (Yes) or (No) input YN ttd2 = Yes; // Select Trading on Tuesday (Yes) or (No) input YN ttd3 = Yes; // Select Trading on Wednesday (Yes) or (No) input YN ttd4 = Yes; // Select Trading on Thursday (Yes) or (No) input YN ttd5 = Yes; // Select Trading on Friday (Yes) or (No) input YN ttd6 = No; // Select Trading on Saturday (Yes) or (No) //--Trade & Order management Parameter input group "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter input YN use_sl = No; // Use Order Stop Loss (Yes) or (No) input YN autosl = Yes; // Use Automatic Calculation Stop Loss (Yes) or (No) input double SLval = 30; // If Not Use Automatic SL - Input SL value in Pips input YN use_tp = Yes; // Use Order Take Profit (Yes) or (No) input YN autotp = Yes; // Use Automatic Calculation Take Profit (Yes) or (No) input double TPval = 10; // If Not Use Automatic TP - Input TP value in Pips input YN TrailingSLTP = Yes; // Use Trailing SL/TP (Yes) or (No) input YN autotrl = Yes; // Use Automatic Trailing (Yes) or (No) input double TSval = 5; // If Not Use Automatic Trailing Input Trailing value in Pips input double TSmin = 5; // Minimum Pips to start Trailing Stop input double TPmin = 25; // Input Trailing Profit Value in Pips input YN Close_by_Opps = Yes; // Close Trade By Opposite Signal (Yes) or (No) input YN SaveOnRev = Yes; // Close Trade and Save profit due to weak signal (Yes) or (No) //--Others Expert Advisor Parameter input group "=== Others Expert Advisor Parameter ==="; // Others EA Parameter input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No) input YN UseEmailAlert = No; // Email Alert (Yes) or (No) input YN UseSendnotify = No; // Send Notification (Yes) or (No) input YN trade_info_display = Yes; // Select Display Trading Info on Chart (Yes) or (No) input ulong magicEA = 2023102; // Expert ID (Magic Number) //---
Um alle Variablen, Objekte und Funktionen zu deklarieren, die in diesem Mehr-Währungs-EA benötigt werden, werden wir eine Klasse erstellen, um den Aufbau und die Konfiguration im Expert Advisor Workflow zu spezifizieren.
//+------------------------------------------------------------------+ //| Class for working Expert Advisor | //+------------------------------------------------------------------+ class MCEA { //--- private: //---- int x_year; // Year int x_mon; // Month int x_day; // Day of the month int x_hour; // Hour in a day int x_min; // Minutes int x_sec; // Seconds //-- int oBm, oSm, ldig; int posCur1, posCur2; //-- double LotPS; double slv, tpv, pip, xpip; double differ; double floatprofit, fixclprofit; //-- string pairs, hariini, daytrade, trade_mode; //-- double OPEN[], HIGH[], LOW[], CLOSE[]; datetime TIME[]; datetime closetime; //------------ int DirectionMove(const string symbol); int GetPSARSignalMTF(string symbol); int PARSAR05(const string symbol); int PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf); int LotDig(const string symbol); //-- double MLots(const string symbx); double NonZeroDiv(double val1,double val2); double OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type); //-- string ReqDate(int d,int h,int m); string TF2Str(ENUM_TIMEFRAMES period); string timehr(int hr,int mn); string TradingDay(void); string AccountMode(); string GetCommentForOrder(void) { return(expname); } //------------ public: //-- FXSAR_MTF_MCEA Config -- string DIRI[], AS30[]; string expname; int hPar05[]; // Handle for the iSAR indicator for M5 Timeframe int hPSAR[][5]; // Handle Indicator, where each Symbol has 5 arrays for Timeframe starting from TF_M15 to TF_D1 int ALO, dgts, arrsar, arrsymbx; int sall, arper; ulong slip; //-- double SARstep, SARmaxi; double profitb[], profits[]; //-- int Buy, Sell; int ccur, psec, xtto, TFArrays, checktml; int OpOr[],xob[],xos[]; //-- int year, // Year mon, // Month day, // Day hour, // Hour min, // Minutes sec, // Seconds dow, // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) doy; // Day number of the year (January 1st is assigned the number value of zero) //-- ENUM_TIMEFRAMES TFt, TFT05, TFSAR[]; //-- bool PanelExtra; //------------ MCEA(void); ~MCEA(void); //------------ virtual void FXSAR_MTF_MCEA_Config(void); virtual void ExpertActionTrade(void); //-- void ArraySymbolResize(void); void CurrentSymbolSet(const string symbol); void Pips(const string symbol); void TradeInfo(void); void Do_Alerts(const string symbx,string msgText); void CheckOpenPMx(const string symbx); void SetSLTPOrders(void); void CloseBuyPositions(const string symbol); void CloseSellPositions(const string symbol); void CloseAllOrders(void); void CheckClose(const string symbx); void TodayOrders(void); void UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf); void RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars); //-- bool RefreshTick(const string symbx); bool TradingToday(void); bool OpenBuy(const string symbol); bool OpenSell(const string symbol); bool ModifyOrderSLTP(double mStop,double ordtp); bool ModifySLTP(const string symbx,int TS_type); bool CloseAllProfit(void); bool ManualCloseAllProfit(void); //-- int PairsIdxArray(const string symbol); int TFIndexArray(ENUM_TIMEFRAMES TF); int GetOpenPosition(const string symbol); int GetCloseInWeakSignal(const string symbol,int exis); int ThisTime(const int reqmode); //-- string getUninitReasonText(int reasonCode); //------------ //--- }; //-end class MCEA
Die allererste und wichtigste Funktion im Arbeitsprozess des Mehr-Währungs-EAs, die von OnInit() aufgerufen wird, ist FXSAR_MTF_MCEA_Config().
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { //--- mc.FXSAR_MTF_MCEA_Config(); //-- return(INIT_SUCCEEDED); //--- } //-end OnInit()
In der Funktion FXSAR_MTF_MCEA_Config() werden alle zu verwendenden Symbole, alle verwendeten Handle-Indikatoren und einige wichtige Funktionen des Include-Dateikopfes für den Expert Advisor Workflow konfiguriert.
//+------------------------------------------------------------------+ //| Expert Configuration | //+------------------------------------------------------------------+ void MCEA::FXSAR_MTF_MCEA_Config(void) { //--- //-- string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP", "EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD", "GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF", "NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs //-- sall=ArraySize(All30); ArrayResize(AS30,sall,sall); ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY); //-- arrsymbx=sall; ArraySymbolResize(); ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY); for(int x=0; x<arrsymbx; x++) {SymbolSelect(DIRI[x],true);} pairs="Multi Currency 30 Pairs"; //-- TFT05=PERIOD_M5; ENUM_TIMEFRAMES TFA[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1}; TFArrays=ArraySize(TFA); ArrayResize(TFSAR,TFArrays,TFArrays); ArrayCopy(TFSAR,TFA,0,0,WHOLE_ARRAY); //-- TFt=TFSAR[2]; //-- //-- iSAR Indicators handle for all symbol for(int x=0; x<arrsymbx; x++) { hPar05[x]=iSAR(DIRI[x],TFT05,SARstep,SARmaxi); //-- Handle for the iSAR indicator for M5 Timeframe //-- for(int i=0; i<TFArrays; i++) { hPSAR[x][i]=iSAR(DIRI[x],TFSAR[i],SARstep,SARmaxi); // Handle for iSAR Indicator array sequence of the requested timeframe } } //-- ALO=(int)mc_account.LimitOrders()>arrsymbx ? arrsymbx : (int)mc_account.LimitOrders(); //-- LotPS=(double)ALO; //-- mc_trade.SetExpertMagicNumber(magicEA); mc_trade.SetDeviationInPoints(slip); mc_trade.SetMarginMode(); //-- return; //--- } //-end FXSAR_MTF_MCEA_Config()
2. Experten-Tick-Funktion
Innerhalb der Funktion OnTick() des EAs werden wir eine der Hauptfunktionen in einem Mehr-Währungs-EA aufrufen, nämlich die Funktion ExpertActionTrade().
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(void) { //--- mc.ExpertActionTrade(); //-- return; //--- } //-end OnTick()
Die Funktion ExpertActionTrade() führt alle Aktivitäten aus und verwaltet den automatischen Handel, angefangen bei Eröffnen und Schließen der Positionen, den Trailing Stops oder Trailing Profits und anderen zusätzlichen Aktivitäten.
Der Ablauf des Arbeitsprozesses ist wie folgt, wie ich am Rande des Programms erklärt habe.
void MCEA::ExpertActionTrade(void) { //--- //Check Trading Terminal ResetLastError(); //-- if(!MQLInfoInteger(MQL_TRADE_ALLOWED) && mc.checktml==0) //-- Check whether MT5 Algorithmic trading is Allow or Prohibit { mc.Do_Alerts(Symbol(),"Trading Expert at "+Symbol()+" are NOT Allowed by Setting."); mc.checktml=1; //-- Variable checktml is given a value of 1, so that the alert is only done once. return; } //-- if(!DisplayManualButton("M","C","R")) DisplayManualButton(); //-- Show the expert manual button panel //-- if(trade_info_display==Yes) mc.TradeInfo(); //-- Displayed Trading Info on Chart //--- //-- int mcsec=mc.ThisTime(mc.sec); //-- if(fmod((double)mcsec,5.0)==0) mc.ccur=mcsec; //-- if(mc.ccur!=mc.psec) { string symbol; //-- Here we start with the rotation of the name of all symbol or pairs to be traded for(int x=0; x<mc.arrsymbx && !IsStopped(); x++) { //-- if(mc.DIRI[x]==Symbol()) symbol=Symbol(); else symbol=mc.DIRI[x]; //-- mc.CurrentSymbolSet(symbol); //-- if(mc.TradingToday()) { //-- mc.OpOr[x]=mc.GetOpenPosition(symbol); //-- Get trading signals to open positions //-- //-- and store in the variable OpOr[x] if(mc.OpOr[x]==mc.Buy) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Buy" (value=1) { //-- mc.CheckOpenPMx(symbol); //-- if(Close_by_Opps==Yes && mc.xos[x]>0) mc.CloseSellPositions(symbol); //-- if(mc.xob[x]==0 && mc.xtto<mc.ALO) mc.OpenBuy(symbol); else if(mc.xtto>=mc.ALO) { //-- mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); //-- mc.CheckOpenPMx(symbol); //-- if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0) {mc.CloseSellPositions(symbol); mc.OpenBuy(symbol);} else if(SaveOnRev==Yes) mc.CloseAllProfit(); } } if(mc.OpOr[x]==mc.Sell) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Sell" (value=-1) { //-- mc.CheckOpenPMx(symbol); //-- if(Close_by_Opps==Yes && mc.xob[x]>0) mc.CloseBuyPositions(symbol); //-- if(mc.xos[x]==0 && mc.xtto<mc.ALO) mc.OpenSell(symbol); else if(mc.xtto>=mc.ALO) { //-- mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); //-- mc.CheckOpenPMx(symbol); //-- if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0) {mc.CloseBuyPositions(symbol); mc.OpenSell(symbol);} else if(SaveOnRev==Yes) mc.CloseAllProfit(); } } } //-- mc.CheckOpenPMx(symbol); //-- if(mc.xtto>0) { //-- if(SaveOnRev==Yes) //-- Close Trade and Save profit due to weak signal (Yes) { mc.CheckOpenPMx(symbol); if(mc.profitb[x]>0.02 && mc.xob[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) { mc.CloseBuyPositions(symbol); mc.Do_Alerts(symbol,"Close BUY order "+symbol+" to save profit due to weak signal."); } if(mc.profits[x]>0.02 && mc.xos[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Sell)==mc.Buy) { mc.CloseSellPositions(symbol); mc.Do_Alerts(symbol,"Close SELL order "+symbol+" to save profit due to weak signal."); } } //-- if(TrailingSLTP==Yes) //-- Use Trailing SL/TP (Yes) { if(autotrl==Yes) mc.ModifySLTP(symbol,1); //-- If Use Automatic Trailing (Yes) if(autotrl==No) mc.ModifySLTP(symbol,0); //-- Use Automatic Trailing (No) } } //-- mc.CheckClose(symbol); } //-- mc.psec=mc.ccur; } //-- return; //--- } //-end ExpertActionTrade()
3. Wie erhalten wir die Handelssignale für das Öffnen oder Schließen von Positionen?
Um das Indikatorsignal zu erhalten, müssen wir die Funktion GetOpenPosition(Symbol) aufrufen, um ein Handelssignal für eine offene Position zu erhalten.
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position { //--- int ret=0; int rise=1, down=-1; //-- int dirmov=DirectionMove(symbol); int parsOp=GetPSARSignalMTF(symbol); //-- if(parsOp==rise && dirmov==rise) ret=rise; if(parsOp==down && dirmov==down) ret=down; //-- return(ret); //--- } //-end GetOpenPosition()
Die Funktion GetOpenPosition() ruft 2 Signalfunktionen auf und speichert sie in der Variablen OpOr[].
1. DirectionMove(symbol); //-- Die Funktion prüft, ob sich der Preis auf dem Candlestick-Balken im Expertenzeitraum bewegt.
2. GetPSARSignalMTF(symbol); //-- Funktion zur Berechnung der Parabolic iSAR Formel für den angeforderten Zeitrahmen.
int MCEA::GetPSARSignalMTF(string symbol) // iSAR MTF signal calculation { //--- int mv=0; int rise=1, down=-1; //-- int sarup=0, sardw=0; //-- for(int x=0; x<TFArrays; x++) // The TFArrays variable has a value of 5 which is taken from the number of time frames from TF_M1 to TF_H1. { if(PARSARMTF(symbol,TFSAR[x])>0) sarup++; if(PARSARMTF(symbol,TFSAR[x])<0) sardw++; } //-- if(sarup==TFArrays) mv=rise; if(sardw==TFArrays) mv=down; //-- return(mv); //--- } //- end GetPSARSignalMTF()
Die Funktion GetPSARSignalMTF() ruft eine Funktion PARSARMTF() auf, die das iSAR-Signal entsprechend dem gewünschten Zeitrahmen berechnet.
Wie Sie sehen können, werden innerhalb der Funktion PARSARMTF() 2 Funktionen verwendet und aufgerufen:
1. int xx= PairsIdxArray(Symbol)
2. int tx=TFIndexArray(mtf).
Die Funktion PairsIdxArray() wird verwendet, um den Namen des angeforderten Symbols zu erhalten, und die Funktion TFIndexArray() wird verwendet, um die Zeitrahmen-Array-Sequenz des angeforderten Zeitrahmens zu erhalten.
Dann wird das entsprechende Indikator-Handle aufgerufen, um den Pufferwert des iSAR-Indikators für den angeforderten Zeitrahmen zu erhalten.
int MCEA::PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf) // formula Parabolic iSAR on the requested Timeframe { //--- int ret=0; int rise=1, down=-1; //-- int br=2; //-- double PSAR[]; ArrayResize(PSAR,br,br); ArraySetAsSeries(PSAR,true); int xx=PairsIdxArray(symbol); int tx=TFIndexArray(mtf); CopyBuffer(hPSAR[xx][tx],0,0,br,PSAR); //-- double OPN0=iOpen(symbol,TFSAR[tx],0); double HIG0=iHigh(symbol,TFSAR[tx],0); double LOW0=iLow(symbol,TFSAR[tx],0); double CLS0=iClose(symbol,TFSAR[tx],0); //-- if(PSAR[0]<LOW0 && CLS0>OPN0) ret=rise; if(PSAR[0]>HIG0 && CLS0<OPN0) ret=down; //-- return(ret); //--- } //-end PARSARMTF()
int MCEA::PairsIdxArray(const string symbol) { //--- int pidx=0; //-- for(int x=0; x<arrsymbx; x++) { if(DIRI[x]==symbol) { pidx=x; break; } } //-- return(pidx); //--- } //-end PairsIdxArray()
int MCEA::TFIndexArray(ENUM_TIMEFRAMES TF) { //--- int res=-1; //-- for(int x=0; x<TFArrays; x++) { if(TF==TFSAR[x]) { res=x; break; } } //-- return(res); //--- } //-end TFIndexArray()
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- //--- handling CHARTEVENT_CLICK event ("Clicking the chart") ResetLastError(); //-- ENUM_TIMEFRAMES CCS=mc.TFt; //-- if(id==CHARTEVENT_OBJECT_CLICK) { int lensymbol=StringLen(Symbol()); int lensparam=StringLen(sparam); //-- //--- if "Set SL All Orders" button is click if(sparam=="Set SL/TP All Orders") { mc.SetSLTPOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Set SL/TP All Orders"); //--- unpress the button ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_STATE,false); ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Order" button is click if(sparam=="Close All Order") { mc.CloseAllOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Orders"); //--- unpress the button ObjectSetInteger(0,"Close All Order",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Order",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Profit" button is click if(sparam=="Close All Profit") { mc.ManualCloseAllProfit(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Profit"); //--- unpress the button ObjectSetInteger(0,"Close All Profit",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Profit",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "X" button is click if(sparam=="X") { ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); //--- unpress the button ObjectSetInteger(0,"X",OBJPROP_STATE,false); ObjectSetInteger(0,"X",OBJPROP_ZORDER,0); //-- DeleteButtonX(); mc.PanelExtra=false; DisplayManualButton(); } //--- if "M" button is click if(sparam=="M") { //--- unpress the button ObjectSetInteger(0,"M",OBJPROP_STATE,false); ObjectSetInteger(0,"M",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateManualPanel(); } //--- if "C" button is click if(sparam=="C") { //--- unpress the button ObjectSetInteger(0,"C",OBJPROP_STATE,false); ObjectSetInteger(0,"C",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateSymbolPanel(); } //--- if "R" button is click if(sparam=="R") { Alert("-- "+mc.expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart."); ExpertRemove(); //--- unpress the button ObjectSetInteger(0,"R",OBJPROP_STATE,false); ObjectSetInteger(0,"R",OBJPROP_ZORDER,0); if(!ChartSetSymbolPeriod(0,Symbol(),Period())) ChartSetSymbolPeriod(0,Symbol(),Period()); DeletePanelButton(); ChartRedraw(0); } //--- if Symbol button is click if(lensparam==lensymbol) { int sx=mc.PairsIdxArray(sparam); ChangeChartSymbol(mc.AS30[sx],CCS); mc.PanelExtra=false; } //-- } //-- return; //--- } //-end OnChartEvent()
Um die Chartsymbole mit einem Klick zu ändern, wird der Befehl OnChartEvent() ChangeChartSymbol() aufgerufen, wenn einer der Symbolnamen angeklickt wird.
void ChangeChartSymbol(string c_symbol,ENUM_TIMEFRAMES cstf) { //--- //--- unpress the button ObjectSetInteger(0,c_symbol,OBJPROP_STATE,false); ObjectSetInteger(0,c_symbol,OBJPROP_ZORDER,0); ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); //-- ChartSetSymbolPeriod(0,c_symbol,cstf); //-- ChartRedraw(0); //-- return; //--- } //-end ChangeChartSymbol()
Wenn die Option in der Experteneigenschaft Display Trading Info on Chart (Handelsinformationen auf dem Chart anzeigen) auf „Ja“ gesetzt ist, dann werden auf dem Chart, auf dem der Expertenberater platziert ist, Handelsinformationen durch den Aufruf der Funktion TradeInfo() angezeigt.
void MCEA::TradeInfo(void) // function: write comments on the chart { //---- Pips(Symbol()); double spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)/xpip; //-- string comm=""; TodayOrders(); //-- comm="\n :: Server Date Time : "+string(ThisTime(year))+"."+string(ThisTime(mon))+"."+string(ThisTime(day))+ " "+TimeToString(TimeCurrent(),TIME_SECONDS)+ "\n ------------------------------------------------------------"+ "\n :: Broker : "+ TerminalInfoString(TERMINAL_COMPANY)+ "\n :: Expert Name : "+ expname+ "\n :: Acc. Name : "+ mc_account.Name()+ "\n :: Acc. Number : "+ (string)mc_account.Login()+ "\n :: Acc. TradeMode : "+ AccountMode()+ "\n :: Acc. Leverage : 1 : "+ (string)mc_account.Leverage()+ "\n :: Acc. Equity : "+ DoubleToString(mc_account.Equity(),2)+ "\n :: Margin Mode : "+ (string)mc_account.MarginModeDescription()+ "\n :: Magic Number : "+ string(magicEA)+ "\n :: Trade on TF : "+ EnumToString(TFt)+ "\n :: Today Trading : "+ TradingDay()+" : "+hariini+ "\n ------------------------------------------------------------"+ "\n :: Trading Pairs : "+pairs+ "\n :: BUY Market : "+string(oBm)+ "\n :: SELL Market : "+string(oSm)+ "\n :: Total Order : "+string(oBm+oSm)+ "\n :: Order Profit : "+DoubleToString(floatprofit,2)+ "\n :: Fixed Profit : "+DoubleToString(fixclprofit,2)+ "\n :: Float Money : "+DoubleToString(floatprofit,2)+ "\n :: Nett Profit : "+DoubleToString(floatprofit+fixclprofit,2); //--- Comment(comm); ChartRedraw(0); return; //---- } //-end TradeInfo()
Die Schnittstelle des Mehr-Währungs-EA FXSAR_MTF_MCEA sieht wie in der folgenden Abbildung aus.
Unter dem Namen des Expert Advisors FXSAR_MTF_MCEA finden Sie die Schaltflächen „M“, „C“ und „R“.
Wenn die Schaltfläche „M“ oder „C“ angeklickt wird, wird ein manuelles Schaltflächenfeld angezeigt (siehe unten).
Wenn die Schaltfläche M angeklickt wird, wird ein manuelles Schaltfeld angezeigt, über das der Händler Aufträge verwalten kann:
1. Set SL/TP All Orders (SL/TP für alle Aufträge einstellen)
2. Close All Orders (Alle Aufträge schließen)
3. Close All Profits (Alle Positionen im Gewinn schließen)
Wenn die Schaltfläche C angeklickt wird, wird eine Schaltfläche mit 30 Symbolnamen oder -paaren angezeigt, und die Händler können auf einen der Paar- oder Symbolnamen klicken. Wird einer der Namen des Paars oder der Symbole angeklickt, wird das Chartsymbol sofort durch das Symbol ersetzt, dessen Name angeklickt wurde.
Wenn die Schaltfläche R angeklickt wird, wird der Mehr-Währungs-EA FXSAR_MTF_MCEA aus dem Chart entfernt.
Strategietester
Wie bekannt, unterstützt das MetaTrader 5-Terminal Strategy Tester und ermöglicht es uns, Strategien zu testen, auf mehreren Symbolen zu handeln oder den automatischen Handel für alle verfügbaren Symbole und auf allen verfügbaren Zeitrahmen zu testen.
Bei dieser Gelegenheit werden wir FXSAR_MTF_MCEA als Multi-Timeframe und Mehr-Währungs-EA auf der MetaTrader 5 Strategy Tester Plattform testen.
Schlussfolgerung
Die Schlussfolgerung bei der Erstellung eines Multi-Currency und Multi-Timeframe Expert Advisors mit MQL5 ist wie folgt:
- Es stellt sich heraus, dass die Erstellung eines Mehr-Währungs-EA in MQL5 sehr einfach ist und sich nicht wesentlich von einem Single-Currency Expert Advisor unterscheidet. Aber gerade bei Mehr-Währungs-EAs mit Multi Timeframes ist es ein wenig komplizierter als einer für einen einzelnen Zeitrahmen.
- Die Erstellung eines Mehr-Währungs-EAs erhöht die Effizienz und Effektivität von Händlern, da sie nicht viele Chart-Symbole für den Handel öffnen müssen.
- Durch die Anwendung der richtigen Handelsstrategie und die Berechnung besserer Indikatorsignale erhöht sich die Gewinnwahrscheinlichkeit im Vergleich zur Verwendung eines Single-Currency Expert Advisors. Denn die Verluste, die bei einem Paar auftreten, werden durch Gewinne bei anderen Paaren ausgeglichen.
- Dieser FXSAR_MTF_MCEA Mehr-Währungs-EA ist nur ein Beispiel, um zu lernen und Ideen zu entwickeln.
- Die Testergebnisse des Strategietesters sind immer noch nicht gut. Wenn also eine bessere Strategie mit genaueren Signalberechnungen implementiert wird und einige bessere Zeitrahmen hinzugefügt werden, glaube ich, dass die Ergebnisse besser sein werden als die aktuelle Strategie.
Anmerkung:
Wenn Sie eine Idee für die Erstellung eines einfachen Mehr-Währungs-EA auf der Grundlage der eingebauten MQL5-Standardindikatoren haben, schlagen Sie sie bitte in den Kommentaren vor.
Wir hoffen, dass dieser Artikel und das MQL5 Mehr-Währungs-EA-Programm für Händler beim Lernen und Entwickeln von Ideen nützlich sein werden. Danke fürs Lesen.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/13470





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.