Closing a trade

 
OK, so this is so simple I can't beleive I actually have to post a thread about it, and I apologize.  However, I have searched through all the documentation and all I have found is info on how to close ORDERS, not actual OPEN TRADES.  So I need to know, how can I close a trade, or a portion of a trade, without resorting to some duct tape method like adjusting the stop loss to the current quote?  How can I code a trade close, just like I can do when I trade manually, and I click on the trade in the Terminal window, and the order window pops up, and I can choose the volume I want to close, and click the close button.  How can I do this in MQL4? Thanks.
 

basically, OrderClose() is your builtin to use. If give < OrderLots() of ticket# then is partial close...

OrderClose() is for market orders and OrderDelete() is for pending orders. The Order Trade Pool contains both and market orders are live/brokered and pending orders may become market orders if it's conditions are met.

.

a few great refs for you:

https://book.mql4.com/trading/orderclose

and https://book.mql4.com/trading/orders

please always look at book and also use search box (top right of page) - an enormous archive of delights awaits you

have fun...

.

btw. have you read the mql4 book? well worth the effort...

.

ps.

As has been said by other on site - mql4 supplies most primitives for making more functional functions if you need. So in that aspect duct tape away for ability to do anything needed

:o)

 

Well Okay.  Thanks.  The reason I asked this is because I was using orderclose and in backtesting it wasn't working.  Here's my code below.  In backtesting none of the orders close untill the end of backtesting.  Some of them are stopped out, which is wierd unless it is a margin call, because there are no stop orders.  I keep getting this error message:

2008.05.20 23:12:10 2008.01.18 03:02 demon EURUSD,M1: OrderClose error 4051


int Ticket;
int Begin = 0;
double PosStart;
 
int start()
{
 
if(Begin==0)
{
   //buy 1/2 AccountBalance
   Ticket = OrderSend(Symbol(),OP_BUY,(AccountBalance()/2)*0.0001,Ask,3,0,0,NULL,0,0,Green);
   PosStart = Ask; 
   Begin=1;
}
 
//if price has moved +/-100 pips then
if(Begin==1)
{
   if((Ask > PosStart+100*Point)||(Ask < PosStart-100*Point))
   {    
      //close position
      OrderClose(Ticket, OrderLots(), Bid , 0, CLR_NONE);
      //buy AccountBalance/2
      Ticket = OrderSend(Symbol(),OP_BUY,(AccountBalance()/2)*0.0001,Ask,3,0,0,NULL,0,0,Green);
      PosStart = Ask;
   }
}
   
return(0);
}
 

Inkexit

Looking at https://docs.mql4.com/constants/errors we see 4051 is 'invalid parameter'

I suspect the value of the Ticket variable is going out of scope (i.e. disappearing at the end of the tick.

The start() function executes every tick (unless it is still processing a prior execution when the next tick occurs)

So...

Try declaring the variable as static, i.e.

static int Ticket;

thus the value of the last orders ticket is held over to the next tick (and hence the next run through of the start() function

Good luck

-BB-

 
BarrowBoy:

Inkexit

Looking at https://docs.mql4.com/constants/errors we see 4051 is 'invalid parameter'

I suspect the value of the Ticket variable is going out of scope (i.e. disappearing at the end of the tick.

The start() function executes every tick (unless it is still processing a prior execution when the next tick occurs)

So...

Try declaring the variable as static, i.e.

static int Ticket;

thus the value of the last orders ticket is held over to the next tick (and hence the next run through of the start() function

Good luck

-BB-

Using static didn't work.  I messed around and got it to work this way:

Lots = (AccountBalance()/2)*0.0001;
Ticket = OrderSend(Symbol(),OP_BUY,Lots*0.0001,Ask,3,0,0,NULL,0,0,Green);
OrderClose(Ticket, Lots, Bid, 0, CLR_NONE);


So I guess the invalid parameter was "OrderLots()"  Anybody know why that didn't work?  I thought OrderLots was a standard function?

 
inkexit:
BarrowBoy:

Inkexit

Looking at https://docs.mql4.com/constants/errors we see 4051 is 'invalid parameter'

I suspect the value of the Ticket variable is going out of scope (i.e. disappearing at the end of the tick.

The start() function executes every tick (unless it is still processing a prior execution when the next tick occurs)

So...

Try declaring the variable as static, i.e.

static int Ticket;

thus the value of the last orders ticket is held over to the next tick (and hence the next run through of the start() function

Good luck

-BB-

Using static didn't work. I messed around and got it to work this way:

Lots = (AccountBalance()/2)*0.0001;
Ticket = OrderSend(Symbol(),OP_BUY,Lots*0.0001,Ask,3,0,0,NULL,0,0,Green);
OrderClose(Ticket, Lots, Bid, 0, CLR_NONE);

So I guess the invalid parameter was "OrderLots()" Anybody know why that didn't work? I thought OrderLots was a standard function?

Hello,

I mean, you have forgot to define Lots. You have bought AccountBalance()/2*0.0001, there is no reference to Lots. But your Sell order is declared as Lots*0.0001.

A question to your new way, please: Why do scribe OP_BUY, Lots*0.0001, if you have defined Lots as AccountBalance/2*0.0001? Do you really deal with 1/10000 Lots (AccountBalance/2*0.0001)?

Ingolf

 
Ingolf:

Hello,

I mean, you have forgot to define Lots. You have bought AccountBalance()/2*0.0001, there is no reference to Lots. But your Sell order is declared as Lots*0.0001.

A question to your new way, please: Why do scribe OP_BUY, Lots*0.0001, if you have defined Lots as AccountBalance/2*0.0001? Do you really deal with 1/10000 Lots (AccountBalance/2*0.0001)?

Ingolf

Lots is defined as a double, sorry I didn't include that.  I use (AccountBalance/2*0.0001) because 1 lot = 10,000 units.  So if my balance is say, $5,000, and I want to invest 1/2 my account balance, I would be investing 0.25 lots.  5000/2*0.0001 = 0.25.

 

double OrderLots( )
Returns amount of lots for the selected order.
Note: The order must be previously selected by the OrderSelect() function.

Reason: