Added vector and matrix methods CopyTicks and CopyTicksRange. They enable easy copying of tick data arrays into vectors and matrices.

bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);

The copied data type is specified in the 'flags' parameter using the ENUM_COPY_TICKS enumeration. The following values are available:

COPY_TICKS_INFO = 1,
COPY_TICKS_TRADE = 2,
COPY_TICKS_ALL = 3,
COPY_TICKS_TIME_MS = 1<<8,
COPY_TICKS_BID = 1<<9,
COPY_TICKS_ASK = 1<<10,
COPY_TICKS_LAST = 1<<11,
COPY_TICKS_VOLUME = 1<<12,
COPY_TICKS_FLAGS = 1<<13,

If multiple data types are selected (only available for matrices), the order of the rows in the matrix will correspond to the order of values in the enumeration.

Added Swap methods for vectors and matrices.

bool vector::Swap(vector &vec);
bool vector::Swap(matrix &vec);
bool vector::Swap(double &arr[]);
bool matrix::Swap(vector &vec);
bool matrix::Swap(matrix &vec);
bool matrix::Swap(double &arr[]);

Each array, vector or matrix refers to a memory buffer which contains the elements of that object. The Swap method actually swaps pointers to these buffers without writing the elements to memory. Therefore, a matrix remains a matrix, and a vector remains a vector. Swapping a matrix and a vector will result in a one-row matrix with vector elements and a vector with matrix elements in a flat representation (see the Flat method).

void OnStart()
{
matrix a= {{1, 2, 3},
{4, 5, 6}};
Print("a before Swap: \n", a);
matrix b= {{5, 10, 15, 20},
{25, 30, 35, 40},
{45, 50, 55, 60}};
Print("b before Swap: \n", b);
a.Swap(b);
Print("a after Swap: \n", a);
Print("b after Swap: \n", b);
vector v=vector::Full(10, 7);
Print("v before Swap: \n", v);
Print("b before Swap: \n", b);
v.Swap(b);
Print("v after Swap: \n", v);
Print("b after Swap: \n", b);
}

The Swap() method also enables operations with dynamic arrays (fixed-sized arrays cannot be passed as parameters). The array can be of any dimension but of an agreed size, which means that the total size of a matrix or vector must be a multiple of the array's zero dimension. The array's zero dimension is the number of elements contained at the first index. For example, for a dynamic three-dimensional array 'double array[][2][3]', the zero dimension is the product of the second and third dimension sizes: 2x3=6. So, such an array can only be used in the Swap method with matrices and vectors whose total size is a multiple of 6: 6, 12, 18, 24, etc.

Consider the following example:

void OnStart()
{
matrix m= matrix::Full(1, 10, 7.0);
Print("matrix before Swap:\n", m);
double array_small[2][5]= {{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10}};
Print("array_small before Swap:");
ArrayPrint(array_small);
if(m.Swap(array_small))
{
Print("array_small after Swap:");
ArrayPrint(array_small);
Print("matrix after Swap: \n", m);
}
else
{
Print("m.Swap(array_small) failed. Error ", GetLastError());
}
double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}
};
Print("array_static before Swap:");
ArrayPrint(array_static);
if(m.Swap(array_static))
{
Print("array_static after Swap:");
ArrayPrint(array_static);
Print("matrix after Swap: \n", m);
}
else
{
Print("m.Swap(array_static) failed. Error ", GetLastError());
}
double array_dynamic[][10];
ArrayResize(array_dynamic, 3);
ArrayCopy(array_dynamic, array_static);
if(m.Swap(array_dynamic))
{
Print("array_dynamic after Swap:");
ArrayPrint(array_dynamic);
Print("matrix after Swap: \n", m);
}
else
{
Print("m.Swap(array_dynamic) failed. Error ", GetLastError());
}
}