desmondc » Tue Mar 22, 2016 4:00 am wrote:To update this thread, i did find a solution to my problem. In summary since I can't get seem to get the if condition to work direclty with OrderTotal() what I did was get a loop to pull out that figure for my IF condition. Its stupid but hell as long as we get the result we want..
Your code is both faulty, inefficient and ineffective. I get goosebumps even looking at it:
Faulty because there is no function OrderTotal(). You probably mean Order
sTotal().
Inefficient as OrdersTotal() is re-evaluated for every iteration in the loop. If you want to iterate over the open-orders cursor in chronological order use:
Code: Select all
int ordersTotal = OrdersTotal();
for (int index=0; index < ordersTotal; index++) {
if ( OrderSelect(index, SELECT_BY_POS, MODE_TRADES ) ) {
...
}
}
and if you wish to iterate over the open-orders cursor in reverse chronological order use:
Code: Select all
for (int index = OrdersTotal()-1; index >= 0; index--) {
if ( OrderSelect(index, SELECT_BY_POS, MODE_TRADES ) ) {
...
}
}
If you want to start closing orders, whilst iterating over the open-orders cursor, you have start at the end, i.e. you have to iterate in reverse chronological order, as it totally messes up the cursor if you close orders at the start or in the middle. Still, even if you start at the end, and you close orders depending on a certain condition, you have to first collect their ticket numbers, and then close each ticket separately, like so:
Code: Select all
int ticketsToBeClosed[];
ArrayResize( ticketsToBeClosed, 0 );
for (int index = OrdersTotal()-1; index >= 0; index--) {
if ( OrderSelect(index, SELECT_BY_POS, MODE_TRADES ) ) {
if ( index % 2 == 0 ) { // For arguments sake, just close the 'even' orders
addToIntArray( ticketsToBeClosed, OrderTicket() );
}
}
}
for( int index = 0; index < ArraySize(ticketsToBeClosed); index++ ) {
if ( OrderSelect( ticketsToBeClosed[index], SELECT_BY_TICKET ) ) {
if ( ( OrderCloseTime() == 0 ) && ( ( OrderType() == OP_BUY ) || ( OrderType() == OP_SELL ) ) ) {
OrderClose( ticketsToBeClosed[index], OrderLots(), ( OrderType() == OP_BUY ) ? MarketInfo( OrderSymbol(), MODE_BID ) : MarketInfo( OrderSymbol(), MODE_ASK ), SLIPPAGE, clrNONE );
}
}
}
void addToIntArray( int &array[], int num ) {
int currentSize = ArraySize( array );
ArrayResize( array, currentSize+1 );
array[currentSize] = num;
}
Ineffective As I don't think you achieve what you have set out to do, and the above code is good to know but has nothing to do with what you want. The requirement is to execute a function when OrdersTotal() has reached a set number (N). So, presumably, there is another thread (may be the same thread) or process that is opening trades. You just need to add somewhere in your OnTick() or OnTimer() thread the following code:
Code: Select all
if ( OrdersTotal() >= N ) {
// ExecuteRequiredFunction()
}
Why '>=' and not '=='? Because, imagine that you missed the moment that OrdersTotal() == N. The code could happily add orders ad infinitum, without your required function being called
ever.
Note, that OrdersTotal() returns
all active orders on the account, including pending orders and orders with different magic numbers (manual orders have MagicNumber == 0 ). So, if you want to execute the required function only when the total of
your orders equal or exceed N, you'd need to do something like:
Code: Select all
if ( numOrders() >= N ) {
// ExecuteRequiredFunction()
}
int numOrders() {
int result = 0;
for(int index=OrdersTotal()-1; index >= 0; index--) {
if ( OrderSelect( index, SELECT_BY_POS ) ) {
if ( OrderMagicNumber() != MagicNumber ) continue;
if ( (OrderType() != OP_BUY) && (OrderType() != OP_SELL) ) continue;
result++;
}
}
return(result);
}
Hope this has clarified a few points.