90

Hi guys!

I have been working on an EA for a few weeks now and I am stuck: I want to close all trades and open orders when a profit target (say 10 pips) is reached.

I have a ClosePosition function which doesn't seem to be working.

Would anyone have any idea how to solve this?

Thanks a lot,

Martin

```//+------------------------------------------------------------------+

// So far: first two open order are placed

// ADDING: Close all trades and orders if overall profit is 10 pips

//+------------------------------------------------------------------+

input double PositionSize                       = 1;      // Position size (cost of one pip)
input double PositionHedge                      = 3;      // Size of hedge position
input int StopLossDistance                      = 30;     // Stop loss distance in pips
input bool IsUseTrailingStop                    = false;  // Use trailing stop
input int  TrailingStopDistance                 = 40;     // Trailing stop distance in pips
input bool UseTakeProfit                        = false;   // Use Take Profit
input int  Take_Profit                          = 30;     // Take Profit
input int RSIuplimit                            = 70;     // RSI Upper Limit
input int RSIlowlimit                           = 30;     // RSI Lower Limit
input double AccountProfit                      = 100;    // Account Profit

string HoursandMinutes;
int Previouscount;
bool   ext_hedging=true;
CSymbolInfo symbol_info;
ulong arr_ticket_long_rsi[];
ulong arr_ticket_short_rsi[];
double trailing_stop_value;
double stop_loss_value;
double take_profit_value;
int tick_counter=0;
int time_in_open_function=-1;
int time_in_close_function=-1;
double Long1, Long2, Short1, Short2;

#define MA_MAGIC 2719281928459450

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

//--- prepare trade class to control positions if hedging mode is active
ext_hedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
symbol_info.Name(_Symbol);

if(symbol_info.Digits()==3 || symbol_info.Digits()==5)

ArrayResize(arr_ticket_long_rsi,0,100000);
ArrayResize(arr_ticket_short_rsi,0,100000);

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

// get local time
datetime time= TimeLocal();
//format time and create a string
HoursandMinutes = TimeToString(time,TIME_MINUTES);

currentBid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Get latest Bid Price

//  CheckForClose();
CheckForOpen();

}
//+------------------------------------------------------------------+
//| Try to open the deal                                          |
//+------------------------------------------------------------------+
void CheckForOpen()

{
MqlRates rt[2];
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return ;
}

datetime cur_time=rt[1].time;
MqlDateTime mdt;
TimeToStruct(cur_time,mdt);
int cur_calculated_time=mdt.hour*60+mdt.min;
if(cur_calculated_time==time_in_open_function)
return;
time_in_open_function=cur_calculated_time;

//remove unnecessary orders
RefreshOrders();
//move trailing stop orders if it is necessary
ModifyOrders();

string str_date_time= TimeToString(TimeCurrent())+" ";

// IF DAILYPROFIT IS < 100) THEN PROCEED

// Place Open Order at 07:55 UK time
if (StringSubstr(HoursandMinutes,0,5)=="07:55")
{
morningbid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Get bid price at 07:55am UK time

Short1 = morningbid - 3;

}

// if only 1 position is open then proceed

if (OrdersTotal() < 1);
{

ENUM_POSITION_TYPE firstlong=PositionGetInteger(POSITION_TYPE);
double open_price_firstlong=PositionGetDouble(POSITION_PRICE_OPEN);
double current_stop_loss_firstlong=PositionGetDouble(POSITION_SL);
double local_stop_loss_firstlong;

{

}

ENUM_POSITION_TYPE firstshort=PositionGetInteger(POSITION_TYPE);
double open_price_firstshort=PositionGetDouble(POSITION_PRICE_OPEN);
double current_stop_loss_firstshort=PositionGetDouble(POSITION_SL);
double local_stop_loss_firstshort;

if (firstshort == POSITION_TYPE_SELL)
{

}
}

}
//+------------------------------------------------------------------+
//| Open position                                                  |
//+------------------------------------------------------------------+
void OpenPosition(ulong& arr_ticket[],ENUM_ORDER_TYPE order_type)
{

{
string str_date_time= TimeToString(TimeCurrent())+" ";
double stop_loss=0;
double take_profit=0;
double local_stop_loss_value=IsUseTrailingStop ? trailing_stop_value:stop_loss_value;

//        double local_take_profit_value= UseTakeProfit ? take_profit_value:take_profit_value;
double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
//Calculate stop loss price
if(local_stop_loss_value!=0)
NormalizeDouble(bid_price-local_stop_loss_value,Digits());

// Calculating take profit price
//        if(local_take_profit_value!=0)
take_profit=order_type==ORDER_TYPE_SELL ? NormalizeDouble(bid_price-take_profit_value,Digits()):

//                                                       NormalizeDouble(bid_price+local_take_profit_value,Digits());

//Calculate lot size
double lot_size=GetLotSize();
string str_comment=_Symbol+_Period+TimeToString(TimeCurrent());
stop_loss,take_profit,str_comment);
if(is_open)
{
Print("Terminal opened the deal for ",_Symbol);
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string symbol=PositionGetSymbol(i);
string comment=PositionGetString(POSITION_COMMENT);
if(symbol==_Symbol && comment==str_comment)
{
ticket=PositionGetInteger(POSITION_TICKET);

}

}
int array_size=ArraySize(arr_ticket);
ArrayResize(arr_ticket,array_size+1);
arr_ticket[array_size]=ticket;

}
else
{
Print("Terminal could not open deal for ",_Symbol);
Print("Terminal error code= ",result_ret_code);
}
}

}

//+------------------------------------------------------------------+
//| Close position with the specified ticket                                                 |
//+------------------------------------------------------------------+
void ClosePosition(ulong& arr_tickets[])
{
string date_time_string=TimeToString(TimeCurrent())+" ";
for(int i=0;i<ArraySize(arr_tickets);i++)
{
ulong ticket=arr_tickets[i];

if (AccountInfoDouble(ACCOUNT_PROFIT) == AccountProfit)
{

bool is_selected=PositionSelectByTicket(ticket);
if(is_selected)
{

{
if(!is_close)
{
Print("Terminal could not close the position for",_Symbol," the error Code=",result_ret_code);
}
}

}
}
else
{

}
ticket=0;

}
ArrayResize(arr_tickets,0,10000);
}
//+------------------------------------------------------------------+
//| Remove unnecessary orders from tickets array                                                 |
//+------------------------------------------------------------------+
void RefreshArray(ulong& arr_ticket[])
{
ulong buffer_array[];
ArrayResize(buffer_array,0,10000);
int count=0;
for(int i=0;i<ArraySize(arr_ticket);i++)
{
ulong ticket=arr_ticket[i];
bool is_selected=PositionSelectByTicket(ticket);
if(is_selected)
{
ArrayResize(buffer_array,count+1,10000);
buffer_array[count]=ticket;
count++;
}
}
if(ArraySize(buffer_array)!=ArraySize(arr_ticket))
{
ArrayResize(arr_ticket,ArraySize(buffer_array),10000);
ArrayCopy(arr_ticket,buffer_array,0,0,WHOLE_ARRAY);
}
}
//+------------------------------------------------------------------+
//| Remove unnecessary orders from all tickets array                                                 |
//+------------------------------------------------------------------+
void RefreshOrders()
{
RefreshArray(arr_ticket_long_rsi);
RefreshArray(arr_ticket_short_rsi);
}
//+------------------------------------------------------------------+
//| Get lot size for the deal                                                 |
//+------------------------------------------------------------------+
double GetLotSize()
{
double lot_step=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
double min_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
double max_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
lot_size_for_deal=GetLotSize(lot_size_for_deal, lot_step,min_lot,max_lot);
return lot_size_for_deal;
}
//+------------------------------------------------------------------+
//| Get best fit lot size for the calculated one
//+------------------------------------------------------------------+
double GetLotSize(double calculated_lot_size,double lot_size_step,double min_lot_size,double max_lot_size)
{
if(calculated_lot_size<min_lot_size)
return min_lot_size;
if(calculated_lot_size>max_lot_size)
return max_lot_size;
double cur_lot_size=lot_size_step;
double next_lot_size=cur_lot_size+lot_size_step;
do
{
if(calculated_lot_size>=cur_lot_size && calculated_lot_size<=next_lot_size)
{
if(calculated_lot_size==cur_lot_size)
return cur_lot_size;
if(calculated_lot_size==next_lot_size)
return next_lot_size;
if(calculated_lot_size-cur_lot_size<next_lot_size-calculated_lot_size)
return cur_lot_size;
else
return next_lot_size;
}
cur_lot_size=next_lot_size;
next_lot_size=cur_lot_size+lot_size_step;
}while(true);
}
//+------------------------------------------------------------------+
//| Move trailing stop if it is necessary for all orders                                                 |
//+------------------------------------------------------------------+
void ModifyOrders()
{
ModifyOrders(arr_ticket_long_rsi);
ModifyOrders(arr_ticket_short_rsi);
}
//+------------------------------------------------------------------+
//| Move trailing stop if it is necessary for all orders from array                                                |
//+------------------------------------------------------------------+
void ModifyOrders(ulong& arr_ticket[])
{

if(!IsUseTrailingStop || TrailingStopDistance==0)
return;
for(int i=0;i<ArraySize(arr_ticket);i++)
{
ulong ticket=arr_ticket[i];
bool is_selected=PositionSelectByTicket(ticket);
if(is_selected)
{
ENUM_POSITION_TYPE position_type=PositionGetInteger(POSITION_TYPE);
double open_price=PositionGetDouble(POSITION_PRICE_OPEN);
double current_stop_loss=PositionGetDouble(POSITION_SL);
double local_stop_loss;
double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
{
if(bid_price-open_price>trailing_stop_value)
{
local_stop_loss=NormalizeDouble(bid_price-trailing_stop_value,Digits());
if(current_stop_loss<local_stop_loss)
{
}
}
}
else if(position_type==POSITION_TYPE_SELL)
{
{
if(current_stop_loss>local_stop_loss)
{
}

}
}

}
}

}
```
425

Martin:

I have been working on an EA for a few weeks now and I am stuck: I want to close all trades and open orders when a profit target (say 10 pips) is reached.

I have a ClosePosition function which doesn't seem to be working.

Would anyone have any idea how to solve this?

Before we even look at close, your EA won't even open... Check these lines:

```   morningbid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Get bid price at 07:55am UK time

Short1 = morningbid - _Point*3;
```

You cannot just add 3 to a price... you need to multiply it to _Point first. And if your broker uses 3 or 5 digits (check _Digits), which is highly probably nowadays, you should multiple _Point by 30 instead of 3.

And where do you plan to call ClosePosition function? (it isn't called at all, so of course it doesn't work).

90

Seng Joo Thio:

Before we even look at close, your EA won't even open... Check these lines:

You cannot just add 3 to a price... you need to multiply it to _Point first. And if your broker uses 3 or 5 digits (check _Digits), which is highly probably nowadays, you should multiple _Point by 30 instead of 3.

And where do you plan to call ClosePosition function? (it isn't called at all, so of course it doesn't work).

Thanks for the tip on adding 3 pips, I hadn't seen that.

I'm calling it in OnTick, at the same place as CheckforOpen, as CheckForClose().

I removed the if statement (below) from the ClosePosition function and added it in this new function which should close all positions.

```void CheckForClose()
{

if (AccountInfoDouble(ACCOUNT_PROFIT) == AccountProfit)
{

ClosePosition(arr_ticket_long_rsi);
ClosePosition(arr_ticket_short_rsi);

}

} ```
425

Martin:

Thanks for the tip on adding 3 pips, I hadn't seen that.

I'm calling it in OnTick, at the same place as CheckforOpen, as CheckForClose().

I removed the if statement (below) from the ClosePosition function and added it in this new function which should close all positions.

A number of issues:

1. In your CheckForClose(), you cannot compare floating numbers with ==, because they're rarely equal. Should change to >= instead.
2. Your arr_ticket_long_rsi and arr_ticket_short_rsi arrays - you iterate through them in ClosePositions(), RefreshArray() and ModifyOrders(), but they were never filled with any data. That explains why your positions are never closed (and not modified too).
3. Long1 and Short1 - only set at specific time. Beyond that time, your code still attempt to set buystop and sell stop, so you see many error messages when actual price is below Short1 and you try to set sellstop, and vice versa for buystop.
Try fixing these first and see how it performs...