Reputation: 1699
With MetaTrader Terminal ( MQL4
), I try to have a reversed array, that I append ( prepend ) items to.
So, on every tick, myArray[0]
becomes the 'newest' value, and the previous value shifts to myArray[1]
and so on.
But its harder then it sounds.
I tried like this ->
double myArray = []; // GLOBAL Dynamic array
extern int maxArrayLength = 50; // EXTERN iterable
// -----------------------------------------------------------------------
bool prependToReversedDoubleArray( double& theArray[], double value, int maxLength ) {
int size = ArraySize( theArray ); // LOCAL size
ArraySetAsSeries( theArray, false ); // Normalize the array ( left to right )
ArrayResize( theArray, size + 1 ); // Extend array length
Alert( "test = ", size );
theArray[size] = value; // Insert the new value
ArraySetAsSeries( theArray, true ); // Reverse the array again
if ( ArraySize( theArray ) > maxLength ) {
ArrayResize( theArray, maxLength );
}
return( true );
}
prependToReversedDoubleArray( myArray, 0.1234, maxArrayLength );
Upvotes: 2
Views: 2299
Reputation: 210
This can be done for optimal performance by creating your own dynamic Array class based on a linked list of pointers. You can define a custom operator []
to access its elements like you do with a normal array. This class can implement a Prepend()
method that would be very fast as it would just have to perform a few operations with pointers and just one memory allocation.
However, such a class is not a simple thing to code, so depending on your goals, it might not be the best solution to your case.
Upvotes: 0
Reputation: 1699
thanks for all the good intel! I learned a lot from the explanations :)
The problem I had was, how to append values to the 'beginning' of a reversed array ( write to array[0]
and shift the rest up ).
It still not non-blocking and probably not the fastest way, but it works for now.
Here is the solution, it also takes a 'maxLength' value, that keeps the array size as desired :) :
int prependToReversedDoubleArray( double &theArray[],
double value,
int maxLength
)
{ int newSize = ArraySize( theArray ) + 1;
ArraySetAsSeries( theArray, false ); // Normalize the array (left to right)
ArrayResize( theArray, newSize ); // Extend array length
theArray[newSize-1] = value; // Insert the new value
ArraySetAsSeries( theArray, true ); // Reverse the array again
if ( maxLength > 0
&& newSize > maxLength ) // Check if the max length is reached
{ newSize = maxLength;
ArrayResize( theArray, maxLength );
}
return( newSize );
}
Upvotes: 2
Reputation: 1
Fortunately a default MQL4
instrumentation for TimeSeries organisation will not work on this scenario.
Why?
MQL4
TimeSeries ( reversed ) Arrays do get system-driven event-locked cell-index re-shuffling only on a current TimeFrame's aNewBarEVENT
, not based on just every anFxQuoteArrivalEVENT
( as was asked in the O/P to shift / update [0]
per each tick arrival " ..., on every tick, " ).
A trivial for(){ shift 'em all / store new}
kind of loops, proposed earlier, seems on a first glimpse, as a simple can-do hack.
The danger is a devil is hidden in details.
After some 100.000+ quotes, the array(s) grow to sizes a single memory-page will not hold the whole array + processing times for a dumb cell-shifting grows ( linearly ) in O(1)
, but to such scales, which start to destroy an ability to be still as fast as being finally able to wait a few ms
/ us
for next FOREX market events' arrival in a non-blocking mode, thus the MetaTrader Terminal inner architecture loses an ability to hold an illusion of a false-synchronicity with external events.
ArrayResize()
is another hidden devil out there.
In other words, such code will start "missing" events ( will drop data ( which it will never see on arrival, as still shuffling data in the cell-shifting loop ) ).
0 ) Avoid memory-page swaps - stay In-RAM.
1 ) Avoid any blocking step.
2 ) Avoid a dumb cell-shuffling of any kind - alike value[i] = value[i-1];
.
3 ) Avoid any ArrayResize()
on the fly.
Solution leads to a proxy in a form of a circular-buffer architecture with a distributed ( the only possible non-blocking help to an MT4
MQL4
code-execution with a rigid, user non-controllable, thread architecture )
This way MQL4
code can contain a lightweight proxy-object ( internally a local, cache-alike managed ring buffer ) which can also seamlessly access literally limitless amounts of cell-data, stored and practically maintained in a remote process / a fast computing grid.
This is both non-blocking (ever) and fast and smart and limitless ( if your algo-trading needs that ) .
Upvotes: 3
Reputation: 74
for( int i = arraylength - 1; i >= 1; i-- ) {
value[i] = value[i-1];
}
value[0] = newValue;
Upvotes: 3