Smart Algorithmic Trading Solution

Trend-Hunting

Introduction

The article contains a description of a trading method – volume accumulation of profit trades. I suppose only profit trades can be accumulated. The article explains the optimal way to implement this and contains an EA code that helps to execute such trades correctly.

Concept of the Algorithm

Accumulating the volume of a profitable trade allows to gain maximum profit from the market movement that we come across. But the volume must be accumulated so that it does not result in the increase of risks. One of the algorithms of such volume accumulation is described in this article.
First of all we need a reference point – the first main trade. The main trade should be of volume larger than volume of each auxiliary trade. Suppose the volume of the main trade is 0.2 lot, volume of auxiliary trades will be 0.1 lot. Trailing Stop Loss is used for all trades, for example 50 points. When profit of the main trade reaches +100 points, Stop Loss will be +50. At this moment a trade of 0.1lot is opened in the same direction with Stop Loss of -50 points. If price goes back, both trades will be closed by Stop Loss order. Acquired profit will be equal to 50 points of 0.2 lot, loss – 50 points of 0.1 lot. Totally profit will be equal to 50 points of 0.1 lot. Thus loss protection s achieved, while the trade volume is increased.
If a trade continues movement in the necessary direction, when profit of the auxiliary trade reaches +50 points, Trailing Stop Loss is enabled. When profit of 200 points is reached in the main trade, and that of 100 points in the auxiliary one, one more auxiliary trade will be opened. SL again is equal to -50. And so on.
This quite a simple method allows gaining good profit from lot accumulation. At the same time risks are minimized. Actually risk here is only losing part of the main trade, i.e. risk that the first auxiliary trade makes loss. But this is not a risk of loss, this is a risk of not getting the full profit.
The standard Trailing Stop Loss allows trailing trades only if there is profit. But if it is done on auxiliary trades before the necessary profit is gained, the profitability of such an approach to lot accumulation can be increased. You can do this as well as optimize opening of auxiliary orders by means of MQL4.

Implementation

The Expert Advisor written for this purpose is based on the EA described in the article “Comfortable Scalping”. In this article the EA has combined functions: it plays the role of a trainer-game and a tool for opening trades. For this trade the function of a game was deleted. Thus the Expert Advisor draws two arrows on a chart – up and down. Deletion of one of them is a signal to open trades in a necessary direction. For example, deleting a down arrow an up arrow is left on a chart. For the EA this is a signal to open a Buy order and placing a number of pending Buy Stop orders.
A market order is the main order here. Pending orders have the functions of auxiliary orders that have a smaller lot than the main one. For the calculation of “frequency” of auxiliary trades opening and their quantity, two notions are used. The first one is the ultimate goal, Take Profit. It is equal for all orders (main and auxiliary). The second notion is a step for opening pending orders. Depending on the ultimate goal the EA calculate how many orders it can place in the interval from the current price to the Take Profit level.
For example, if we use Take Profit equal to 400 points and the step for order opening is 100 points (by default), 4 orders will be opened at Buy. The first one is Buy at the Ask price, the main order. The second one is an auxiliary Buy Stop at the price Ask+100 points. The third one is an auxiliary Buy Stop at Ask+200 points. The fourth one – an auxiliary Buy Stop at the price of Ask+300 points. Take profit for all orders will be equal to Ask+400 points, i.e. for the first order it will be 400 points, for the second one 300, for the third one – 200 and 100 points for the fourth order.
Trailing Stop Loss for the main trade works only if a necessary profit is obtained (by default 50 points). For auxiliary trades it works from the moment of opening (i.e. Stop Loss can be trailed the area of loss). The Trailing Stop Loss level is equal for all trades. Besides Trailing Stop Loss is a Stop Loss level for auxiliary trades.
If the main order is closed, remaining pending orders are deleted. After that two arrows are drawn on the chart again. This indicates the readiness of the EA to open trades again.
All this may seem lengthy but it can be easily implemented in practice. Let’s analyze the EA code.

 

//+------------------------------------------------------------------+
//|                                                   take_trend.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
extern int gap=20;            //level at which arrows are placed 
extern int TP=400;            //Take Profit level
extern int SL=0;              //Stop Loss level
extern double Lots1=0.2;      //lot of a main trade
extern double Lots2=0.1;      //lot of auxiliary trades 
extern int slippage=2;        //level of acceptable requote
extern int MagicNumber1=5345; //magic number of the main trade
extern int MagicNumber2=4365; //magic number of auxiliary trades
extern int Open_Step=100;     //step for opening auxiliary trades

extern bool UseTrailing = true; //enabling/disabling T-SL
extern int TrailingStop = 50;   //Trailing Stop Loss level
extern int TrailingStep = 1;    //Trailing Stop Loss step
int start()
  {
//------------------------------       
//+----------------------------------------------------------------------------------------------+
//|                              searching open orders for a pair                                |
    int pos_sell=0;
  for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--) 
  { 
   if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break; 
   if (Symbol()==OrderSymbol()
   &&OrderMagicNumber()==MagicNumber1   
   &&(OrderType()==OP_SELL))
   {
    pos_sell=1; break;   
   } 
  }

    int pos_buy=0;
  for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--) 
  { 
   if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break; 
   if (Symbol()==OrderSymbol()
   &&OrderMagicNumber()==MagicNumber1
   &&(OrderType()==OP_BUY))
   {
    pos_buy=1; break;   
   } 
  }    
//|                              searching open orders for a pair                                |
//+----------------------------------------------------------------------------------------------+  
//+------------------------------------------------------------------------------------+
//|                                 working with objects                               |  

//+----------------------------------------------------------+
//|                    deleting objects                      | 
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
  if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point)            
    { 
     ObjectDelete("up"); 
    } 
//|                    deleting objects                      |   
//+----------------------------------------------------------+ 

//+----------------------------------------------------------+
//|                   drawing objects                        |   
   if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no objects
   &&!pos_sell&&!pos_buy)                              //if no open orders
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, 234);
     ObjectSet("down", OBJPROP_COLOR, Red);

     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, 233);
     ObjectSet("up", OBJPROP_COLOR, Blue);
   }    
//|                   drawing objects                        |
//+----------------------------------------------------------+   

//|                                 working with objects                               |   
//+------------------------------------------------------------------------------------+

//+----------------------------------------------------------------------------------------------+ 
//|                                deleting unnecessary orders                                   | 
int cnt_del; 
if(pos_buy==0)
{               
  for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++) 
  {
    if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue;     
    if(OrderSymbol()==Symbol())
    {
     if (OrderType()==OP_BUYSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket()); 
    }
  } 
 } 

if(pos_sell==0)
{               
  for (cnt_del=0; cnt_del<OrdersTotal(); cnt_del++) 
  {
    if (!(OrderSelect(cnt_del, SELECT_BY_POS, MODE_TRADES))) continue;     
    if(OrderSymbol()==Symbol())
    { 
    if (OrderType()==OP_SELLSTOP && OrderMagicNumber()==MagicNumber2) OrderDelete(OrderTicket()); 
    }
  } 
 }  
//|                                deleting unnecessary orders                                   |
//+----------------------------------------------------------------------------------------------+  

//+------------------------------------------------------------------------------------+ 
//|                                   opening trades                                   |
double sl_buy, sl_sell;
 if(!SL)
 { 
  sl_buy=0;
  sl_sell=0;
 }
 else
 {
  sl_buy=Ask-SL*Point;
  sl_sell=Bid+SL*Point;
 }
 int stop_positions=MathFloor(TP/Open_Step-1);
 int i, open_step_2;
  if(
     ObjectGet("up", OBJPROP_PRICE1)==Open[0]+gap*Point
     &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0
     &&ObjectFind("down") != 0
     &&ObjectFind("up") == 0
     &&!pos_buy  
     )
     {
      OrderSend(Symbol(),OP_BUY, Lots1,Ask,slippage,sl_buy,Ask+TP*Point,"take_trend",MagicNumber1,0,Blue); 
      for(i=stop_positions;i>=0; i--) 
      {
       open_step_2=open_step_2+Open_Step;
       OrderSend(Symbol(),OP_BUYSTOP, Lots2,
       Ask+open_step_2*Point,slippage,
       0,Ask+TP*Point,"take_trend",MagicNumber2,0,Blue);
      }          
     }
  if(
     ObjectGet("down", OBJPROP_PRICE1)==Open[0]-gap*Point
     &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0
     &&ObjectFind("up") != 0
     &&ObjectFind("down") == 0
     &&!pos_sell
     )
     {
      OrderSend(Symbol(),OP_SELL, Lots1,Bid,slippage,sl_sell,Bid-TP*Point,"take_trend",MagicNumber1,0,Red);
      for(i=stop_positions;i>=0; i--) 
      {
       open_step_2=open_step_2+Open_Step;
       OrderSend(Symbol(),OP_SELLSTOP, Lots2,
       Bid-open_step_2*Point,slippage,
       0,Bid-TP*Point,"take_trend",MagicNumber2,0,Red);
      }        
     }
