Download MetaTrader 5

Creating Neural Network EAs Using MQL5 Wizard and Hlaiman EA Generator

19 September 2013, 10:27
Ivan Negreshniy
18
11 239

Introduction

Virtually every trader knows about the existence of neural networks. But for the majority of them it remains a black box, with the only things known being the ability of neural networks to recognize patterns, produce associative search for solutions and learn, as well as the fact that they can be effective in predicting the market behavior and in automated trading. Many sources of information that focus on the application of neural networks often speak about their difficulty, emphasizing that one has to devote a great deal of time and effort to learn this subject well and be able to use neural networks in the future.

This article aims at refuting these arguments and proving that advanced automation methods enable traders to have an easy start with neural networks and avoid the lengthy learning process. There is nothing difficult in getting your own experience with neural networks. It is certainly easier than technical analysis.

With this in view, we will describe a method of automatic generation of neural network EAs for MetaTrader 5 using the MQL5 Wizard and Hlaiman EA Generator.

The choice of tools to solve the task at hand is far from being random:

  1. MQL5 Wizard is an efficient and the fastest mechanism of automatic MQL5 code generation to date that allows you to scale the generated code using additional modules.
  2. Hlaiman EA Generator is a neural network engine with a flexible mechanism of object integration, programmable directly in the MQL5 code of an Expert Advisor.

The abbreviation 'EA' has been added to the name of the Expert Advisor intentionally as humanlike properties associated with recognition and learning are predominant in a neural network EA unlike in other cases where the use of 'EA' in a name is often misleading and does not reflect the true nature of things.


General Description

Due to the reason outlined in the article's objective, you will not find here any theoretical information, classifications and structure of neural networks or research data related to financial markets. That information is available in other sources. In this article, we will deliberately confine ourselves to the concept of a neural network as a black box capable of associative thinking and predicting market entries based on recognition of graphical price patterns. For the same reason, we will use the simplest notion of the pattern being a continuous sequence of bars in a trading instrument chart that precedes a profitable price movement.

A few words about problem-solving tools. Unlike Hlaiman, MQL5 Wizard has often been the subject of various articles and documentation and needs no introduction just as MetaTrader 5. The socially-oriented Hlaiman project is intended for the development and promotion of multi-purpose software in the form of plug-ins, with EA Generator being one of them. As mentioned earlier, functionally EA Generator represents a neural network engine with the integration mechanism.

Hlaiman EA Generator includes <hlaim.exe> - a shell that represents a Windows GUI application with multi-document interface and plug-ins in the form of dynamically loadable component libraries. The system provides a wide range of manual and algorithmic adjustment and component control methods that can be both standard and loadable as part of plug-ins. In the course of system operation, you can create complex hierarchies of objects and have flexible control over their methods and properties, using Object Inspector and automation software tools, e.g. scripts.

The integration of Hlaiman EA Generator with MQL5 involves the Object Pascal script interpreter, while the source code is passed via Named Pipes. A multilayer perceptron (MLP) is used as the main neural network component.

Hlaiman EA Generator is integrated with the MQL5 Wizard using a signal library module - SignalHNN.mqh. Once generated automatically, the Expert Advisor can then be taught to trade on any number of instruments and time frames. In the МetaТrader 5 terminal, arrows indicating signals can be either drawn in the price chart manually using the graphical objects for arrows or automatically using the TeachHNN.mq5 script that at the same time initiates the process of teaching the Expert Advisor.

This concludes the theoretical description. We now proceed to the practical part that is divided into two sections - Operating Principles and Implementation.

The second section is aimed at software developers and is provided here primarily out of respect to this website. It is therefore optional, especially for traders who have little or no interest in gaining programming skills but are interested in creating neural network EAs and assessing their efficiency or uselessness in terms of trading.


Operating Principles

In MQL5.community, it would probably be unnecessary to mention that you need the MetaТrader 5 terminal in order to proceed. If you do not have it, download and install it. You should also download and install a demo version of Hlaiman EA Generator.

Launch the МetaТrader 5 terminal and start MetaEditor. Open the MQL5 Wizard. You can do it using the 'New' option in the Standard toolbar or under the File menu, as well as using the 'Ctrl+N' hotkey.

In the MQL5 Wizard window, select 'Expert Advisor (generate)' and click 'Next'.

Fig. 1. Creating an Expert Advisor in the MQL5 Wizard

Fig. 1. Creating an Expert Advisor in the MQL5 Wizard

Specify the location and the name of the Expert Advisor, e.g. 'Experts\SampleHNN' and click 'Next'.

Fig. 2. General Properties of the Expert Advisor

Fig. 2. General Properties of the Expert Advisor

Click the 'Add' button. You will see the window of 'Parameters of Signal Module' where you need to select 'Signals of patterns Hlaiman Neural Network EA generator' from the drop-down list and click 'OK'.

Fig. 3. Selecting the trading signal module of Hlaiman Neural Network EA generator

Fig. 3. Selecting the trading signal module of Hlaiman Neural Network EA generator

In case of a very basic implementation, you can click 'Next' at all the remaining steps of the MQL5 Wizard. If necessary, the Expert Advisor can be enhanced by selecting additional options.

Upon completion of the code generation, click 'Compile' and close the MetaEditor window. The generated Expert Advisor will appear in the Navigator panel of the MetaTrader 5 terminal under 'Expert Advisors'.

Fig. 4. The SampleHNN Expert Advisor

Fig. 4. The SampleHNN Expert Advisor

Before we proceed to teaching the generated Expert Advisor, we need to open a chart with the required symbol and time frame in the terminal. The Hlaiman EA Generator application must be up and running.

Fig. 5. Neural network teaching preparation

Fig. 5. Neural network teaching preparation

To teach the Expert Advisor, select 'TeachHNN' under 'Scripts' in the Navigator panel of the terminal and activate it for the specified chart.

Prior to running the 'TeachHNN' script, you should make sure it has all the appropriate settings. It has the following parameters:

  • Document name - name of the Expert Advisor for teaching;
  • Neural layers - number of neural network layers;
  • Middle neurons - number of neurons;
  • Teaching epochs - number of teaching epochs;
  • Pattern bars - number of bars in a pattern;
  • Teaching a net? - start the neural network teaching process (or simply the signal generation);
  • SignalsCreate - to automatically create graphical images of signals;
  • SignalsBarPoints - signal generation threshold expressed in points;
  • SignalsBarsCount - number of bars for the calculation of points;
  • SignalsStartTime, SignalsEndTime - start and end time of the period for the signal generation;
  • SignalsClear - to automatically delete signal images upon completion of teaching.

Fig. 6. The TeachHNN script parameters

Fig. 6. The TeachHNN script parameters

If everything is ready, click 'OK' to start the process of teaching the Expert Advisor. This will initiate the automatic generation of graphical patterns for each of the available signals in the chart.

The relevant information is displayed in the 'Experts' tab on the 'Toolbox' panel of the terminal, while the corresponding objects appear in the Hlaiman EA Generator window.

Upon completion of the pattern generation, the teaching process starts. It is displayed in the teaching progress bar that appears on the screen.

Teaching Hlaiman EA Generator

Fig. 7. Teaching progress panel

Wait until the process is completed. The teaching process can be terminated before it is completed by right-clicking on the teaching progress bar and selecting the appropriate option in the context menu.

Upon completion of the teaching process and script operation, the relevant message will be added to the log in the 'Experts' tab, e.g. 'Neural net create success! On 431 patterns' indicates that the teaching of the Expert Advisor was successfully completed using 431 signals.

These messages show how many patterns were involved in the teaching process and find out the numbers of those patterns. The BUY and SELL, in particular, are determined using the messages of the following type: 'Sell signal detected at pattern #211'.

Fig. 8. The TeachHNN script messages in the course of teaching

Fig. 8. The TeachHNN script messages in the course of teaching

The reasons why the process of teaching the Expert Advisor may start with an error are as follows:

  1. The Hlaiman application was not up and running prior to the start, as required. In this case the error message will be as follows "CSignalHNN::InitHNN: Error! initializing pipe server (possible reason: HLAIMAN APPLICATION IS NOT RUNNING!)".
  2. The absence of arrows indicating signals in the chart upon disabled automatic generation of signals (the SignalsCreate variable = false). In this case the error message to be displayed is as follows: "OnStart: error, orders arrow not found!" If the automatic generation of signals is enabled (the SignalsCreate variable = true), an error may be caused by the presence of other graphical objects in the chart, since custom markings are not supposed to be messed with in the program. It is therefore recommended to open all charts separately for the purpose of automatic generation of signals.

When the teaching of the Expert Advisor is completed, you can view the relevant results by switching to GUI Hlaiman and selecting the appropriate objects and visualization panels.

Fig. 9. The 'Text' tab of the Hlaiman application

Fig. 9. The 'Text' tab of the Hlaiman application


Fig. 10. The 'Graph' tab of the Hlaiman application

Fig. 10. The 'Graph' tab of the Hlaiman application

After successfully teaching the Expert Advisor on at least one trading instrument, we can proceed to testing and/or optimization.

To do this, select the name of the trained Expert Advisor, symbol, time frame, interval and other testing parameters in the Strategy Tester. Set the external variables, if necessary, and run the test.

Fig. 11. Settings of the SampleHNN Expert Advisor for backtesting

Fig. 11. Settings of the SampleHNN Expert Advisor for backtesting


Fig. 12. External variables of the SampleHNN Expert Advisor can be modified

Fig. 12. External variables of the SampleHNN Expert Advisor can be modified

Below is an example of the Expert Advisor operation report in the Strategy Tester. The Expert Advisor has been taught using automatically generated signals, with all the external parameters of the teaching script being set by default. The teaching period: 01.01.2010-01.07.2013, instrument: EURUSD H4.


Strategy Tester Report

Expert Advisor:SampleHNN
Symbol: EURUSD
Period: H4 (2010.01.01-2013.07.12)
Currency: USD
Initial Deposit: 10,000.00
Leverage: 0,111111111
Backtesting
History Quality: 100%
Bars: 5497
Net Profit: 9,159.58
Gross Profit: 29,735.97
Gross Loss: -20,576.39
Profit Factor: 1.45
Recovery Factor: 12.81
AHPR: 1.0005 (0.05%)
GHPR: 1.0005 (0.05%)
Total Trades: 1417
Total Deals: 2246
Ticks: 60211228
Balance Drawdown Absolute: 0.00
Balance Drawdown Maximal: 679.98 (3.81%)
Balance Drawdown Relative: 4.00% (715.08)
Expected Payoff: 6.46
Sharpe Ratio: 0.16
LR Correlation: 0.98
LR Standard Error: 595.06
Short Trades (won %): 703 (56.61%)
Profit Trades (% of total): 793 (55.96%)
Largest Profit Trade: 53.00
Average Profit Trade: 37.50
Maximum consecutive wins: 9 (450.38)
Maximum consecutive profit: 450.38 (9)
Average consecutive wins: 2
Symbols: 1
Equity Drawdown Absolute: 6.60
Equity Drawdown Maximal: 715.08 (4.00%)
Equity Drawdown Relative: 4.00% (715.08)
Margin Level: 6929.24%
Z-Account: -1.24 (78.50%)
OnTester Result: 0
Long Trades (won %): 714 (55.32%)
Loss Trades (% of total): 624 (44.04%)
Largest Loss Trade: -53.30
Average Loss Trade: -32.97
Maximum consecutive losses: 9 (-234.00)
Maximum consecutive loss: -276.67 (7)
Average consecutive losses: 2

Fig. 13. The SampleHNN Expert Advisor backtesting results

Fig. 13. The SampleHNN Expert Advisor backtesting results


Fig. 14. The SampleHNN Expert Advisor market entry statistics

Fig. 14. The SampleHNN Expert Advisor market entry statistics


Fig. 15. Correlation between profit and MFE/MAE of the SampleHNN Expert Advisor

Fig. 15. Correlation between profit and MFE/MAE of the SampleHNN Expert Advisor


Fig. 16. The SampleHNN Expert Advisor position holding time statistics

Fig. 16. The SampleHNN Expert Advisor position holding time statistics

Implementation

The main MQL5 implementation component is the CSignalHNN class described in the SignalHNN.mqh signal module. The class is inherited from the CExpertSignal base class and includes all the necessary data fields and methods for the operation and integration of Hlaiman, as well as for working with Expert Advisors generated using the MQL5 Wizard.

The class template is as follows:

//+------------------------------------------------------------------+
//| Class CSignalHNN.                                                |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Hlaiman EA Generator Neural Net' indicator.        |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalHNN :public CExpertSignal
  {
protected:
   //--- variables
   int               m_hnn;                   // handle of HNN connect
   string            hnn_path;                // MT5 Terminal data path
   string            hnn_fil;                 // HNN file w neural net 
   string            hnn_nam;                 // Expert name
   string            hnn_sym;                 // Symbol name
   string            hnn_per;                 // Period name
   ENUM_TIMEFRAMES   hnn_period;              // Period timeframe
   int               hnn_index;               // Index ext multinet
   int               hnn_bar;                 // index of last bar
   int               hnn_in;                  // input layer 
   int               hnn_out;                 // output layer
   int               hnn_layers;              // layers count
   int               hnn_neurons;             // neurons count
   int               hnn_epoch;               // learn epoch
   double            hnn_signal;              // value of last signal
   double            pattern[];               // values of the pattern
   bool              hnn_norm;                // normalize pattern

public:
                     CSignalHNN(void);        // class constructor
                    ~CSignalHNN(void);        // class destructor
   //--- methods of setting adjustable parameters
   void              PatternBarsCount(int value) { hnn_in = value; ArrayResize(pattern, value + 1);  }
   void              LayersCount(int value)      { hnn_layers = value;  }
   void              NeuronsCount(int value)     { hnn_neurons = value;  }
   void              EpochCount(int value)       { hnn_epoch = value;  }
   void              Normalize(bool value)       { hnn_norm = value;  }
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   //--- method of creating the indicator and timeseries
   virtual bool      InitIndicators(CIndicators *indicators);
   //--- methods of checking conditions of entering the market
   virtual double    Direction(void);

   bool              FillPattern(datetime tim = 0);      // prepare pattern
   bool              AddPattern(string name, int ptype);  // add new pattern
   bool              TeachHNN(void);                     // learn neural net
   bool              SaveFileHNN(void);                  // neural net file
   double            CalculateHNN(void);                 // calc neural signal

                                                        //protected:
   //--- method of initialization of the Hlaiman Application
   bool              InitHNN(bool openn);                // Hlaiman App Init
   void              FreeHNN(void)
     {                     // Hlaiman App Deinit
      if(m_hnn!=0 && m_hnn!=INVALID_HANDLE)
        {
         FileClose(m_hnn);
         m_hnn=0;
        }
     };
  };

Following the creation of the class instance using the constructor, this object can work in two main modes:

  1. Teaching mode: this mode is associated with collection of market patterns and teaching of the neural network.
  2. Indicator mode: in this mode, the neural network signal is calculated using the current pattern.

The mode is identified upon calling the InitHNN initialization mode using the Boolean parameter openn. The true value of this parameter initiates the search and opening of, as well as loading and operation of, the data file of the taught neural network in the indicator mode (2). This mode is considered to be the operating mode and is used in the Expert Advisor for trading.

Unlike the teaching mode (1) that is initialized when calling the InitHNN method with openn=false, the indicator mode is preparatory for the Expert Advisor and is used for the operation of the teaching script.

The initialization method is implemented as follows:

//+------------------------------------------------------------------+
//| Initialize HNN                                                   |
//+------------------------------------------------------------------+
bool CSignalHNN::InitHNN(bool openn)
  {
//--- initialize Hlaiman Application
   int num=0;
   ulong res=0;
   if(m_symbol!=NULL)
     {
      hnn_sym=m_symbol.Name();
      hnn_period=m_period;
        } else {
      hnn_sym=_Symbol;
      hnn_period=_Period;
     }
   hnn_per = string(PeriodSeconds(hnn_period) / 60);
   hnn_fil = hnn_nam + NAME_DELIM + hnn_sym + hnn_per + NAME_DELIM + string(hnn_index) + TYPE_NEURO;
   if(m_hnn== 0|| m_hnn == INVALID_HANDLE)
      m_hnn=FileOpen(HLAIMAN_PIPE,FILE_READ|FILE_WRITE|FILE_BIN);
   if(m_hnn!=0 && m_hnn!=INVALID_HANDLE)
     {
      string source,result="";
      if(openn==true)
        {
         result=CON_OPENN+CON_TRUE;
         if(!FileIsExist(hnn_fil,FILE_READ))
           {
            if(FileIsExist(hnn_fil,FILE_READ|FILE_COMMON))
               hnn_fil=TerminalInfoString(TERMINAL_COMMONDATA_PATH)+PATH_FILES+hnn_fil;
            else
              {
               //              hnn_fil = hnn_path + PATH_MQL5 + PATH_FILES + hnn_fil;
               hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
              }
           }
         else hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
           } else {
         result=CON_OPENN+CON_FALSE;
         hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
        }
      source="unit InitHNN; Interface "+result+" var libr, term, exp, sym: TObject;"
             " Implementation function main: integer;\n\r" // Line #1
             " begin"
             " Result := 0;"
             " libr := Open('mt45.dll');\n\r" // Line #2
             " if (libr <> nil) then"
             " begin"
             " term := Open('"+hnn_path+"');\n\r" // Line #3
             " if (term <> nil) then"
             " begin"
             " exp := term.ObjectOfName('"+hnn_nam+"');"
             " if (exp = nil) then exp := term.AddObject('TMT45Expert');\n\r" // Line #5
             " if (exp <> nil) then"
             " begin"
             " if (exp.Name <> '"+hnn_nam+"') then exp.Name := '"+hnn_nam+"';\n\r" // Line #6
             " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');"
             " if (sym = nil) then sym := exp.AddObject('TMT45Symbol');"
             " if (sym <> nil) then"
             " begin"
             " sym.Log.Add('"+hnn_sym+hnn_per+"');\n\r"
             " if (sym.Name <> '"+hnn_sym+hnn_per+"') then sym.Name := '"+hnn_sym+hnn_per+"';"
             " if (sym.Period <> "+hnn_per+") then sym.Period := "+hnn_per+";"
             " if (openn = true) then"
             " begin"
             //                   " sym.Log.Add('" + hnn_fil + "');"
             " if (sym.Open('"+hnn_fil+"')) then Result := sym.TeachInput;\n\r" // ret input Line #8
             " end else"
             " begin"
             " sym.TeachInput := "+IntegerToString(hnn_in)+";"
             " sym.TeachOutput := "+IntegerToString(hnn_out)+";"
             " sym.TeachLayer := "+IntegerToString(hnn_layers)+";"
             " sym.TeachNeurons := "+IntegerToString(hnn_neurons)+";"
             " sym.TeachEpoch := "+IntegerToString(hnn_epoch)+";"
             " sym.FileName := '"+hnn_fil+"';"
             " Result := sym.TeachInput;\n\r" // ret input Line #9
             " end;"
             " end;"
             " end;"
             " end;"
             " end;"
             " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(res<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         res=FileSize(m_hnn);
         num++;
        }
      if(res>0)
        {
         result=FileReadString(m_hnn,int(res/2));
         res=StringToInteger(result);
         if(res<=RES_OK)
            printf(__FUNCTION__+": Error! Initialization data(possible reason: FILE NOT EXIST OR CORRUPTED "+hnn_fil);
         else
           {
            printf(__FUNCTION__+": Initialization successful! NEURAL PATTERN "+string(res));
            ArrayResize(pattern,int(res+1));
            return(true);
           }
        }
      else
         printf(__FUNCTION__+": Error! pipe server not responding(possible elimination: RESTART HLAIMAN APPLICATION)");
     }
   else
      printf(__FUNCTION__+": Error! initializing pipe server (possible reason: HLAIMAN APPLICATION IS NOT RUNNING!)");
//--- ok
   return(false);
  }

As can be seen from the code, the first initialization step covers an attempt to open a named pipe for connectivity with the Hlaiman application. If this attempt fails (e.g., when <hlaim.exe> is not running), the exit is performed with a negative status. At the second step (upon the successful completion of the first step and operating indicator mode), local and common folders of the terminal are searched for the required file name with the neural network data. The third step deals with the preparation of the code in ObjectPascal (Delphi) for the initialization directly in the Hlaiman application.

The text of the code is then moved to the source string. For convenience of formatting, it is broken down into substrings using '\n\r' and contains invocations of Hlaiman object properties and methods (see comments). As defined in the text, the object-based environment of the MetaTrader 5 Hlaiman plug-in represents tree architecture, with the object of the plug-in lying at the root.

The МetaТrader 5 terminal object is at the next level followed by Expert Advisor and symbol objects. In case of successful translation and execution of the source code passed via the named pipe, the returned Result value will contain the number of elements of the neural network input vector. As the code suggests, this value is used to initialize the pattern array and the method execution is completed with a positive status.

The other key methods of the CSignalHNN class are CalculateHNN, AddPattern and TeachHNN. The first one returns the result of the neural network calculation in the indicator mode. The other two methods are used in the teaching mode when collecting patterns and initiating the neural network teaching process, respectively.

The implementation of these methods in <SignalHNN.mqh> is as follows:

//+------------------------------------------------------------------+
//| Calculate HNN signal                                             |
//+------------------------------------------------------------------+
double CSignalHNN::CalculateHNN(void)
  {
   if(m_hnn==0 || m_hnn==INVALID_HANDLE) return(0.0);
   int num = 0;
   ulong siz = 0;
   double res=0.0;
   string source,result="";
   if(FillPattern(0)==true)
     {
      result=CON_START;
      for(int i=1; i<(ArraySize(pattern)-1); i++)
         result= result+DoubleToString(pattern[i])+CON_ADD;
      result = result + DoubleToString(pattern[ArraySize(pattern) - 1]) + CON_END;
      source = "unit CalcHNN; Interface " + result + " var i: integer; libr, term, exp, sym, lst: TObject;"
              " Implementation function main: double;\n\r" // Line #1
              " begin"
              " Result := 0.0;"
              " libr := Open('mt45.dll');\n\r" // Line #2
              " if (libr <> nil) then"
              " begin"
              " term := Open('"+hnn_path+"');\n\r" // Line #3
              " if (term <> nil) then"
              " begin"
              " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
              " if (exp <> nil) then"
              " begin"
              " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
              " if (sym <> nil) then"
              " begin"
              " lst := TStringList.Create;"
              " if (lst <> nil) then"
              " begin"
              " lst.Text := cons;"
              " if (lst.Count >= sym.NetInputs.Count) then"
              " begin"
              " for i := 0 to sym.NetInputs.Count - 1 do"
              " begin"
              " sym.NetInputs.Objects[i].NetValue := StrToFloat(lst[i]);\n\r" // Line #6
              //                    " sym.Log.Add('Input ' + IntToStr(i) + ' = ' + lst[i]);"              
              " end;"
              " sym.Computed := true;"
              " Result := sym.NetOutputs.Objects[0].NetValue;\n\r" // ret input Line #7
              " end;"
              " lst.Free;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToDouble(result);
        }
     } //else Print("fill pattern error!");
   return(res);
  }
//+------------------------------------------------------------------+
//| AddPattern                                                       |
//+------------------------------------------------------------------+
bool CSignalHNN::AddPattern(string name,int ptype)
  {
   int num=0;
   long res=0;
   ulong siz=0;
   string result,source,nam=name;
   if(m_hnn!=0 || m_hnn!=INVALID_HANDLE)
     {
      pattern[0]=ptype;
      result=CON_START;
      for(int i=0; i<(ArraySize(pattern)-1); i++)
         result= result+DoubleToString(pattern[i])+CON_ADD;
      result = result + DoubleToString(pattern[ArraySize(pattern) - 1]) + CON_END;
      source = "unit AddPatternHNN; Interface " + result + " Implementation function main: integer;"
              " var i: integer; out: double; onam: string;"
              " libr, term, exp, sym, ord, tck, lst: TObject;\n\r" // Line #1
              " begin"
              " Result := 0;"
              " libr := Open('mt45.dll');\n\r" // Line #2
              " if (libr <> nil) then"
              " begin"
              " term := Open('"+hnn_path+"');\n\r" // Line #3
              " if (term <> nil) then"
              " begin"
              " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
              " if (exp <> nil) then"
              " begin"
              " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
              " if (sym <> nil) then"
              " begin"
              " lst := TStringList.Create;"
              " if (lst <> nil) then"
              " begin"
              " lst.Text := cons;"
              " if (lst.Count >= (sym.TeachInput + sym.TeachOutput)) then"
              " begin"
              " out := StrToFloat(lst[0]);"
              " if(out >= 0) then onam := 'BUY-"+nam+"'"
              " else onam := 'SELL-"+nam+"';"
              " ord := sym.ObjectOfName(onam);"
              " if (ord = nil) then ord := sym.AddObject('TMT45Order');\n\r" // Line #6                    
              " if (ord <> nil) then"
              " begin"
              " if (ord.Name <> onam) then ord.Name := onam;\n\r" // Line #7
              " if (out >= 0) then ord.OrderType := 0 else ord.OrderType := 1;"
              " if (ord.NetOutput <> out) then ord.NetOutput := out;\n\r" // Line #8
              " for i := 1 to sym.TeachInput do"
              " begin"
              " if(i <= ord.Count) then tck := ord.Items[i - 1] else"
              " tck := ord.AddObject('TMT45Tick');\n\r" // Line #10                    
              " if (tck <> nil) then"
              " begin"
              " tck.x := i;"
              " tck.y := StrToFloat(lst[i]);\n\r" // Line #11
              " end;"
              " end;"
              " end;"
              " Result := sym.Count;\n\r" // ret input Line #12
              " end;"
              " lst.Free;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToInteger(result);
        }
     }
   return(res>0);
  }
//+------------------------------------------------------------------+
//| TeachHNN                                                         |
//+------------------------------------------------------------------+
bool CSignalHNN::TeachHNN(void)
  {
   int num=0;
   long res=0;
   ulong siz=0;
   string result,source;
   if(m_hnn!=0 || m_hnn!=INVALID_HANDLE)
     {
      source="unit TeachHNN; Interface const WAIT_TIM = 100; WAIT_CNT = 100;"
             "  var i: integer; libr, term, exp, sym: TObject;"
             " Implementation function main: integer;\n\r" // Line #1
             " begin"
             " Result := 0;"
             " libr := Open('mt45.dll');\n\r" // Line #2
             " if (libr <> nil) then"
             " begin"
             " term := Open('"+hnn_path+"');\n\r" // Line #3
             " if (term <> nil) then"
             " begin"
             " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
             " if (exp <> nil) then"
             " begin"
             " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
             " if (sym <> nil) then"
             " begin"
             " if (sym.Teached) then sym.Teached := false;\n\r" // Line #6
             " sym.Teached := true;\n\r" // Line #7
             " Result := sym.Count;\n\r" // ret input Line #8
             " end;"
             " end;"
             " end;"
             " end;"
             " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0)
        {// && (MQL5InfoInteger(MQL5_TESTER) || num < WAIT_TIMES)) {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToInteger(result);
        }
     }
   return(res>0);
  }

As can be seen from the code, the method body primarily consists of the source lines, whose text is arranged similarly to the texts considered above in the InitHNN method description. The only difference being that the object-based hierarchy of the plug-in has two more levels for the pattern representation - order and tick. Furthermore, the code contains additional object properties and methods. E.g. the start of the neural network calculation is flagged by the Computed flag of the 'symbol' object, while the Teached flag is used when initiating the teaching process.

The CalculateHNN method is also different from other methods in that the type of the 'main' value returned by the function in this case is 'double'. This value is the neural network output - the signal, whereby the BUY level lies in the range 0..1 and the SELL level is in the range 0..-1. This signal is used by the Expert Advisor in taking decisions regarding opening or closing of trading positions and is controlled by the Direction method. This method performs recalculation in case of the new bar and returns its value expressed as percentage.

//+------------------------------------------------------------------+
//| Check conditions for trading signals.                            |
//+------------------------------------------------------------------+
double CSignalHNN::Direction(void)
  {
   if( m_hnn == 0 || m_hnn == INVALID_HANDLE) return(EMPTY_VALUE);
//--- check new bar condition
   int cur_bar = Bars(hnn_sym, hnn_period);
   if (hnn_bar != cur_bar) {
//--- condition OK
      hnn_signal = CalculateHNN() * 100;
      hnn_bar = cur_bar;
   }
   return(hnn_signal);
  }

To set the signal response threshold of the Expert Advisor in respect of signals for opening and closing trading positions, you can use the following external variables:

  • input int    Signal_ThresholdOpen =10;      // Signal threshold value to open [0...100]
  • input int    Signal_ThresholdClose=10;      // Signal threshold value to close [0...100]

In practice, signal levels depend on the neural network teaching quality and intensity which, as a rule, can be assessed visually by monitoring the decrease dynamics of the computational error displayed in the indicator in the course of teaching.


Conclusions

Hlaiman EA Generator provides components and a transparent controlled object-based environment for the integration with MQL5, whereby:

  1. The MQL5 Wizard interface gets an additional type based on signal and pattern recognition, as well as the possibility of generating neural network EAs.
  2. In addition to the ability to quickly generate neural network EAs, you can also quickly adapt them to the changing market behavior and repeatedly teach them on different trading instruments and time frames.
  3. Due to the fact that the MQL5 Wizard can enable multiple signal modules, you can create complex multi-currency neural network EAs and/or compound indicator-based neural network EAs. They can also be combined with various additional filters, e.g. time filters.
  4. And finally, the neural network module in itself can be used as an additional filter to increase the efficiency of a ready-made Expert Advisor. This is possible due to the ability of a neural network to be taught using the visualization charts of test results of the original Expert Advisor.

The use of the script interpreter causing the integrated computing system to appear not very high performing can be considered as one of the disadvantages of the implementation provided above. First off, however, it should be noted that the script code interpretation, as well as the operation of the Hlaiman plug-in is asynchronous with EX5, i.e. we deal with task parallelization. Second, to increase the speed of time-consuming calculations, e.g. when dealing with large neural networks, MetaTrader 5 and Hlaiman can be run on different computers connected via named network pipes. Launching a trading terminal on a separate computer, you will not only gain in performance but you may also increase its security.

When put in perspective, we can look into development of Expert Advisors that can self-learn in the course of trading. At this point the easiest way to do this is by combining the code of the Expert Advisor with the teaching script code as both of them use the same CSignalHNN class that provides the required functionality. This material can become the subject of the follow-through article or form the basis of a completely new one, if it appears to be of interest.

The demo version of Hlaiman EA Generator can be downloaded here.

Attachments:

  • SignalHNN.mqh - signal module "MQL5\Include\Expert\Signal\".
  • TeachHNN.mq5 - teaching script "MQL5\Scripts\".
  • SampleHNN.mq5 - Expert Advisor based on the trading signal module 'Signals of patterns Hlaiman Neural Network EA generator' and generated using the MQL5 Wizard.

Translated from Russian by MetaQuotes Software Corp.
Original article: https://www.mql5.com/ru/articles/706

Attached files |
signalhnn.mqh (23.88 KB)
teachhnn.mq5 (9.67 KB)
samplehnn.mq5 (6.35 KB)
Last comments | Go to discussion (18)
Joao Henriques
Joao Henriques | 21 Oct 2014 at 03:01

