Automatically initialise and reinitialise the EA from a file

 
Task: to restore the EA environment (position data, counters, etc.) after reinitialisation, reboot in case of a system crash, etc.

Solution: we save each change in the EA's dynamic variables to a file. During OnInit(), all this stuff is loaded back into the file.

However, the past state of the variables cannot be loaded from the file if:
  • The file structure has changed (different version, new build of the Expert Advisor). It is elementary to check, no problem.
  • The bot glitched last time. Let's say it crashed on a stopout or hung or went over the error limit, then there could be variables in the file that cause an error immediately. This is partly very easy to check (error limit to consider, critical error record...), but it's not a complete solution.
  • The file is just too "dusty". Suppose last time EA was uploaded X days ago or even today, but information in it is already out of date. How to check it - fudge knows.

Now I have done so: analyze the cause of OnDeinit(), if the program is closed, then I delete the global terminal (like a flag of re-initialization).

When there is no this flag during OnInit(), I have to ask user each time with dumb messaging box "restore variables from file?".

This is an insanely stupid and inconvenient way!


Question: how to fully automate such a solution?

How can you tell when a file can't be uploaded and when it can be downloaded?

At least reduce call of this messaging box to minimum.

 

MQL4 or MQL5 ?

IfMQL5, then:

In OnInit() check:

1. Position

if ( PositionSelect(_Symbol) )
{
}
else
{
}

2) Orders:

(if something goes wrong, I simply delete all orders without checking where they are coming from. )

//+------------------------------------------------------------------+
//| Expert Remove orders function                                    |
//+------------------------------------------------------------------+
void RemoveOrders()
{
  int orders_total = OrdersTotal();
//---  
  if ( orders_total > 0 )
  {
    for ( int i = ( orders_total - 1 ); i >= 0; i-- )
    {
      ulong temp_order_ticket = OrderGetTicket( i );
      
      if ( OrderSelect( temp_order_ticket ) )
      {
        string temp_symbol = OrderGetString( ORDER_SYMBOL );
        
        if ( ( temp_symbol == sec_symbol ) || ( temp_symbol == _Symbol ) )
        {
          RemoveOldOrder( temp_order_ticket );
        }
      }
    }
  }
}

3. Global variables of the terminal:

  if ( !GlobalVariableCheck( "trans_count" ) )
  {
    datetime a_time = GlobalVariableSet( "trans_count", 0 );
    
    if ( ulong( a_time ) == 0 )
    {
      MessageBox( "Глобальная переменная терминала 'Счётчик транзакций' не создана!", "Ошибка", MB_OK | MB_ICONHAND );
      return( INIT_FAILED );
    }
  }

4. Variables to be saved

a) Loading:

//+------------------------------------------------------------------+
//| Expert Load setings function                                     |
//+------------------------------------------------------------------+
void LoadSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    file_handle = FileOpen( file_name, FILE_READ|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      e_high = FileReadLong( file_handle );
      a_profit = FileReadLong( file_handle );
      e_low = FileReadLong( file_handle );
      ord_delta_high = FileReadLong( file_handle );
      ord_delta_low = FileReadLong( file_handle );
      order_delta = FileReadLong( file_handle );
      exit_delta = FileReadLong( file_handle );
      FileClose( file_handle );
    }
  } 
}

b) Saving ( OnDeInit() )

//+------------------------------------------------------------------+
//| Expert Save settings function                                    |
//+------------------------------------------------------------------+
void SaveSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
  bool file_found = true;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    if ( FileDelete( file_name, 0 ) ) file_found = false;
  }
  else
  {
    file_found = false;
  }
//---
  if ( !file_found )
  {
    file_handle = FileOpen( file_name, FILE_WRITE|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      FileWriteLong( file_handle, e_high );
      FileWriteLong( file_handle, a_profit );
      FileWriteLong( file_handle, e_low );
      FileWriteLong( file_handle, ord_delta_high );
      FileWriteLong( file_handle, ord_delta_low );
      FileWriteLong( file_handle, order_delta );
      FileWriteLong( file_handle, exit_delta );
      FileClose( file_handle );
    }
  } 
}
 
Fry_Антон:
The task: to restore the environment of the EA (position data, counters, etc.) after reinitialisation, rebooting in case of system failure, etc.

The counter question is Why?

Imho, restoring the environment from a file is always suicidal in the long run. When restarting, you should always recalculate your data based on the MetaTrader trading environment.

 
Fry_Антон:
Task: Restore the EA environment (position data, counters, etc.) after reinitialisation, reboot in case of system failure, etc.
Recalculating
 
