I agree with Steve, tramping around inside MPTM is probably not a good idea. There are an awful lot of people very happy with it and using it daily. It would be a shame to break something and even worse to change the behaviour they all expect and rely upon.dusktrader wrote:IDEA #1: FIFO compliant with Global Order Closure
I use the Global Order Closure feature almost daily, because my research has shown that trades left open into the Asian session tend to become losers. Around 5pm Eastern (NY close) I implement Global Order Closure to gracefully terminate any open positions. One problem I've seen is that MPTM does not follow FIFO rules, apparently. When it issues a closure order "out of order" I get an error in my platform and that trade does not close. This might be a really simple thing to fix, such as sorting the active orders by order number. I'm not 100% sure how FIFO works, but I think a sequence number could be available to help with this.
In the spirit of the holidays, however, I pulled out some of my existing code and made a FIFO compliant (as I understand the acronym, not the rules
In the interest of increasing your knowledge and understanding of MQL, I'd also be happy to review any changes you make to the code to make it more resilient. As you allude to, there is no error checking in the existing routine.
Look for "gah" to see where my changes start.
Code: Select all
void GlobalOrderClosureFIFO()
{
bool CloseOrders=false;
double ProfitPercentage=0;
// First calculate whether the upl is >= the point at which the position is to close
// Profit in dollars enabled
if (ProfitInDollars)
{
if(AccountProfit()>=DollarProfit) CloseOrders=true;
}
// Profit as percentage of account balance enabled
if (ProfitAsPercentageOfBalance)
{
ProfitPercentage=AccountBalance() * (PercentageProfit/100);
if (AccountProfit()>= ProfitPercentage) CloseOrders=true;
}
//Profit in pips
if (ProfitInPips)
{
Pips = CalculatePipsProfit();
//Dynamic pips target
if (UseDynamicPipsProfit)
{
PipsProfit = OrdersTotal() * PipsPerTrade;
}//if (UseDynamicPipsProfit)
if (Pips >= PipsProfit) CloseOrders=true;
}//if (ProfitInPips)
// Abort routine if profit has not hit the required level
if (!CloseOrders) return(0);
// Got this far, so orders are to be closed.
// Code lifted from CloseAll-PL, so thanks to whoever wrote the ea. Ok, so I could
// have written my own, buy why re-invent the wheel?
int _total=OrdersTotal(); // number of lots or trades ????
int _ordertype;// order type
if (_total==0) {return;} // if total==0
int _ticket; // ticket number
double _priceClose;// price to close orders;
//added - gah
//build an array of all tickets to manage so we don't
//have to worry about closing them as we go.
int OpenTickets[]; //array to hold all our ticket numbers
ArrayResize(OpenTickets, _total); //make it big enough to hold all of them
ArrayInitialize(OpenTickets, 0);
int i; //i will iterate over all orders
for(i = 0; i < _total; i++) {
if(OrderSelect(i, SELECT_BY_POS)) {
//skip the ones that don't match our symbol and MN
OpenTickets[i] = OrderTicket(); //It's a match, save it to the array
}//if(OrderSelect(i, SELECT_BY_POS))
}//for(i = 0; i < OrdersTotal(); i++)
for(int _i=0;_i<_total;_i++)
{ //# for loop
if (OrderSelect(OpenTickets[_i], SELECT_BY_TICKET) ) //gah - pick from our array
{
_ordertype=OrderType();
_ticket=OrderTicket();
switch(_ordertype)
{ //# switch
case OP_BUYLIMIT:
if(IncludePendingOrdersInClosure) OrderDelete(OrderTicket());
case OP_BUYSTOP:
if(IncludePendingOrdersInClosure) OrderDelete(OrderTicket());
case OP_BUY:
// close buy
_priceClose=MarketInfo(OrderSymbol(),MODE_BID);
Print("Close on ",_i," position order with ticket ¹",_ticket);
OrderClose(_ticket,OrderLots(),_priceClose,10,Red);
break;
case OP_SELLLIMIT:
if(IncludePendingOrdersInClosure) OrderDelete(OrderTicket());
case OP_SELLSTOP:
if(IncludePendingOrdersInClosure) OrderDelete(OrderTicket());
case OP_SELL:
// close sell
_priceClose=MarketInfo(OrderSymbol(),MODE_ASK);
Print("Close on ",_i," position order with ticket ¹",_ticket);
OrderClose(_ticket,OrderLots(),_priceClose,10,Red);
break;
default:
// values from 1 to 5, deleting pending orders
// if (PrintToJournal) Print("Delete on ",_i," position order with ticket ¹",_ticket);
// OrderDelete(_ticket);
break;
} //# switch
} // # if
} // # for loop
// User feedback
if (ShowAlerts) Alert("Global profit hit your target, so all open trades should have been closed");
} //End of GlobalOrderClosureFIFO()
BTW, I also agree with Steve about coding and trading. I would not be a trader if I wasn't a coder already.
George