WORKAROUND attempt:
Idea: At position open, save the time in a hash map (ticketNumber, openTime). Later, after the end of a backtest, access openTime from the hash map and write it to the file instead of the erroneous value from the loop “For each Closed Position”.
See the source code of a function that acts like an object managing a hash map below. Added this to the functions area of Custom Blocks. This part of the workaround is tested and working well.
HOWEVER: I learned something new. Something, that disabled this workaround completely: In MT5, we have different “ticket numbers” for deals, orders and positions. Specifically, the ticket number I can access directly after position open is not the same as the one in the loop “For each Closed Position”. I didn’t find any way to map those two ticket numbers with the fxDreema UI. If you know a way, please share.
Therefore, WORKAROUND TWO is this: Develop an independent function writing the complete CSV-file with the position history and call it in “on Deinit”.
A fix of the bug described above would be appreciated.
Here is the code on the function managing a hash map. You may like to modify its hash and value types according to your needs. Furthermore, at the moment, the “action” parameter is not used. It’s a template for all kinds of hash maps. Use a copy of this function with different name for each hash map that you need.
double hashMap(int hash=-1, double value=-1, string action=NULL)
/*
* This is a template for a function acting as a simple object
* managing a hash map. For usage as custom code in fxDreema, for
* example. Copy this function for each hashMap that you need, rename
* it according to the content and adapt the types of hash and value
* as desired.
*
* In this template, the hash values must be numbers >= 0 (!)
*
* Returns (a) 0 if all went well, or (b) the requested value belonging
* to a hash key, or (c) -1 in case of an error or "hash key not found".
*/
{
static int hashArray[];
static double valueArray[];
static const int RESERVE_SIZE=3000;
//
// Action "return map size"
//
if(hash==-1 && value==-1 && action==NULL)
return(ArraySize(hashArray));
//
// Action "add element"
//
if(hash>-1 && value>-1 && action==NULL)
{
int i;
int size=ArraySize(hashArray);
for(i=0; i<size; i++)
if(hashArray[i]==hash)
break;
if(i<size) // Found => Invalid
{
PrintFormat(">>>>> Error in %s(): hash=%i existing.",__FUNCSIG__,hash);
return(-1);
}
int newSize=ArraySize(hashArray)+1;
ArrayResize(hashArray,newSize,RESERVE_SIZE);
ArrayResize(valueArray,newSize,RESERVE_SIZE);
hashArray[newSize-1]=hash;
valueArray[newSize-1]=value;
return(0);
}
//
// Action "get element"
//
if(hash>-1 && value==-1 && action==NULL)
{
int i;
int size=ArraySize(hashArray);
for(i=0; i<size; i++)
if(hashArray[i]==hash)
break;
if(i<size) // Found
return(valueArray[i]);
else // Not found
return(-1);
}
//
// Action "unidentified"
//
return(-1);
}