Vasiliy Sokolov:

The counter question is Why?

Imho, restoring the environment from a file is always suicidal in the long run. You should always recalculate your data based on the MetaTrader trading environment when restarting.

Features of the futures market.

Not everything can be recalculated. Of course I update what I can from the environment, but... Well, here is an example:

On clearing a position and orders are closed/open. The terminal locks the trade and deletes the orders for the day (and the orders are prohibited by the broker until cancelled). I have to create new orders.

And I need the initial price of opening a position, the initial time of setting a position and orders.

Thus, I have to keep my own accounting of such parameters.

There are also counters of requests per second/minute/hour/day, counters of non-fatal erroneous actions, etc. etc.

I would gladly give up the file! If it were real. =(

There is a situation like this: terminal crashed (today's builds are stable, and before it was always like this, and not the fact that there will always be only stable releases).

After crash terminal: quick reboot and autorun - restore from file and everything works.

Works very stable, because I always save initialization file to OnTrade() event (with timer for a second or two, not to torment the disk).


So for me the question is very relevant: how not to load variables from a file which is obsolete or dangerous to load?

 
Михаил:

MQL4 or MQL5 ?

If it isMQL5, then:

In OnInit() check:

1. Position

2) Orders:

(if something goes wrong, I simply delete all orders without checking where they are coming from. )

3. Global variables of the terminal:

4. Variables to be saved

a) Loading:

b) Saving ( OnDeInit() )

Made it almost like this. But I save the file to OnTrade() with a timer.

I also have a shitload of different traits and other variables, and the code is constantly evolving, so it was very inconvenient to store them one by one.

I created a basic structure that holds everything I need for the file (except some string values).

I've named it with one letter, so the code is quite short (b.volume is almost like volume). And it's convenient to save the whole structure at once with operator =.

 
Fry_Антон:

...

Question: how to fully automate such a solution?

...

A fundamentally different approach to EA programming.

 
Dmitry Fedoseev:

A fundamentally different approach to EA programming.

Expand the answer to a reasonable useful thought and I would be grateful to you.

What are the basic principles on the basis of which EA code turns out "better"?

 
Fry_Антон:

Expand the answer to a reasonable useful thought and I would appreciate it.

What are the basic principles that make the EA code "better"?

It has already been written here - recalculate everything again. I.e. analyze the situation with orders. Whether some data is stored in files, or some other way (maybe in global variables), is not of fundamental importance. The main point is that if some data is needed, it is stored in binding to the order tickets, and in this case there is no problem with outdated data - we have order - we have data, no order - we have no data. There may be data not tied to a specific order, but we have to think about each case and it is a solvable problem.

Clearing is really the most complicated problem. But it is not a problem of long-term data storage (or its obsolescence), we can store data in simple variables in the Expert Advisor (a bit risky, but only for 5 minutes). The difficulty here is how to deal with it later. We can create a group of global terminal variables for each order and store the opening price in them. Then, when the unmarked orders appear (or at the opening of a new day), we look at the last closed orders in the history, match them according to those features that can be used (for example, lot), and reset all global variables from the closed order to the new order.

 

Anton!

You are getting too "worked up" about this problem.

It is clear that you want to properly restore the work of the expert after the emergency

situation. I, too, racked my brains at first.

But then decided that such situations are extremely rare

(from my own experience of semi-annual MT5 real trade), so I decided it would not be worth

to "bother" with placed orders and just "nail" everything that exists after the fall.

Orders have been placed before the fall, if they have been executed then nothing can be done, and if

If they are still "hanging around", then killing them and re-setting them in accordance with the trading situation, you will not lose anything!

Then all that remains is the position - whether it is there or not.

As for writing/reading variables from a file.

I have "hot" (during work) change of variables in my EAs, so I

I write them and read from a file so the Expert Advisor will take the "hot" settings on a new start.

The problem YOU are creating for yourself!

Think about it!

P/S MT5 is not MT4 where orders are very important!

In MT5, you have to be guided by POSITION, not by orders.

 
Fry_Антон:

Expand the answer to a reasonable useful thought and I would appreciate it.

What are the basic principles that make the EA code "better"?

Answered in private.

Z.I. Your examples are not valid. There are no such problems on Forts. Of course, you can make up any problem and then try to solve it for a long time. But why solve it when it's easier not to make it up?

Reason: