creating a magic number - page 3

 
//|                                                      This_EA.mq4 |
//|                      Copyright © 2010, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

#define This_EA  101
#define That_EA  102
#define Other_EA 103 // put this list of ea names to each of your ea's header, or...
                     // .. alternatively you can use a number suffix to your ea's file name 
                     // so it can be identified with --> StringSubstr(WindowExpertName(),x,y);
double This_EA_qty;
string magic_prefix;

int init()
  {

   if(GlobalVariableGet(This_EA_qty) >= 0.0){
            GlobalVariableSet("This_EA_qty", This_EA_qty + 1);
   }
   magic_prefix = StringConcatenate(This_EA, DoubleToStr(This_EA_qty,0));

   return(0);
  }

int deinit()
  {

      GlobalVariableSet("This_EA_qty", This_EA_qty - 1);
   
   return(0);
  }

int start()
  {
      double lots, SL, TP; int slip, time_stamp ;
      bool BuyCondition;
   
      if( BuyCondition == true )
      {
         time_stamp  = TimeCurrent(); 
         string magic_name = StringConcatenate(magic_prefix, time_stamp );
         int magic = StrToInteger(magic_name);
         
                                      // Integers range from -2147483648 to 2147483647
                                      // the resulting magic integer would most probably exceed that 
                                      // so we cut the number returned with TimeCurrent() short with 
                                      // MathMod(time_stamp,x) x being years, months not necessary for 
                                      // magic unique-ness. I don't include this calculation, 
                                      // since I'm short in time for testing it...
      
      
         OrderSend(Symbol(),0, lots, Ask, slip, SL, TP, NULL, magic, 0, CLR_NONE);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
takes a bit longer than I thought ...
edit : GVget condition != -1.0 to >= 0.0; edit
 
cameofx:
[...] takes a bit longer than I thought ...

This is increasingly becoming a re-hash (apologies for pun) of the previous topic I've already mentioned: https://www.mql5.com/en/forum/120034. Anything involving global variables raises issues around backup and disaster-recovery. If trading has to be moved in a hurry to a new server, then either there needs to be a recent backup of gvariables.dat available, or the user needs to be in a position to recreate the global variables manually.

I've not studied your code closely, but I'm also not sure what happens if there are multiple copies of the EA and MT4 is then restarted. It looks as though the code may assume that the EAs will be automatically reloaded in the same order that they were originally manually loaded. In other words, multiple copies of the EA may get different This_EA_qty values across restarts, and I can't then see how they correctly identify their historic orders in the MT4 list. But I could be wrong about this.

 
cameofx:
takes a bit longer than I thought ...
edit : GVget condition != -1.0 to >= 0.0
// TimeCurrent() in seconds since 1970 would most probably exceed that 

TimeCurrent() returns a 32 bit integer. The datatime type is an alias for the int type, int is also a 32 bit integer.


The other thing i don't understand in your code is why are you using a different MN for every opened trade? This is the opposite of what MNs are meant for. The idea of a MN is that you can identify all trades by a certain EA by simply looking at the MN. What is the reason for the random part of the MN? How would code in your EA look like that would close all open trades of this EA or trail all stops of this EA?
 
If I understand correctly - your solution to 2 diferent experts accidentally having the same ID is to put all expert ID's in the header of each expert. That's kind of a pain in the ass... Even if u put that part in an include file then u would still need to recompile all experts for each new expert u make.

The question of persistence is still there. I don't c how this would work properly after a terminal restart or after switching to a completely different terminal...
 
jjc:

This is increasingly becoming a re-hash (apologies for pun) of the previous topic I've already mentioned: https://www.mql5.com/en/forum/120034. Anything involving global variables raises issues around backup and disaster-recovery. If trading has to be moved in a hurry to a new server, then either there needs to be a recent backup of gvariables.dat available, or the user needs to be in a position to recreate the global variables manually.

I've not studied your code closely, but I'm also not sure what happens if there are multiple copies of the EA and MT4 is then restarted. It looks as though the code may assume that the EAs will be automatically reloaded in the same order that they were originally manually loaded. In other words, multiple copies of the EA may get different This_EA_qty values across restarts, and I can't then see how they correctly identify their historic orders in the MT4 list. But I could be wrong about this.

These are the kind of feedback I'm expecting... thank you gordon, 7bit & jjc..

your replies need some pondering.. but to reply quickly :

- if This_EA expert is already attached once on other chart, magic_number then would have value of : 101-1-time_stamp (dash for clarity sake)

- the information contained would be 101 - expert id; 1 - This_EA quantity operating to the moment; time_stamp - time of OrderSend

- we can then scan it with StringSubStr and know that a particular order was opened by This_EA while there were 1 other This_EA attached.

 
7bit:

TimeCurrent() returns a 32 bit integer. The datatime type is an alias for the int type, int is also a 32 bit integer.


The other thing i don't understand in your code is why are you using a different MN for every opened trade? This is the opposite of what MNs are meant for. The idea of a MN is that you can identify all trades by a certain EA by simply looking at the MN. What is the reason for the random part of the MN? How would code in your EA look like that would close all open trades of this EA or trail all stops of this EA?

Sorry, what I meant was the resulting int magic_name would exceed that allocation. I'll move the comment in code accordingly.

To equalize our perception. I would propose this requirements for this 'automated' magic_number. The MN would have the following :

- You can Identify with what EA - this particular order with said MN - was open.

- An EA containing this technique - if attached to numerous (more than 1) would not generate the same magic number if that EAs open orders simultaneously outside of a 1 second span

- thus would not conflict in order handling but at the same time origin of the MN can still be traced

- please add if my list is not complete...

 
cameofx:
- the information contained would be 101 - expert id; 1 - This_EA quantity operating to the moment; time_stamp - time of OrderSend

- we can then scan it with StringSubStr and know that a particular order was opened by This_EA while there were 1 other This_EA attached.

But what is the time part in the MN for? Why not just use the EA numbers alone? and dont use substr? The usage of substr would need the int to be converted into a string, then some string operations and a string comparison, the time part of the MN is thrown away because it is never needed. String operations with integers generally tend to look amateurish because in most cases if could be better solved by encoding the information in different bits of the 32 bit word and use bitwise operations to manipulate or check them which would be orders of magnitude faster and more elegant.

Why not just use a (EA-instance-unique) int value for the mn and use simple integer comparison to compare either the whole number or certain bits of it?

For example let the first 28 bits be the ID and the last four bits a number from 0..15 to identify different types of trades (for example if it can open 3 different types of orders: initial, level1, level2 and hedge)

ID = hash & 0xFFFFFFF0  // this has the 4 low bits always zero


// generate the mn for level 1 trades
MN = (ID + 1);
OrderSend(..., MN, "level 1");


// generate the mn for hedge trades
MN = (ID + 15);
OrderSend(..., MN, "hedge the whole mess");


// this strategy may not make any sense, only to illustrate the code:
// close the hedge trades and trail the stops of all levels
for(...){
   if (OrderMagicNumber() & 0xFFFFFFF0 == ID){  // this trade belongs to us
      if (OrderMagicNumber() & 0x0000000F == 15){ // this is a hedge trade
         OrderClose(...)
      }else{ // this is one of the other levels
         Trail(OrderTicket());
      }
   }
}

// or even easier:
MN = (ID + 15); // all our hedge trades have this MN
for(...){
   if (OrderMagicNumber() == MN){
      OrderClose(...)
   }
}
 
gordon:
If I understand correctly - your solution to 2 diferent experts accidentally having the same ID is to put all expert ID's in the header of each expert. That's kind of a pain in the ass... Even if u put that part in an include file then u would still need to recompile all experts for each new expert u make.

The question of persistence is still there. I don't c how this would work properly after a terminal restart or after switching to a completely different terminal...

No, you haven,t :) please read the comments in code regarding WindowExpertName().

If called from expert it would retrieve expert/script/indicator file name without the ".mq4" or ".ex4" you don't have to put any include just name you EAs accordingly.

PS : sorry for the spammy reply :)

 
7bit:

But what is the time part in the MN for? Why not just use the EA numbers alone? and dont use substr? The usage of substr would need the int to be converted into a string, then some string operations and a string comparison, the time part of the MN is thrown away because it is never needed. String operations with integers generally tend to look amateurish because in most cases if could be better solved by encoding the information in different bits of the 32 bit word and use bitwise operations to manipulate or check them which would be orders of magnitude faster and more elegant.

Why not just use a (EA-instance-unique) int value for the mn and use simple integer comparison to compare either the whole number or certain bits of it?

For example let the first 28 bits be the ID and the last four bits a number from 0..15 to identify different types of trades (for example if it can open 3 different types of orders: initial, level1, level2 and hedge)


hmm... I use the time part because I thought MN for each order opened by an EA must be unique in regards to other orders opening at the same time with the same EA on different charts.

the premise would be : If an EA opened two(more) orders simultaneously with the same magic number. they cannot have the same MN or else it would conflict in Order handling and or

Order identifying... maybe I mistakenly confused this with OrderTicket grabbing (or not?).

- incorporating strategy to the MN would be the next step naturally

- I see your skill exceeds me by light years: )). I haven't yet the ability to optimize operations, that's why I posted this.. Now I know that checking with bitwise operations would be faster.

thank you. I may need to ask you for how-to explanation later :)))

 
cameofx:

hmm... I use the time part because I thought MN for each order opened by an EA must be unique in regards to other orders

No, they can be anything you want. just like the comment. see them as some sort of a numerical comment. All manual trades opened with the normal MT4 user interface will have the magic number 0, so you can for example loop over all orders and close/delete all manual trades and orders while leaving all EA trades untouched.

All my EAs create their own number, unique to (EA-name + symbol + timeframe), thats why i spent so much effort for finding a good and easy hash function to create this number. The hash is even so good that I can easily cut off the last few bits of this hash to make room for sub-numbers (if i need it, but I rarely need this) and it would still be quite safe against collisions.

But most of my EAs use the hash directly and don't have a sub-numbering because they have only one type of trades and treat all their trades identically.

For uniquely identifying only one certain order there is always the ticket number.

Reason: