Self-learning the MQL5 language from scratch - page 58

 
MrBrooklin:

I created a standard template. It's where I started writing the code, and here I've started to post those fragments that have already been written. I haven't thought about the algorithm framework with my own functions, thanks for the tip! Also thanks for the tip about the netting account!


There's such a technique from literacy-programming - it allows you to write very quickly and intelligibly.

In general, in literary style, write in the comments what you will do (just the main direct sequence)

// тралим стоп-лосс единственного ордера по сигналу от тиков

// прим.) трал - подтягиваем стоп-лосс следом за ценой, 

void TrallOnTick() {

// берём рыночный ордер (для 5-ки позицию)

        // смотрим сколько пунктов от текущей цены до стоп-лосс

        // если больше чем требуемая дистанция

        // переносим стоп-лосс

}

Basically all. Further after each comment you write a code of 3-5 (a little bit in general) lines. Your whole function from start to finish should fit in the screen you see. If you get more, it means that fragments must be separated into separate functions/methods.

When such an elementary thing starts to work in the tester, then you can generalize, add conditions from real life, step change for example or frequency, take into account market conditions, there is no limit to perfection...

 
Maxim Kuznetsov:

abstract, there is a literacy-programming technique that allows you to write very quickly and clearly.

In general, in literary style, write in the comments what you will do (only the main direct sequence)

// тралим стоп-лосс единственного ордера по сигналу от тиков

// прим.) трал - подтягиваем стоп-лосс следом за ценой, 

void TrallOnTick() {

// берём рыночный ордер (для 5-ки позицию)

        // смотрим сколько пунктов от текущей цены до стоп-лосс

        // если больше чем требуемая дистанция

        // переносим стоп-лосс

}

Basically all. Further after each comment you write a code of 3-5 (a little bit in general) lines. Your whole function from start to finish should fit in the screen you see. If you get more, it means that fragments must be separated into separate functions/methods.

When such an elementary thing starts to work in the tester, you can generalize, add conditions from real life, step change or frequency for example, take market conditions into account, there is no limit to perfection...

Hello Maxim! You are very helpful with your tip! I am sitting here wondering how to fill a standard EA template.

Regards, Vladimir.

 
MrBrooklin:

Dear programming experts!

Please explain two questions:

  1. First question about Magic Number - is it created in input parameters only for pending orders and open positions (or only for open positions?), or for the EA itself it can be created too? If the answer is "yes," for what purpose should this be done. I have really got confused with this question and do not have a good answer.
  2. The second question about Magic Number - if there is more than one open position in the current chart, then it is possible to apply such an input parameter to determine each position:

Perhaps I have a wrong understanding of Magic Number application in programming at all.

Regards, Vladimir.

When an order is accepted for execution all its characteristics (symbol, time, order type, ticket) are assigned by the terminal (requested by user and assigned by terminal) and not by user and the same with position, position stores information about its orders but there may be a lot of them. And the magic number is a user identifier. Quote:

When we create a new pending request, we need to mark it somehow - so the program can know that this particular order was placed by NAMI on this particular pending request - that is, we need to uniquely identify and associate an order or position with a particular pending request.

NAMI is missing in the meaning. And then Artem puts the classification of orders into the Magik number. Why not, the first 2 digits indicate something, e.g. the order type, the next 4 digits indicate the date of the order.

Regarding the algorithm of something. Initially define the initial conditions. There are orders on our symbol and we don't take them into account or we take them into account. Without initial conditions rework when creating the algorithm, and even more so the code can be eternal)

 
Maxim Kuznetsov:

abstract, there is a literacy-programming technique that allows you to write very quickly and intelligibly.

In general, literacy-programming style, write in the comments what you will do (just the main direct sequence) ...

... Basically all. Next, after each comment you write code 3-5 (not much in general) lines. The whole function from the beginning to the end should fit into the screen you see. If you get more, it means that you have to separate fragments into separate functions/methods.

Maxim, please check if I got your hint right or is there something else I need to add? I mean the test part, because I haven't written the codes yet.

Regards, Vladimir.

//+------------------------------------------------------------------+
//|                                                Trailing_Stop.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
// установим входные параметры: "Уровень перестановки Stop Loss в безубыток" и "Шаг трейлинга"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
//    тралим стоп-лосс единственной открытой позиции по сигналу от тиков
void OnTick()
  {
//---

// 1. берём позицию Buy
// 2. смотрим сколько пунктов прошла текущая цена в нужном направлении от той цены, по которой открылась позиция:
//    - если количество пунктов больше, чем задано во входном параметре "Уровень перестановки Stop Loss в безубыток"
//    - тогда переносим стоп-лосс на уровень цены, по которой открылась эта позиция
// 3. смотрим сколько пунктов прошла текущая цена в нужном направлении от той цены, при которой мы перенесли 
//    стоп-лосс на уровень цены открытия позиции:
//    - если количество пунктов больше, чем задано во входном параметре "Шаг трейлинга"
//    - тогда переносим стоп-лосс на количество пунктов, укзанных во входном параметре "Шаг трейлинга"
// 4. берём позицию Sell и выполняем все те же действия, описанные в пунктах 2 и 3
  }
//+------------------------------------------------------------------+
 
MrBrooklin:

Maxim, please see if I got your hint right, or is there anything else I need to add? I mean the test part, apart from the codes.

Sincerely, Vladimir.

Initial conditions. We calculate that there is a position on our symbol and we see it on the chart.

If we have a position, it is only one, either buy or sell. Therefore we start by searching for positions on our symbol. Request / get characteristics. Determination of position type - buy or sell. And so on through the text.

 
Valeriy Yastremskiy:

When an order is accepted for execution all its characteristics (symbol, time of issue, order type, ticket) are assigned by the terminal (requested by the user and assigned by the terminal), not by the user, and the same with the position, the position stores information about its orders, but there can be many of them. And the magic number is a user identifier. Quote:

When we create a new pending request, we need to mark it somehow - so the program can know that this particular order was placed by NAMI on this particular pending request - that is, we need to uniquely identify and associate an order or position with a particular pending request.

NAMI is missing in the meaning. And then Artem puts the classification of orders into the Magik number. Why not, the first 2 digits indicate something, e.g. the order type, the next 4 digits indicate the date of the order.

Regarding the algorithm of something. Initially define the initial conditions. There are orders on our symbol and we don't take them into account or we take them into account. Without the initial conditions rework when creating the algorithm, and even more so, the code can take forever)

Thank you, Valeriy, for the detailed reply. A lot of things have become clearer. I feel the same way about the algorithm, but Vassily has already explained why we don't need Magic Number in this EA.

Regards, Vladimir

 
MrBrooklin:

Thank you, Valery, for the detailed reply. It cleared up a lot. I have the same opinion on the algorithm, but Vasiliy has already explained why we don't need Magic Number in this EA.

Sincerely, Vladimir.

We opened a chart and there is a position on the chart symbol, we do not know what it is and we want to open it at breakeven and then trawl SL to reduce losses in case the price reverses.

 

With the corrections from Valery, the EA template with comments has taken on a new look.

Regards, Vladimir.

//+------------------------------------------------------------------+
//|                                                Trailing_Stop.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
// установим входные параметры для "Уровня перестановки Stop Loss в безубыток" и "Шага трейлинга"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
//    тралим стоп-лосс единственной открытой позиции по сигналу от тиков
void OnTick()
  {
//---
// 1. ищем все позиции на текущем символе:
//    - отправляем запрос на сервер и получаем характеристики открытых позиций
//    - определяем тип открытой позиции - Buy или Sell 
// 2. берём позицию Buy
// 3. смотрим сколько пунктов прошла текущая цена в нужном направлении от той цены, по которой открылась позиция:
//    - если количество пунктов больше, чем задано во входном параметре "Уровень перестановки Stop Loss в безубыток"
//    - тогда переносим стоп-лосс на уровень цены, по которой открылась эта позиция
// 4. смотрим сколько пунктов прошла текущая цена в нужном направлении от той цены, при которой мы перенесли 
//    стоп-лосс на уровень цены открытия позиции:
//    - если количество пунктов больше, чем задано во входном параметре "Шаг трейлинга"
//    - тогда переносим стоп-лосс на количество пунктов, укзанных во входном параметре "Шаг трейлинга"
// 5. берём позицию Sell и выполняем все те же действия, описанные в пунктах 2 и 3
  }
//+------------------------------------------------------------------+
 

Vladimir, you don't have to harness it for long. Let's get into the action. I've written a template of the desired trailing for you:

//+------------------------------------------------------------------+
//|                                                  TestingTral.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MrBrooklin"
#property link      "http://www.mql5.com"
#property version   "1.00"
input double BreakevenValue = 100.0; // Величина безубытка, в пунктах инструмента
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //-- Выбираем позиции по текущему символу. Если позиции нет выбирать нечего - выходим
   if(!PositionSelect(Symbol()))
      return;
   //-- Стоп-лосс длинной позиции переставляем в безубыток и тралим его
   if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
   {
      SetBreakevenForBuyPosition();
      TrailingStopLossForBuyPosition();
   }
   //-- Стоп-лосс короткой позиции переставляем в безубыток и тралим его
   else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
   {
      SetBreakevenForSellPosition();
      TrailingStopLossForSellPosition();
   }
  }
//+------------------------------------------------------------------+
//| Устанавливает sl позиции BUY в безубыток                         |
//+------------------------------------------------------------------+
void SetBreakevenForBuyPosition()
  {
   ;   
  }
//+------------------------------------------------------------------+
//| Тралит стоп-лосс позиции BUY вслед за ценой                      |
//+------------------------------------------------------------------+
void TrailingStopLossForBuyPosition()
  {
   ;   
  }
//+------------------------------------------------------------------+
//| Устанавливает sl позиции SELL в безубыток                        |
//+------------------------------------------------------------------+
void SetBreakevenForSellPosition()
  {
   ;   
  }
//+------------------------------------------------------------------+
//| Тралит стоп-лосс позиции BUY вслед за ценой                      |
//+------------------------------------------------------------------+
void TrailingStopLossForSellPosition()
  {
   ;   
  }
//+------------------------------------------------------------------+

All you need to do is to fill the functions with the logic corresponding to their names. As you can see the template is elementary. And structurally similar to the ToR.

Note that this code compiles, that is, from the compiler's point of view, it's correct. Always strive for this state: i.e. make small changes during development, so that after making them, the code can compile. Also strive to have the compiler report "0 error, o warnings". It is clear that you cannot run the program with errors, but the compiler's warnings must be perceived as our Father's Prayer: if there is a warning it must be corrected. This template is made with "0 error, o warnings" - save this status until the end of development.

Once we have understood the logic and we have understood the compiler, all we need to do is to equip the functions with the logic we need.

The second parameter, the trail value, will be moved to the next version for now. It will require additional calculations. That is why it is not present in this template. The trawl will be adjusted every tick.

 
Vasiliy Sokolov:

Vladimir, you don't have to harness it for long. Let's get into the action. I've written a template of the desired trailing for you:

All you need to do is to fill the functions with the logic corresponding to their names. As you can see the template is elementary. And structurally similar to the ToR.

Note that this code compiles, that is, from the compiler's point of view, it's correct. Always strive for this state: i.e. make small changes during development, so that after making them, the code can compile. Also strive to have the compiler report "0 error, o warnings". It is clear that you cannot run the program with errors, but the compiler's warnings must be perceived as our Father's Prayer: if there is a warning it must be corrected. This template is made with "0 error, o warnings" - save this status until the end of development.

Once we have understood the logic and we have understood the compiler, all we need to do is to equip the functions with the necessary logic.

The second parameter, the trail value, will be moved to the next version for now. It will require additional calculations. That is why it is not present in this template. The trawl will be updated every tick.

Vasiliy, of course I want to thank you for doing so much work, but it doesn't help me to understand where these functions and operators come from and, most importantly, why they are there. It would have been more correct to get to the point of writing that code, which you've suggested to me. I really wanted to get to this point myself and now I want to.

I understand that you, like many others, are tired of my constantly spelling out all the lines of code and trampling on the spot, but the problem is that I still don't understand how everything is built, from the algorithm to code writing. I must add lack of knowledge of English to the problem, because I have to copy and paste almost all compiler error and warning messages, and other English words into Google Translator. By the way, if anyone tried to run those micro, even nano-codes I posted in this thread, they all passed compilation with "0 error, 0 warnings".

Now I need some time to realize, or rather to understand why these functions and operators appeared. So, in short, it's a silent horror. And I am a bad student when I don't understand elementary things.

Thank you and all other programmers for tolerating my slow-wittedness. Although I realize that your patience is not boundless.

Sincerely, Vladimir.

Reason: