MetaTrader 5 herunterladen

Hat Dir der Artikel gefallen?
Teile ihn mit den anderen -
poste einen Link zu diesem Beitrag!

Nutze neue Möglichkeiten der Plattform MetaTrader 5

Optimierung. Einige simple Ideen

13 Juni 2016, 13:12
Jose Miguel Soriano
2
241

Einleitung

Nachdem wir eine konsistente Handelsstrategie für den EA gefunden haben, führen wir den EA auf dem EURUSD-Diagramm aus, richtig? Könnte diese Strategie für andere Währungspaare noch profitabler sein? Gibt es andere Währungspaare, auf denen diese Strategie zu besseren Ergebnissen führt, ohne das Los in geometrischer Progression zu vergrößern?

Was passiert, wenn wir EURUSD und den Standard-Timeframe H1 wählen und uns anschließend für EURJPY auf H4 entscheiden, wenn wir mit dem Ergebnis unzufrieden sind?

Wenn wir außerdem über ein 64-Bit-Betriebssystem verfügen, dank dem wir uns keine Sorgen mehr um die Geschwindigkeit beim Testen des Systems machen müssen, vergessen wir dann die lächerlichen Eingabeparameter des Handelssystems, die an der vollständigen Aufzählung während der Optimierung beteiligt sind und deren Ergebnisse wir in den finalen Berichten vernachlässigen müssen?

Ich habe diese "kleinen Probleme" selbst gelöst und möchte in diesem Beitrag die effektiven Lösungen mit Ihnen teilen. Mir ist natürlich bewusst, dass es andere und bessere Lösungen geben kann.


Optimierung nach Timeframes

MQL5 liefert einen vollständigen Satz von Timeframes: von M1, M2, M3, M4,... H1, H2,... bis zu monatlichen Diagrammen. Insgesamt gibt es 21 Timeframes. Bei der Optimierung wollen wir allerdings wissen, welche Timeframes für unsere Strategie am besten geeignet sind – kurze wie M1 und M5, mittlere wie H2 und H4 oder lange wie D1 und W1.

Am Anfang brauchen wir diese Vielfalt an Optionen überhaupt nicht. Wenn wir sehen, dass sich die Strategie auf dem M5-Timeframe als effektiv erweist, können wir bei der nächsten Optimierungsphase prüfen, ob sie auch auf M3 oder M6 noch funktioniert.

Wenn wir eine Variable des Typen ENUM_TIMEFRAMES als Eingabeparameter nutzen:

input ENUM_TIMEFRAMES marcoTF= PERIOD_M5; 

bietet uns der Optimierer 21 Optimierungsvarianten an. Brauchen wir wirklich diese Menge?

Standardoptionen eines Timeframes

Am Anfang nicht. Wie können wir die Optimierung vereinfachen? Zunächst können wir die Aufzählung definieren:

enum mis_MarcosTMP
{
   _M1= PERIOD_M1,
   _M5= PERIOD_M5,
   _M15=PERIOD_M15,
//   _M20=PERIOD_M20,
   _M30=PERIOD_M30,
   _H1= PERIOD_H1,
   _H2= PERIOD_H2,
   _H4= PERIOD_H4,
//   _H8= PERIOD_H8,
   _D1= PERIOD_D1,
   _W1= PERIOD_W1,
   _MN1=PERIOD_MN1
};

in der wir die jeweiligen Timeframes hinzufügen oder löschen können. Definieren Sie für die Optimierung die Eingabevariable am Anfang des Codes:

input mis_MarcosTMP timeframe= _H1;

und definieren Sie in der .mqh-Bibliothek eine neue Funktion:

//----------------------------------------- DEFINE THE TIMEFRAME ----------------------------------------------------------
ENUM_TIMEFRAMES defMarcoTiempo(mi_MARCOTMP_CORTO marco)
{
   ENUM_TIMEFRAMES resp= _Period;
   switch(marco)
   {
      case _M1: resp= PERIOD_M1; break;
      case _M5: resp= PERIOD_M5; break;
      case _M15: resp= PERIOD_M15; break;
      //case _M20: resp= PERIOD_M20; break;
      case _M30: resp= PERIOD_M30; break;
      case _H1: resp= PERIOD_H1; break;
      case _H2: resp= PERIOD_H2; break;
      case _H4: resp= PERIOD_H4; break;
      //case _H8: resp= PERIOD_H8; break;
      case _D1: resp= PERIOD_D1; break;
      case _W1: resp= PERIOD_W1; break;
      case _MN1: resp= PERIOD_MN1;
   }
return(resp);
}

Deklarieren Sie eine neue Variable im Bereich der globalen Variablen:

ENUM_TIMEFRAMES marcoTmp= defMarcoTiempo(marcoTiempo);          //timeframe is defined as a global variable

"marcoTmp" ist eine globale Variable, die im EA verwendet wird, um den erforderlichen Timeframe für das Diagramm zu definieren. In der Tabelle der Parameter des Optimierers kann das Intervall für die Ausführung der Variable "marcoTiempo" definiert werden. Dies deckt nur die für uns interessanten Schritte ab, ohne Zeit und Ressourcen für die Analyse von M6 oder M12 aufzuwenden. Auf diese Weise können wir die Ergebnisse der Arbeit des EAs auf unterschiedlichen Timeframes analysieren.

Benutzerspezifische Optionen eines Timeframes

Natürlich besteht auch die folgende Möglichkeit:

ENUM_TIMEFRAMES marcoTmp= (ENUM_TIMEFRAMES)marcoTiempo;

Das zeigt sich nach Monaten oder gar Jahren des Programmierens, wenn man Perfektionist ist und den Code mehrfach durchforstet, um ihn zu vereinfachen. Oder wenn man einen VPS nutzt und versucht, die Rechnungen durch die Optimierung der Performance des Computers niedrig zu halten.


Optimieren eines Symbols oder eines Satzes von Symbolen

Im Strategietester von MetaTrader 5 gibt es einen Optimierungsmodus, der die Ausführung des EAs auf allen in der Marktübersicht ausgewählten Symbolen ermöglicht. Allerdings erlaubt es diese Funktion nicht, die Optimierung so einzurichten, dass das ausgewählte Symbol als weiterer Parameter behandelt wird. Wenn also 15 Symbole ausgewählt sind, richtet der Tester 15 Durchläufe ein. Wie finden wir heraus, welches Symbol für unseren EA das beste ist? Wenn es sich um einen mehrwährungsfähigen EA handelt, welche Gruppe von Symbolen liefert mit welchem Satz von Parametern das beste Ergebnis? Stringvariablen werden in MQL5 nicht optimiert. Was kann man tun?

Programmieren Sie ein Symbol oder ein Paar von Symbolen mit dem Wert des Eingabeparameters auf folgende Art:

input int selecDePar= 0;

string cadParesFX= selecPares(selecDePar);

Der Parameter "selecDePar" wird als Optimierungsparameter verwendet, der in eine Stringvariable konvertiert wird. Verwenden Sie die Variable "cadParesFX" im EA. Das Währungspaar/die Währungspaare (für diesen Code ist es irrelevant, ob die Strategie mit mehreren Währungen arbeitet) werden zusammen mit anderen gewöhnlichen Optimierungsparametern in dieser Variable gespeichert.

//------------------------------------- SELECT THE SET OF PAIRS -------------------------------------
string selecPares(int combina= 0)
{
   string resp="EURUSD";
   switch(combina)               
      {
         case 1: resp= "EURJPY"; break;
         case 2: resp= "USDJPY"; break;
         case 3: resp= "USDCHF"; break;      
         case 4: resp= "GBPJPY"; break;
         case 5: resp= "GBPCHF"; break;      
         case 6: resp= "GBPUSD"; break;
         case 7: resp= "USDCAD"; break;
         case 8: resp= "CADJPY"; break;      
         case 9: resp= "XAUUSD"; break;
       
         case 10: resp= "EURJPY;USDJPY"; break;
         case 11: resp= "EURJPY;GBPJPY"; break;
         case 12: resp= "GBPCHF;GBPJPY"; break;
         case 13: resp= "EURJPY;GBPCHF"; break;
         case 14: resp= "USDJPY;GBPCHF"; break;

         case 15: resp= "EURUSD;EURJPY;GBPJPY"; break;
         case 16: resp= "EURUSD;EURJPY;GBPCHF"; break;
         case 17: resp= "EURUSD;EURJPY;USDJPY"; break;
         case 18: resp= "EURJPY;GBPCHF;USDJPY"; break;
         case 19: resp= "EURJPY;GBPUSD;GBPJPY"; break;
         case 20: resp= "EURJPY;GBPCHF;GBPJPY"; break;
         case 21: resp= "USDJPY;GBPCHF;GBPJPY"; break;
         case 22: resp= "EURUSD;USDJPY;GBPJPY"; break;
       
         case 23: resp= "EURUSD;EURJPY;USDJPY;GBPUSD;USDCHF;USDCAD"; break;
         case 24: resp= "EURUSD;EURJPY;USDJPY;GBPUSD;USDCHF;USDCAD;AUDUSD"; break;
      }
   return(resp);
}

Je nachdem, was unser Ziel ist, definieren Sie Kombinationen von Paaren und informieren Sie den Tester über das zu analysierende Intervall. Erteilen Sie dem Strategietester einen Befehl zum Optimieren des Parameters "selecDePar" im Intervall von 15 bis 22 (siehe nachfolgende Abbildung). Was machen wir, wenn wir Ergebnisse für eine einzelne Währung vergleichen wollen? In diesem Fall führen wir die Optimierung auf dem Intervall von 0 bis 9 durch.

Optimierung eines Satzes von Paaren

Beispielsweise erhält der EA den Wert des Parameters cadParesFX= "EURUSD;EURJPY;GBPCHF". Rufen Sie in OnInit() die Funktion "cargaPares()" auf, die das dynamische Array arrayPares[] im Parameter cadParesFX mit Strings befüllt, getrennt durch das Zeichen ";". Alle globalen Variablen müssen in dynamische Arrays geladen werden, die die Werte jedes Symbols speichern, einschließlich der Kontrolle der Öffnung eines neuen Balkens auf einem Symbol, falls möglich. Wenn wir mit einem Symbol arbeiten, ist die Dimension des Arrays gleich eins.

//-------------------------------- STRING CONVERSION FROM CURRENCY PAIRS INTO AN ARRAY  -----------------------------------------------
int cargaPares(string cadPares, string &arrayPares[])
{            //convierte "EURUSD;GBPUSD;USDJPY" a {"EURUSD", "GBPUSD", "USDJPY"}; devuelve el número de paresFX
   string caract= "";
   int i= 0, k= 0, contPares= 1, longCad= StringLen(cadPares);
   if(cadPares=="")
   {
      ArrayResize(arrayPares, contPares);
      arrayPares[0]= _Symbol;
   }
   else
   {
      for (k= 0; k<longCad; k++) if (StringSubstr(cadPares, k, 1)==";") contPares++;
      ArrayResize(arrayPares, contPares);    
      ZeroMemory(arrayPares);
      for(k=0; k<longCad; k++)
      {
         caract= StringSubstr(cadPares, k, 1);
         if (caract!=";") arrayPares[i]= arrayPares[i]+caract;
         else i++;
      }
    }
   return(contPares);
}

In OnInit() wird diese Funktion folgendermaßen umgesetzt:

string ar_ParesFX[];    //array, containing names of the pairs for the EA to work with
int numSimbs= 1;        //variable, containing information about the number of symbols it works with

int OnInit()
{
   
   //...
   numSimbs= cargaPares(cadParesFX, ar_ParesFX);     //returns the ar_ParesFX array with pairs for work in the EA
   //...
   
}

Falls numSimbs>1, wird die Funktion OnChartEvent() aufgerufen. Diese arbeitet mit einem Mehrwährungssystem. Andernfalls wird die Funktion OnTick() verwendet:

void OnTick()
{
   string simb="";
   bool entrar= (nSimbs==1);
   if(entrar)
   {   
      .../...
      simb= ar_ParesFX[0];
      gestionOrdenes(simb);
      .../...
   }
   return;
}

//+------------------------------------------------------------------+
//| EVENT HANDLER                                                   |
//+-----------------------------------------------------------------+
void OnChartEvent(const int idEvento, const long& lPeriodo, const double& dPrecio, const string &simbTick)
{
   bool entrar= nSimbs>1 && (idEvento>=CHARTEVENT_CUSTOM);
   if(entrar)      
   {
      .../...
      gestionOrdenes(simbTick);
      .../...
   }
}
  

Das bedeutet, dass alle Funktionen, die die Rolle eines Eingabeparameters erfüllen, mindestens das zu untersuchende Symbol beinhalten müssen. Beispielsweise müssen wir anstelle der Funktion Digits() Folgendes nutzen:

//--------------------------------- SYMBOLS OF A SYMBOL ---------------------------------------
int digitosSimb(string simb= NULL)
{
   int numDig= (int)SymbolInfoInteger(simb, SYMBOL_DIGITS);
   return(numDig);
}

In anderen Worten: Wir müssen die Funktionen Symbol() oder Point() sowie andere Variablen, die für MetaTrader 4 typisch sind, zum Beispiel Ask oder Bid, vergessen.

//----------------------------------- POINT VALUE in price (Point())---------------------------------
double valorPunto(string simb= NULL) 
{
   double resp= SymbolInfoDouble(simb, SYMBOL_POINT);
   return(resp);
}
//--------------------------- precio ASK-BID  -----------------------------------------
double precioAskBid(string simb= NULL, bool ask= true)
{
   ENUM_SYMBOL_INFO_DOUBLE precioSolic= ask? SYMBOL_ASK: SYMBOL_BID;
   double precio= SymbolInfoDouble(simb, precioSolic);
   return(precio);
}

Ebenso haben wir die Funktion der Kontrolle über die Öffnung des Balkens vergessen, die in solchen Codes vorhanden ist. Wenn die in EURUSD empfangenen Ticks die Öffnung eines neuen Balkens melden, werden die Ticks für USDJPY in den folgenden 2 Sekunden möglicherweise nicht empfangen. Somit muss der EA beim nächsten USDJPY-Tick entdecken, dass ein neuer Balken für dieses Symbol geöffnet wird, auch wenn dieses Ereignis für EURUSD bereits vor 2 Sekunden eingetreten ist.

//------------------------------------- NEW MULTI-CURRENCY CANDLESTICK -------------------------------------
bool nuevaVelaMD(string simb= NULL, int numSimbs= 1, ENUM_TIMEFRAMES marcoTmp= PERIOD_CURRENT)
{
        static datetime arrayHoraNV[];
        static bool primVez= true;
        datetime horaVela= iTime(simb, marcoTmp, 0);    //received opening time of the current candlestick
        bool esNueva= false;
        int codS= buscaCadArray(simb, nombreParesFX);      
        if(primVez)
        {
           ArrayResize(arrayHoraNV, numSimbs);
           ArrayInitialize(arrayHoraNV, 0);     
           primVez= false;
        }
        esNueva= codS>=0? arrayHoraNV[codS]!= horaVela: false;
        if(esNueva) arrayHoraNV[codS]= horaVela;
        return(esNueva); 
}

Dank dieser Methode konnte ich in einem Optimierungsdurchlauf Folgendes entdecken:

  • Der EA funktioniert in EURUSD gut.
  • Funktioniert in EURJPY schlecht.
  • Funktioniert in USDJPY zufriedenstellend.
  • Funktioniert auf den Paaren EURUSD, GBPCHF, EURJPY sehr gut (realer Fall).

Dies gilt für die Periode M5 und eine bestimmte Kombination von anderen Optimierungsparametern, allerdings nicht für H1 oder H2.

Es gibt nur eine Schwierigkeit. Ich habe den technischen Support bereits dazu befragt. Ich weiß nicht, warum das passiert, aber die Optimierungsergebnisse unterscheiden sich abhängig vom Symbol, das wir im Strategietester auswählen. Deshalb fixiere ich dieses Paar während der Entwicklung der Strategie und gehe sicher, dass es sich um eins der Paare handelt, die im Optimierer analysiert werden können, um das Ergebnis zu überprüfen.


Optimierung einer Kombination von Parametern

Manchmal erweisen sich unlogische Kombinationen unter allen Kombinationen von Parametern, die an der Optimierung beteiligt sind, als geeignet. Einige von ihnen machen sogar die Strategie unlogisch. Zum Beispiel: Wenn die Variable des Eingangs "maxSpread" den Wert des Spreads für eine Handelsoperation definiert, optimieren wir diese Variable für verschiedene Paare, bei denen der durchschnittliche Spread des Brokers unter 30 liegt und XAUUSD 400 ist. Es wäre absurd, diese Paare zu analysieren, wenn sie 50 überschreiten und XAUUSD weniger als 200 ist. Nach dem Übergeben der Daten an den Optimierer geben Sie "evalua maxSpread zwischen 0 und 600 mit Intervall 20" an, doch ein solcher Satz mit anderen Parametern führt zu zahlreichen Kombinationen, die keinen Sinn ergeben.

Unter Befolgung des im vorherigen Abschnitt beschriebenen Schemas haben wir Paare für die Optimierung in der Funktion "selecPares()" definiert. EURUSD erhält Option 0 und XAUUSD erhält Option 9. Definieren Sie anschließend eine globale Variable des Typen bool "paramCorrect".

bool paramCorrect= (selecDePar<9 && maxSpread<50) ||
                   (selecDePar==9 && maxSpread>200);

Führen Sie die Aktionen in OnInit() nur dann aus, wenn paramCorrect sich in der korrekten Position true befindet.

int OnInit()
{   
   ENUM_INIT_RETCODE resp= paramCorrect? INIT_SUCCEEDED: INIT_PARAMETERS_INCORRECT;
   if (paramCorrect)
   {
      //...
      nSimbs= cargaPares(cadParesFX, nombreParesFX);     //return the array nombreParesFX containing pairs for work in the EA
      //... function of the EA initialization
   }
   return(resp);
}

Wenn paramCorrect in der inkorrekten Position false ist, führt der EA keine Aktion in OnInit() aus und gibt den Code INIT_PARAMETERS_INCORRECT an den Strategietester zurück, was einen inkorrekten Satz von Eingabedaten bedeutet. Wenn der Strategietester den Wert INIT_PARAMETERS_INCORRECT von OnInit() erhält, wir dieser Satz von Parametern nicht zur Umsetzung an andere Testagenten übergeben und die Tabellenzeile mit den Optimierungsergebnissen wird mit Nullen befüllt und rot markiert (siehe nachfolgende Abbildung).

Ergebnis der Verwendung von inkorrekten Parametern

Der Grund für den Abbruch des Programms wird als Eingabevariable an OnDeinit() übergeben und hilft, den Grund für die Schließung des EAs nachzuvollziehen. Doch das ist ein anderes Thema.

void OnDeinit(const int motivo)
{
   if(paramCorrect)
   {
      
      //functions of the program shutdown
      
   }
   infoDeInit(motivo);
   return;
}

//+-------------------------------------- INFORMATION ABOUT THE PROGRAM SHUTDOWN----------------------------
string infoDeInit(int codDeInit)
{                       //informs of the reason of the program shutdown
   string texto= "program initialization...", text1= "CIERRE por: ";
   switch(codDeInit)
   {
      case REASON_PROGRAM:     texto= text1+"The EA finished its work with the ExpertRemove() function"; break;  //0
      case REASON_ACCOUNT:     texto= text1+"The account was changed"; break;                                    //6
      case REASON_CHARTCHANGE: texto= text1+"Symbol or timeframe change"; break;                                 //3
      case REASON_CHARTCLOSE:  texto= text1+"The chart was closed"; break;                                       //4
      case REASON_PARAMETERS:  texto= text1+"Input parameters changed by the user"; break;                       //5
      case REASON_RECOMPILE:   texto= text1+"The program was recompiled"; break //2
      case REASON_REMOVE:      texto= text1+"The program was deleted from the chart"; break;                     //1
      case REASON_TEMPLATE:    texto= text1+"Another chart template was used"; break;                            //7
      case REASON_CLOSE:       texto= text1+"The terminal was closed"; break;                                    //9
      case REASON_INITFAILED:  texto= text1+"The OnInit() handler returned non-zero value"; break;               //8
      default:                 texto= text1+"Other reason";
   }
   Print(texto);
   return(texto);
}

Das liegt daran, dass, wenn der im Optimierer empfangene Parametersatz in der angegebenen Phase "paramCorrect" auf false stellt (zum Beispiel, wenn der EURUSD-Spread auf 100 Punkte eingestellt wurde), wir den EA nicht ausführen und dieser Optimierungsschritt auf Null gesetzt wird, ohne unnötigerweise Computerressourcen zu verbrauchen oder Kosten für die Miete von Agents für Ihr MQL5.community-Konto zu verursachen.

Natürlich kann alles Gesagte mithilfe der Funktionen OnTesterInit(), ParameterGetRange() und ParameterSetRange() umgesetzt werden, doch das beschriebene Muster scheint einfacher zu sein. Es funktioniert garantiert, während das Muster mit OnTesterInit() nicht so konsistent ist.


Fazit

Wir haben die Beschleunigung der Suche nach den optimalen Timeframes in MetaTrader 5 und die Optimierung des Parameters "Symbol", wenn MetaTrader 5 die Optimierung von Stringvariablen nicht erlaubt, besprochen und sind darauf eingegangen, wie man es bewerkstelligen kann, dass die Anzahl der vom EA verwendeten Symbole unwichtig wird. Wir haben außerdem eine Illustration dazu gesehen, wie die Anzahl der Optimierungsschritte verringert werden kann, indem man unlogische Sätze von Eingabeparametern beseitigt, und man somit die Performance seines Computers schonen und Geld sparen kann.