Congratulations for this awsome article!

But i have a problem on testing it on the strategy tester since it dispalys only errors "on init fail" and i cannot optimize it.

What am i doing wrong? 

Regards 

Ivan Negreshniy
Ivan Negreshniy | 31 Dec 2014 at 12:17

As mentioned in the article, information on neural network learning is stored separately from the original EAs MQL code in the appropriate data files that are downloaded advisers, when you start them in the strategy tester or on a chart.

Now Hlaiman EA Generator has the ability to convert any of such data files of neural networks in the source code of two separate MQL4 and MQL5 indicators that after compilation can be used on their own, such as manual trading in MT4, MT5 terminals or creating other EAs. 

Especially it can be important for users MT4, where as yet there is no option to directly run indicator in the tester.

Appearance and settings generated indicators are the same as in previously published in the Market, free test indicators, on this site.




Ivan Negreshniy
Ivan Negreshniy | 27 Jan 2015 at 09:31
Now Hlaiman EA Genegator allows you to create advisors with integrated indicators, in Market exhibited free Hlaiman Multi Neural EA. https://www.mql5.com/en/market/product/6077
Ivan Negreshniy
Ivan Negreshniy | 17 Aug 2015 at 13:06

Now, with Hlaiman EA Generator can try to improve the efficiency of the trade of other ready EAs if they are presented in the source code and are based on the movement of prices, such as technical analysis.

To do this, directly in the source code of the adviser added neural network filter that can be initially included in the training run advisor in the tester, and can then be put into operation.

In EA settings added variables to control, filter mode, and the necessary degree of filtration.

Free Sample advisor on example Moving Average, can be downloaded from the Market, where you can also see the video, processes, training and testing.
https://www.mql5.com/en/market/product/8460

Ivan Negreshniy
Ivan Negreshniy | 18 Aug 2015 at 12:03

Now, with Hlaiman EA Generator can try to improve the efficiency of the trade of other ready EAs if they are presented in the source code and are based on the movement of prices, such as technical analysis. To do this, directly in the source code of the adviser added neural network filter that can be initially included in the training run advisor in the tester, and can then be put into operation. In EA settings added variables to control, filter mode, and the necessary degree of filtration.

Free Sample advisor on example Moving Average, can be downloaded from the Market, where you can also see the video, processes, training and testing.
https://www.mql5.com/en/market/product/8460

In this example, the training of the neural network filter executed on the trading results of the original Moving Average for 2014, the latest EA update - March 2015.

In order to test the effectiveness of the filter I ran adviser in the tester for the entire period since the publication, ie from April to August the current date.

The first run made with a disabled filter (corresponding to the original Moving Average), and the second with the enabled filter (see. The marked variable UseNeuro = true), here are the results:

Thus, we can see that training in the past year, the neural network filter, over time, has remained effective and can increase the productivity of trade almost doubled.

Step on New Rails: Custom Indicators in MQL5 Step on New Rails: Custom Indicators in MQL5

I will not list all of the new possibilities and features of the new terminal and language. They are numerous, and some novelties are worth the discussion in a separate article. Also there is no code here, written with object-oriented programming, it is a too serous topic to be simply mentioned in a context as additional advantages for developers. In this article we will consider the indicators, their structure, drawing, types and their programming details, as compared to MQL4. I hope that this article will be useful both for beginners and experienced developers, maybe some of them will find something new.

Here Comes the New MetaTrader 5 and MQL5 Here Comes the New MetaTrader 5 and MQL5

This is just a brief review of MetaTrader 5. I can't describe all the system's new features for such a short time period - the testing started on 2009.09.09. This is a symbolical date, and I am sure it will be a lucky number. A few days have passed since I got the beta version of the MetaTrader 5 terminal and MQL5. I haven't managed to try all its features, but I am already impressed.

Using text files for storing input parameters of Expert Advisors, indicators and scripts Using text files for storing input parameters of Expert Advisors, indicators and scripts

The article describes the application of text files for storing dynamic objects, arrays and other variables used as properties of Expert Advisors, indicators and scripts. The files serve as a convenient addition to the functionality of standard tools offered by MQL languages.

How to create an indicator of non-standard charts for MetaTrader Market How to create an indicator of non-standard charts for MetaTrader Market

Through offline charts, programming in MQL4, and reasonable willingness, you can get a variety of chart types: "Point & Figure", "Renko", "Kagi", "Range bars", equivolume charts, etc. In this article, we will show how this can be achieved without using DLL, and therefore such "two-for-one" indicators can be published and purchased from the Market.