//|                                   opening trades                                   |  
//+------------------------------------------------------------------------------------+   

//+-------------------------------------------------------------------------------------------------+ 
//|                                      trail of open orders                                       |
if (UseTrailing)
{ 
  for (int trall=0; trall<OrdersTotal(); trall++) {
    if (!(OrderSelect(trall, SELECT_BY_POS, MODE_TRADES))) continue;
    if (OrderSymbol() != Symbol()) continue;       

    if (OrderType() == OP_BUY ) {
      if (Bid-OrderOpenPrice() > TrailingStop*Point || OrderMagicNumber()==MagicNumber2) {
        if (OrderStopLoss() < Bid-(TrailingStop+TrailingStep-1)*Point || OrderStopLoss() == 0) {
          OrderModify(OrderTicket(), OrderOpenPrice(), Bid-TrailingStop*Point, OrderTakeProfit(), 0, Blue);
       }
      }
    }

    if (OrderType() == OP_SELL) {
     if (OrderOpenPrice()-Ask > TrailingStop*Point || OrderMagicNumber()==MagicNumber2) {
        if (OrderStopLoss() > Ask+(TrailingStop+TrailingStep-1)*Point || OrderStopLoss() == 0) {
          OrderModify(OrderTicket(), OrderOpenPrice(), Ask+TrailingStop*Point, OrderTakeProfit(), 0, Blue);
        }
     }
    }
  }
 }
//|                                      trail of open orders                                       |
//+-------------------------------------------------------------------------------------------------+

   return(0);
  }
//+------------------------------------------------------------------+
The code includes all necessary comments.
Variables:

 

gap – level, on which arrows are placed;
TP – Take Profit level;
SL – Stop Loss level;
Lots1 – lot of a main trade;
Lots2 – lot of auxiliary trades;
slippage – level of acceptable requote;
MagicNumber1 – magic number of the main trade;
MagicNumber2 – magic number of auxiliary trades;
Open_Step – step for opening auxiliary trades;


UseTrailing – enabling/disabling T-SL;
TrailingStop – Trailing Stop Loss level;
TrailingStep – Trailing Stop Loss step.

 

When the Expert Advisor is attached to a chart, it draws two arrows:

The remaining arrow will stay on the chart until the next candlestick:

Immediately after one if the arrows is deleted the EA opens trades:

You see, the remaining arrow is not shown on the screenshot – as it has been written earlier, it is deleted on the next candlestick and arrows do not appear till all trades are closed. As soon as the profit of the first trade reaches a necessary level, T-SL starts working (it works always for auxiliary trades). In this example only the first trade is closed at the rollback. Together with this all other orders are deleted:

Conclusion

To conclude I would like to add that Trailing Stop Loss level, Take Profit and the level for opening auxiliary trades should be chosen for each pair individually. Also it should be noted that for an efficient use the level of auxiliary trades opening must be larger than the T-SL level. In the main trade it is recommended to use lot size larger than that of auxiliary trades.

 

Attachments:
take_trend.mq4 (8.2 Kb)
Source: mql4.com
Leave a Reply

You must be logged in to post a comment.

Exclusive Offer for FxMath Clients

 

FxMath Scanner 50% discount code: RezaOff50

FxMath Harmonic Patterns Signals

Subscribe Free FxMath Harmonic Patterns Signals By Email

Join 10.7K other subscribers
Subscribe to Free FxMath Harmonic Patterns Signals By Telegram: https://www.telegram.me/fxmath_signals
Our Telegram Group: https://t.me/FxMathAI

 

Discover more from FxMath Financial Solution

Subscribe now to keep reading and get access to the full archive.

Continue reading