Die oben aufgeführten Ideen sind nicht neu und können von Neulingen oder Programmierern mit etwas Erfahrung umgesetzt werden. Diese Ideen waren das Ergebnis einer langen Suche nach Informationen und der Nutzung des Debuggers. Es handelt sich um äußerst simple, aber effiziente Ideen. Vielleicht stellen Sie sich die Frage, warum ich diese Ideen teile, wenn ich durch MQL5 Gewinne erzielen will? Die Antwort ist: Um die "Einsamkeit" eines Programmierers zu überwinden.

Vielen Dank für Ihre Aufmerksamkeit. Falls Sie den Beitrag bis zum Ende durchgelesen haben und ein erfahrener Programmierer sind, möchte ich Sie bitten, mit mir nicht zu hart ins Gericht zu gehen.

Übersetzt aus dem Spanischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/es/articles/1052

Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Jose Miguel Soriano
Jose Miguel Soriano | 15 Jun 2016 in 09:43
MetaQuotes Software Corp.:

Neuer Artikel Optimierung. Einige simple Ideen :

Autor: Jose Miguel Soriano

Please, in spanish or english.
Carl Schreiber
Carl Schreiber | 15 Jun 2016 in 11:03
Jose Miguel Soriano:
Please, in spanish or english.

1) Take the url: "https://www.mql5.com/de/articles/1052"  and replace ../de/.. by ../en/..

2) Top-Right of the article you find a button in the colores of the flag. Put the mous above it and choose the language you want.



Überblick über den MetaTrader Market (Infografik) Überblick über den MetaTrader Market (Infografik)

Vor einigen Wochen haben wir die Infografik zum Freelance-Service veröffentlicht. Wir haben auch versprochen, einige Statistiken über den MetaTrader Market zu enthüllen. Wir möchten Sie nun einladen, sich die Daten anzusehen, die wir gesammelt haben.

Regressionsanalyse des Einflusses makroökonomischer Daten auf Fluktuationen des aktuellen Kurses Regressionsanalyse des Einflusses makroökonomischer Daten auf Fluktuationen des aktuellen Kurses

Dieser Artikel widmet sich der Anwendung einer multiplen Regressionsanalyse auf makroökonomische Statistiken. Sie werden außerdem einige Dinge über die Bewertung des Einflusses von Statistiken auf die Wechselkursveränderungen erfahren, indem wir uns beispielhaft das Währungspaar EURUSD anschauen werden. Eine derartige Evaluation erlaubt eine automatisierte Fundamentalanalyse, die selbst unerfahrenen Tradern möglich wird.

Anbieter des Signals Jonpaul77: "Unsere Strategie ist nun seit über drei Jahren profitabel. Warum sollten wir sie ändern?" Anbieter des Signals Jonpaul77: "Unsere Strategie ist nun seit über drei Jahren profitabel. Warum sollten wir sie ändern?"

Lassen Sie uns ein kleines Geheimnis enthüllen: Besucher der Webseite MQL5.com verbringen die meiste Zeit auf der Seite des Signals Johnpaul77. Mit etwa 900 Abonnenten mit Gesamtmitteln von 5,7 Millionen US-Dollar auf realen Konten handelt es sich um den Anführer unseres Signal-Ratings. Wir haben die Anbieter des Signals interviewt. Es hat sich herausgestellt, dass sie zu viert sind! Wie werden die Aufgaben zwischen den Teammitgliedern aufgeteilt? Welche technischen Tools nutzen sie? Warum nennen sie sich John Paul? Und zu guter Letzt, wie konnten sich gewöhnliche Gamer aus Indonesien zu den Anbietern des besten Signals auf MQL5.com entwickeln? Finden Sie all das in diesem Beitrag heraus.

Aufbau eines Social-Technology-Startups, Teil II: Programmierung eines MQL5-REST-Clients Aufbau eines Social-Technology-Startups, Teil II: Programmierung eines MQL5-REST-Clients

Lassen Sie uns die PHP-basierte Twitter-Idee aus dem ersten Teil dieses Beitrags nun in Form bringen. Wir setzen die verschiedenen Teile des SDSS zusammen. In Bezug auf die Client-Seite der Systemarchitektur verlassen wir uns auf die neue MQL5-Funktion WebRequest() zum Senden von Handelssignalen per HTTP.