programming
Now you are reading
MQL Practically. Algo Trader cz. I [Programming course]
0

MQL Practically. Algo Trader cz. I [Programming course]

created Radek SzafronJuly 4 2019

In today's episode, we will begin working on software that will allow you to take advantage of the opportunities offered by algorithmic trading while maintaining maximum control over the course of events. We will focus on ideas that allow you to engage in real trading by maximizing the intuitive operation and flexibility of the function. In the software we use an interface, the form of which is considered by many to be a standard in the day trading industry and is often called price ladder

algotrader

Algo Trader - Interface

Project plan

We will divide the work into several stages, because apart from the extensive order handling, Algo Trader will allow you to run algorithms that will automatically manage the position according to various combinations that you can create depending on the situation you will encounter on the market.

In today's part, we will take the first step into the world of object-oriented programming and we will launch an elementary part of our project related to the interface and operation of basic operations.

In the next episodes we will start work on the first algorithms. At the beginning, we will create a GTP algorithm that will ensure that the position closes with the expected profit regardless of how many orders are made. Next, we will create the algorithm OOO (One Opens the Other, so exactly, it has not been yet), and finally an algorithm enabling scalping during the presentation of important macro data. Together with the algorithms, here and there, we will add some nice gadget.

Technical background

You will find the package with the files you need for today by following this link:

Using the software means accepting the license attached to the file set.

For the software to work properly, you need a Microsoft NET Framework version of min. 4.6.1 Runtime, which you can download here:

Object-oriented programming

We will create our software using object programming, a programming method that allows for logical ordering of algorithm fragments in the so-called objects whose task is to perform separate functions and communicate with other objects in order to implement the task of the program as a whole. To go further, we will need to understand what objects are in practice and how they are created. For this purpose, take a look at the following article in Wikibooks, which - based on the example of the C ++ language on which MQL4 is based - allows you to understand the basics.

READ THE ARTICLE

First class

As you can see, everything revolves around the keyword class. It lets you define an object that you can then create with a keyword new. Open the file containing the definition of one of the classes we will use today, the file ChartOperations.mqhwhich you will find in the catalog MQL4 \ Include \ AlgoTrader_v10.

class cChartOperations { public: cChartOperations(int width, int height) { // ... } void OnClick(int x, int y) { // ... } void OnChartChange() { // ... } private: int Chart_width; int Chart_height; uint Last_click; int Last_click_x, Last_click_y; bool IsDoubleClick(int x, int y) { // ... } };

 

 

Each class has a constructor, which in practice is a function that is automatically called when the object is created. The constructor bears the same name as the object and can take parameters. In our code snippet above, we create a constructor as follows:

cChartOperations(int width, int height) { }

 

After creating the constructor, we can define the components of the class, ie functions and variables. They are defined exactly as in the case of ordinary functions and variables with the difference that in the body of the class. Pay attention to your keywords public: and private:. All functions and variables after the word public: will be available for functions that are found in other parts of the software, e.g. in the API function OnTick () or other objects. Private however, it informs the compiler that the elements that are defined in this part are strictly confidential and that nobody, apart from a given object, naturally has access to them.

Applications of objects

What creates objects so useful? Among other things, it is that once defined object can be created in any number of copies and depending on the parameters passed to them, they will behave differently, but in a way that we are able to analyze and control. In addition, the objects allow for the legible organization of the code by dividing the components of the algorithm into extracted elements, and a properly designed object can be used in a completely different software, which allows you to effectively create complex applications.


expert advisors


We start the first object

Let's move to the main file of our software, file AlgoTrader_v10.mq4which you will find in the catalog MQL4 \ Experts \.

Let's take a look at the API definition below OnInit ():

cChartOperations* ChartOperations = NULL; int OnInit() { // (...) int chart_width = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); int chart_height = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); ChartOperations = new cChartOperations(chart_width, chart_height); return(INIT_SUCCEEDED); }

Pointer

In the part of the file responsible for the definition of global variables using a code fragment ...

cChartOperations* ChartOperations = NULL;

 

... we create the so-called pointer ie, a pointer that will contain an address to a place in the computer's memory, where our object will be created later. Using the pointer we will be able to refer to the object and call its functions. pointers we define similarly to variables, the first element of notation is the type of object, then we place the asterisk * , after which we set a unique name for the object, which we will later use for references. To ours pointer we assign a variable NULL, which says that at the current stage it does not indicate any object yet.

Constructor

Later in the code, in the body of the function OnInit () we create the right object using a keyword new.

ChartOperations = new cChartOperations(chart_width, chart_height);

 

Po new we call the constructor of the object, which in our case takes two variables informing the object about the dimensions of our chart, because we need it to properly place our interface. The called constructor forwards the address of the newly created object in the computer's memory to ours pointer named ChartOperations.

Destroyer

Objects are a special type of data, which if we create it, we must ensure that it is finally removed from the computer's memory. All this so that in front of your laptop you do not have to be a huge server that gathers previously created data that is no longer needed to anyone.

In order to delete objects, we use the keyword delete, after which we place our name poinera indicating which object we mean. We remove our object only in the API function OnDeinit (...)because we need it throughout the entire application life cycle, until the software is turned off.

void OnDeinit(const int reason) { // (...) delete ChartOperations; }

Work with objects

Let's see now how we can use our created object for the needs of our application. For this purpose in the body of the class cChartOperations We defined several functions. Let's look at one of them:

void OnClick(int x, int y) { if(IsDoubleClick(x, y)) GoToPrice(x, y); }

 

Function OnClick (...) we need it to communicate to our interface what price levels are currently interesting to us. By double-clicking on the graph, the algorithm will set our price ladder in the indicated place. In order for our function to work, we need to detect the moment when we click on the chart, and here the API function helps OnChartEvent (...)

void OnChartEvent(const int id, const long & lparam, const double & dparam, const string & spar) { // (...) if(id == CHARTEVENT_CLICK) ChartOperations.OnClick((int)lParam (int)dparam); }

 

The above code snippet recognizes the moment when the user clicks on the graph and then calls the function that is inside our previously created object. Calling a function consists in placing a dot after our name pointer to the object, and then passing the name of the function we are interested in along with the necessary parameters, which in our case indicate the x and y coordinates of the place in the chart in which the click was made.

First effects

The procedures created by us have launched the first functionality of the software, which we can test by compiling our program and clicking on a different chart. Below you will find a graphic that presents a few functions that allow you to manipulate the price levels displayed in our graphical interface.

programming mql

Algo Trader - Mouse and price levels

Second class

Since you have been promoted to the second grade and our clicking does not go to waste, we will design a second facility that will allow you to place orders from the level of our ladder. For this purpose, we have prepared the appropriate class, which you will find in the file MQL4 \ Include \ AlgoTrader_v10 \ OrderOperations.mqh

class cOrderOperations { public: cOrderOperations(int position_id) { Position_id = position_id; } void OnTimer200ms() { ProcessOrderRequests(); } private: int Position_id; void ProcessOrderRequests() { sOrderRequest request = ReadOrderRequest(); if(request.Request_id <= 0) return; if(request.Order_symbol != Symbol() || request.Position_id != Position_id) { request.Request_status = ORDER_REQUEST_STATUS_FAILED; request.Request_error = ORDER_REQUEST_ERROR_WRONG_POSITION; return; } if(OrderSend(request.Order_symbol, request.Order_type, request.Order_volume, request.Order_price, 0, 0, 0, request.Order_comment, request.Position_id) > 0) { request.Request_status = ORDER_REQUEST_STATUS_COMPLETED; } else { request.Request_status = ORDER_REQUEST_STATUS_FAILED; request.Request_error = _LastError; } UpdateOrderRequest(request); } };

In the above code you can see the full definition of the object cOrderOperationswhich will be used to handle orders that we will place on our price ladder. Pay attention to the function ProcessOrderRequests ()in which our program communicates with the library dll using the function ReadOrderRequest ().

structures

Function ReadOrderRequest () as a result of its action returns a type structure sOrderRequest, which is a set of data defined by us with an order placed via the interface.

void ProcessOrderRequests() { sOrderRequest request = ReadOrderRequest(); // (...) }

Structures are younger sisters of classes that allow you to create a block of data containing many variables. This allows logical ordering of information that pertains to a given issue. In our case, the structure collects data about the order sent by our graphic interface, such as the opening price or volume. We define a structure by preceding its name with a keyword structand then we set a list of the data we need.

struct sOrderRequest { int request_id; int Position_id; int ORDER_TYPE; double Order_volume; double Order_price; double Order_range; string Order_symbol; string Order_comment; int Request_status; int Request_error; };

 

The above definition can be found in the file MQL4 \ Include \ AlgoTrader_v10 \ Definitions.mqh.

We use structures similarly to variables, in the first step we need to create it by specifying the type of structure, and then give it a unique name, which we can refer to later. In the following example, we create a type structure sOrderRequest and we give it a unique name requestand then we assign data from our interface using functions ReadOrderRequest ().

void ProcessOrderRequests() { sOrderRequest request = ReadOrderRequest(); // (...) }

 

Access to data stored in the structure is analogous to using variables, because in practice the structure is only a set of variables hidden under a common identifier. To read or write data in the structure it is enough after the name we gave it to put a dot, and then indicate the name of the variable that interests us. In the following fragment of the code, we read the data stored in the structure to send the order and then save the information about the result of the operation.

if(OrderSend(request.Order_symbol, request.Order_type, request.Order_volume, request.Order_price, 0, 0, 0, request.Order_comment, request.Position_id) > 0) { request.Request_status = ORDER_REQUEST_STATUS_COMPLETED; }

Execution of orders

In order for our software to submit orders, we must implement the object created on the basis of the class cOrderOperations. Because we will need the object from the launch of our program, we create it in the API function OnInit ().

input int Position_id = 8821; // The unique identifier of the item cOrderOperations* OrderOperations = NULL; int OnInit() { EventSetMillisecondTimer(200); // (...) OrderOperations = new cOrderOperations(Position_id); return(INIT_SUCCEEDED); }

 

In the constructor cOrderOperations we place a variable Position_id, which is part of the settings of our application available in the default MetaTrader platform window. The identifier allows our software to recognize its own orders so that there are no confusion with orders from other sources.

We also launched the code above timer with the 200 ms interval, because our object should periodically check if the interface sends information about the incoming order.

void OnTimer() { // (...) OrderOperations.OnTimer200ms(); }

 

The function of the object OnTimer200ms () will call a function ProcessOrderRequests ()who will place the order when he receives the appropriate data from the interface.

class cOrderOperations { public: cOrderOperations(int position_id) { Position_id = position_id; } void OnTimer200ms() { ProcessOrderRequests(); } // (...) };

effects

Our software can already communicate with the graphical interface and we can do what we like to do the most, that is, to compile the algorithm and submit a new order. To help you get started the first few steps below you will find some tips that illustrate what functions are hidden under different keys.

Volume control

forex trading volume

Algo Trader - Volume handling

Types of orders

algo trading

Algo Trader - Order handling

Summation

That's all for today, but it's just the beginning of the adventure with Algo Trader. In the next episode, we will move on to the implementation of advanced functions related to algorithm support. Algo Trader will be created together with you and we will be grateful for any ideas and comments that may make it better for you. We'd love to hear from you at biuro@expertadvisors.pl .

What do you think?
I like it
70%
Interesting
20%
Heh ...
10%
Shock!
0%
I do not like
0%
Detriment
0%
About the Author
Radek Szafron
The author of the publication is Radek Szafron, owner of the Expert Advisors company, which for many years has been supporting investors by providing technologies dedicated to the FOREX market. The author is a graduate of the Warsaw School of Economics with the specialization "Financial markets" and a programmer with almost 20 summer experience. The company implements designs of algorithms and applications written in all languages ​​from the "C" family, including popular platforms Meta Trader 4 and 5. Expert Advisors can be found at www.expertadvisors.pl.