Konstantin Boykachev

CEO Proforexea LLC

Honest Coder

Professional Trader

0

No products in the cart.

Konstantin Boykachev

CEO Proforexea LLC

Honest Coder

Professional Trader

Blog Post

Price Action. Automation of trade in the pattern of “Absorption”

introduction

everyone who is studying the Forex market, sooner or later faces the Price Action. It’s not just the technique of reading graphs, it is a whole system of determining the direction of price movement. In this article we will consider the pattern of subsumption and create an expert who will keep track of this pattern and its grounds make trade decisions.

we have previously looked at automation of trade Price Action patterns, namely internal Baru, Price Action in the article. Automation of internal trade bar.

the rules of subsumption pattern

Pattern “Takeover” is a bar, body and shadows which completely absorb the body and shadow of the previous bar. There are two types of pattern:

  • BUOVB (Engulfing Outside Vertical Bar) is bullish external vertical bar;
  • BEOVB (Bearish Outside Vertical Bar) is bearish external vertical bar.

Figure. 1. type of pattern on the graph

Figure. 1. type of pattern on the graph

take a closer look at this pattern.

BUOVB. The graph shows that the maximum external bar above the maximum of the previous, and a minimum of external bar below the minimum of the previous.

BEOVB. This pattern is also easy to identify on the chart. Maximum external bar above the maximum of the previous, and a minimum of external bar below the minimum of the previous.

the difference is that every pattern makes it clear on the possible direction of the market movement.

Figure. 2. Design pattern

Figure. 2. Design pattern

rules of subsumption pattern:

  • work with pattern should be at senior provisional charts: H4, D1.
  • for precise entry should apply additional elements of graphical analysis: trend lines, support/resistance levels, Fibonacci levels, other Price Action patterns and so on.
  • in order to avoid premature or false market entry, you must use pending orders.
  • patterns repeating in the flat, it is not necessary to use as a signal to the entrance of the market.

identification of entry points for the “BUOVB” installation of stop orders

Figure. 3. installation of Buy Stop orders and stop orders

Figure. 3. setting the order Buy Stop and stop orders

consider the entry rules and stop-orders in the above example, to BUOVB (bullish external vertical bar):

  1. Set the pending order Buy Sto p costs just above the prices High (on a few items for confirmation) the outer bar.
  2. the Stop Loss level set Low prices below the outer bar.
  3. the Take Profit Level set, before reaching the nearest resistance level.

    identification of entry points for the “BEOVB” installation of stop orders

    Figure. 4. installation of Sell Stop orders and stop orders

    Figure. 4. setting the order Sell Stop orders and stop orders

    consider the entry rules and stop-orders in the above example, to BEOVB (bear external vertical bar):

    1. Set the pending order Sell Stop at a price slightly below the prices Low (a few points, to confirm) the outer bar.
    2. the Stop Loss level set High prices above the outer bar.
    3. the Take Profit Level set, before reaching the nearest support level.

    creating an expert advisor to trade patterns of “Absorption”

    We have examined the pattern of “Absorption”, learned how to properly and safely enter the market, as well as determined the levels of stop orders to limit potential losses or lock in profits.

    Next we will try to realize algorithms of Adviser and automate trade pattern “Absorption”.

    Open MetaEditor from terminal MetaTrader 4 and create a new Adviser (at this moment to stop more will not, because the site enough literature to establish advisers). At the time the leave all options blank. You can call them whatever you like. The end result is the following:

    
    
    
    #property copyright Copyright, Dmitry Iglakov 2015. "
    #property link      "cjdmitri@gmail.com"
    #property version   "1.00"
    #property 
    
    
    
    strict int OnInit ()
      {
    
    
    
       return(INIT_SUCCEEDED);
      }
    
    
    
     void OnDeinit(const int reason) {}
    
    
    
     void OnTick() {}
    

    graphic design Migration model in MQL4 algorithms

    after the establishment of the expert advisor, you must define the pattern of “Absorption” after the closure of the candles. To this end, we are introducing new variables and assign values to them. See the following code:

    
    
    
    #property copyright Copyright, Dmitry Iglakov 2015. "
    #property link      "cjdmitri@gmail.com"
    #property version   "1.00"
    #property 
    
    a strict double   open1, standard,    
    close1, close2, low2, low1, high1, high2;    
    
    
    
    int OnInit () {
       return(INIT_SUCCEEDED);
      }
    
    
    
     void OnDeinit(const int reason) {}
    
    
    
     void OnTick() {open1 = by NormalizeDouble (iOpen (Sym BOL Period(), 1), Digits);
       standard = by NormalizeDouble (iOpen (Symbol Period(), 2), Digits);
       close1 = by NormalizeDouble (iClose (Symbol Period(), 1), Digits);
       close2 = by NormalizeDouble (iClose (Symbol Period(), 2), Digits);
       low1 = by NormalizeDouble (iLow (Symbol Period(), 1), Digits);
       low2 = by NormalizeDouble (iLow (Symbol Period(), 2), Digits);
       high1 = by NormalizeDouble (iHigh (Symbol Period(), 1), Digits);
       high2 = by NormalizeDouble (iHigh (Symbol Period(), 2), Digits);
      }
    

    Find both types of pattern “Absorption”:

     void OnTick() {open1 = by NormalizeDouble (iOpen (Symbol Period(), 1), Digits);
       standard = by NormalizeDouble (iOpen (Symbol Period(), 2), Digits);
       close1 = by NormalizeDouble (iClose (Symbol Period(), 1), Digits);
       close2 = by NormalizeDouble (iClose (Symbol Period(), 2), Digits);
       low1 = by NormalizeDouble (iLow (Symbol Period(), 1), Digits);
       low2 = by NormalizeDouble (iLow (Symbol Period(), 2), Digits);
       high1 = by NormalizeDouble (iHigh (Symbol Period(), 1), Digits);
       high2 = by NormalizeDouble (iHigh (Symbol Period(), 2), Digits);
    
       if(low1 < low2 & &	//minimum first bar below the minimum of the second bar
          high1 > high2 & &	//Max first bar above the maximum of the second
          close1 < standard & &	//closing price p 1 bar is lower than the opening price of the second
          open1 > close1 & &	//1st bar bear
          standard < close2)	//Second bull bar
         {}

    in the same way we find a bullish pattern:

       if(low1 < low2 &&    
          high1 > high2 & & close1 > standard & & open1 < close1 && 
          open2 > close2) {}
    • Create user-configurable variables: stop orders, slippage, expiry time orders, magic room EA, trading l From. stop-loss can not specify, as will install it according to the rules of the pattern.
    • enter the local variables to cast variables in normal view.
    • Moreover, we remember that the stop orders are set on a specific interval from bar prices. To do this, enter the input variable Intervalwhich is responsible for the interval between the minimum/maximum of the bar and stop orders, as well as the placing of a pending order price.
    • enter the variable timeBUOVB_BEOVBwhich is responsible for preventing the reopening of warrants of this pattern.
    • enter the variable bar1size to verify that the external bar has a fairly large size. Thus, we can assume that the market is not in the flat.

    as a result, we get the following code:

    
    
    
    #property copyright Copyright, Dmitry Iglakov 2015. "
    #property link      "cjdmitri@gmail.com"
    #property version   "1.00"
    #property 
    
    extern strict int     interval = 25;                               
    extern   double lot = 0.1;                              
    extern int     TP = 400;                              
    extern int     magic = 962231;                           
    extern int     = slippage 2;                                
    extern int     ExpDate = 48;                               
    extern int     bar1size = 900;                              
    
       double buyPrice, buyTP, buySL, sellPrice, sellTP, sellSL;     
    
       double open1, standard, close1, close2, low2, low1, high1, high2;    
    
    datetime _ExpDate =0;       
       double _bar1size;        
     datetime timeBUOVB_BEOVB;  
    
    
    
    int OnInit () {
       return(INIT_SUCCEEDED);
      }
    
    
    
     void OnDeinit(const int reason) {}
    
    
    
     void OnTick() {
       double   _bid = by NormalizeDouble(MarketInfo (Symbol(), MODE_BID), Digits); 
       double   = _ask NormalizeDouble(MarketInfo (Symbol(), MODE_ASK) Digits); 
          double _point = MarketInfo (Symbol(), MODE_POINT);
    
       open1 = by NormalizeDouble (iOpen (Symbol Period(), 1), Digits);
       standard = by NormalizeDouble (iOpen (Symbol Period(), 2), Digits);
       close1 = by NormalizeDouble (iClose (Symbol Period(), 1), Digits);
       close2 = by NormalizeDouble (iClose (Symbol Period(), 2), Digits);
       low1 = by NormalizeDouble (iLow (Symbol Period(), 1), Digits);
       low2 = by NormalizeDouble (iLow (Symbol Period(), 2), Digits);
       high1 = by NormalizeDouble (iHigh (Symbol Period(), 1), Digits);
       high2 = by NormalizeDouble (iHigh (Symbol Period(), 2), Digits);
    
       _bar1size =by NormalizeDouble (((high1-low1)/_point),0);
    
       if (timeBUOVB_BEOVB! = iTime (SymbolPeriod(),1) & & _bar1size > bar1size & & low1 < low2 &&    
          high1 > high2 & & close1 < open2 && 
          open1 > close1 & & ope N2 < close2) {timeBUOVB_BEOVB = iTime (SymbolPeriod(),1); 
         }
    
       if (timeBUOVB_BEOVB! = iTime (SymbolPeriod(),1) & & _bar1size > bar1size & & low1 < low2 &&    
          high1 > high2 & & close1 > standard & & open1 < close1 && 
          open2 > close2) {timeBUOVB_BEOVB = iTime (SymbolPeriod(),1); 
         }}
    

    definition of levels of stop orders

    we have fulfilled all conditions and found a high quality patterns. Now you need to define the pattern for each levels of stop orders and prices of pending orders, as well as the expiration date of the warrant.

    in the body of the function OnTick () write the following code:

       =buyPrice NormalizeDouble(high1 + _point * intervalDigits); 
       buySL =by NormalizeDouble (low1-interval * _point,Digits);     
       buyTP =by NormalizeDouble (buyPrice + TP * _point,Digits);       
       _ExpDate =TimeCurrent() + ExpDate *60*60;                   
    
       sellPrice =by NormalizeDouble (low1-interval * _point,Digits);
       sellSL =by NormalizeDouble (high1 + _point * intervalDigits);
       sellTP =by NormalizeDouble (sellPrice-TP * _point,Digits);

    work on mistakes of execution

    If you ever develop expert advisors, you know that when you open and install orders fairly frequently encountered errors, such as a timeout, wrong foot and many other. To exclude them, write a separate function, which integrate a small handler for basic errors.

    
    
    
    
    
    
    
    
    
    
    
    
    
    int OrderOpenF (string     OO_symbol
                   int        OO_cmd
                   double     OO_volume
                   double     OO_ price
                   int        OO_slippage
                   double     OO_stoploss
                   double     OO_takeprofit
                   string     OO_comment
                   int        OO_magic,
                   datetime   OO_expiration
                   color      OO_arrow_color) {
       int      result =-1;    
       int      Error = 0;     
       int      attempt 0 =;     
       int      attemptMax = 3;     
       bool     exit_loop = false; 
       string   lang= TerminalInfoString(TERMINAL_LANGUAGE);  
       double   stopllvl =by NormalizeDouble (MarketInfo (OO_symbol, MODE_STOPLEVEL) * MarketInfo (OO_symbol, MODE_POINT),Digits);  
                                                                                                                         
    
       if(OO_cmd == OP_BUY | OO_cmd = OP_BUYLIMIT | OO_cmd == OP_BUYSTOP) {
          doubLe tp = (OO_takeprofit-OO_price)/MarketInfo (OO_symbol, MODE_POINT);
           double sl = (OO_price-OO_stoploss)/MarketInfo (OO_symbol, MODE_POINT);
          if(tp >0 & & tp < = stopllvl) {OO_takeprofit = OO_price + stopllvl +2* MarketInfo (OO_symbol, MODE_POINT);
            }
          if(sl> 0 & & sl < = stopllvl) {OO_stoploss = OO_price-(stopllvl +2* MarketInfo (OO_symbol, MODE_POINT));
            }}
    
       if (OO_cmd == OP_SELL | OO_cmd = OP_SELLLIMIT | OO_cmd == OP_SELLSTOP) {
          double tp = (OO_price-OO_takeprofit)/MarketInfo (OO_symbol, MODE_POINT);
           double sl = (OO_stoploss-OO_price)/MarketInfo (OO_symbol, MODE_POINT);
          if(tp >0 & & tp < = stopllvl) {OO_takeprofit = OO_price-(stopllvl +2* MarketInfo (OO_symbol, MODE_POINT));
            }
          if(sl> 0 & & sl < = stopllvl) {OO_stoploss = OO_price + stopllvl +2* MarketInfo (OO_symbol, MODE_POINT);
            }}
    
       while(! exit_loop) {result =OrderSend(OO_symbol, OO_cmd, OO_volume, OO_price, OO_slippage, OO_stoploss, OO_takeprofit, OO_comment, OO_magic, OO_expiration, OO_arrow_color); 
          
          if (result0 <) {Error = GetLastError ();                                     
             switch(Error) {                                                         
                case  2:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Sleep(3000);                                       
                      Refreshrates();
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt =0;                                         
                      exit_loop = true;                                  
                      break;                                             
                     }
                case  3: refreshrates();
                   exit_loop = true;                                     
                   break;                                                
                case  4:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Sleep(3000);                                       
                      Refreshrates();
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case  5: = exit_loop true;                                     
                   break;                                                
                case  6:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Sleep(5000);                                       
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case  8:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Sleep(7000);                                       
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case 64: = exit_loop true;                                     
                   break;                                                
                case 65: = exit_loop true;                                     
                   break;                                                
                case 128:
                   Sleep(3000);
                   Refreshrates();
                   continue;                                             
                case 129:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Sleep(3000);                                       
                      Refreshrates();
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case 130: = exit_looptrue;                                       
                   break;
                 case 131: = exit_loop true;                                     
                   break;                                                
                case 132:
                   Sleep(10000);                                         
                   Refreshrates();                                       
                   
                   break;                                                
                case 133: = exit_looptrue;                                       
                   break;                                                
                case 134: = exit_looptrue;                                       
                   break;                                                
                case 135:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Refreshrates();
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case 136:
                   if(attempt < attemptMax) {attempt = attempt +1;                                 
                      Refreshrates();
                      break;                                             
                     }
                   if(attempt == attemptMax) {attempt = 0;                                       
                      exit_loop = true;                                  
                      break;                                             
                     }
                case 137:
                   if(attempt < attemptMax) {attempt = attempt +1;
                      Sleep(2000);
                      Refreshrates();
                      break;
                     }
                   if(attempt == attemptMax) {attempt =0;
                      exit_loop =true;
                      break;
                     }
                case 138:
                   if(attempt < attemptMax) {attempt = attempt +1;
                      Sleep(1000);
                      Refreshrates();
                      break;
                     }
                   if(attempt == attemptMax) {attempt =0;
                      exit_loop =true;
                      break;
                     }
                case 139: = exit_looptrue;
                   break;
                case 141:
                   Sleep(5000);
                   exit_loop =true;
                   break;
                case 145: = exit_looptrue;
                   break;
                case 146:
                   if(attempt < attemptMax) {attempt = attempt +1;
                      Sleep(2000);
                      Refreshrates();
                      break;
                     }
                   if(attempt == attemptMax) {attempt =0;
                      exit_loop =true;
                      break;
                     }
                case 147:
                   if(attempt < attemptMax) {attempt = attempt +1;
                      OO_expiration =0;
                      break;
                     }
                   if(attempt == attemptMax) {attempt =0;
                      exit_loop =true;
                      break;
                     }
                case 148: = exit_looptrue;
                   break;
                default:
                   Print(Error: "Error);
                   exit_loop =true; 
                   break;          
               }}
          
          else
            {
             if(lang = "Russian") {Print("order is successfully opened."result);}
             if(lang = "English") {Print("The order is successfully opened."result);}
             Error = 0;                                
             break;                                    
             
            }}
       return(result);
      }
    

    as a result of all actions get the following code:

    
    
    
    #property copyright Copyright, Dmitry Iglakov 2015. "
    #property link      "cjdmitri@gmail.com"
    #property version   "1.00"
    #property 
    
    extern strict int     interval = 25;                               
    extern   double lot = 0.1;                              
    extern int     TP = 400;                              
    extern int     magic = 962231;                           
    extern int     = slippage 2;                                
    extern int     ExpDate = 48;                               
    extern int     bar1size = 900;                              
    
       double buyPrice, buyTP, buySL, sellPrice, sellTP, sellSL;     
    
       double open1, standard, close1, close2, low2, low1, high1, high2;    
    
    datetime _ExpDate =0;       
       double _bar1size;        
     datetime timeBUOVB_BEOVB;  
    
    
    
    int OnInit () {
       return(INIT_SUCCEEDED);
      }
    
    
    
     void OnDeinit(const int reason) {}
    
    
    
     void OnTick() {
       double   _bid = by NormalizeDouble(MarketInfo (Symbol(), MODE_BID), Digits); 
       double   = _ask NormalizeDouble(MarketInfo (Symbol(), MODE_ASK) Digits); 
          double _point = MarketInfo (Symbol(), MODE_POINT);
    
       open1 = by NormalizeDouble (iOpen (Symbol Period(), 1), Digits);
       standard = by NormalizeDouble (iOpen (Symbol Period(), 2), Digits);
       close1 = by NormalizeDouble (iClose (Symbol Period(), 1), Digits);
       close2 = by NormalizeDouble (iClose (Symbol Period(), 2), Digits);
       low1 = by NormalizeDouble (iLow (Symbol Period(), 1), Digits);
       low2 = by NormalizeDouble (iLow (Symbol Period(), 2), Digits);
       high1 = by NormalizeDouble (iHigh (Symbol Period(), 1), Digits);
       high2 = by NormalizeDouble (iHigh (Symbol Period(), 2), Digits);
       
    
       buyPrice =by NormalizeDouble (high1 + _point * intervalDigits); 
       buySL =by NormalizeDouble (low1-interval * _point,Digits);     
       buyTP =by NormalizeDouble (buyPrice + TP * _point,Digits);       
       _ExpDate =TimeCurrent() + ExpDate *60*60;                   
    
       sellPrice =(low1-interval * _point,Digits);
       sellSL =by NormalizeDouble (high1 + _point * intervalDigits);
       sellTP =by NormalizeDouble (sellPrice-TP * _point,Digits);
    
       _bar1size =by NormalizeDouble (((high1-low1)/_point),0);
    
       if (timeBUOVB_BEOVB! = iTime (SymbolPeriod(),1) & & _bar1size > bar1size & & low1 < low2 &&    
          high1 > high2 & & close1 < open2 && 
          open1 > close1 & & ope N2 < close2) {OrderOpenF (Symbol(), OP_SELLSTOP, lot, sellPrice, slippage, sellSL, sellTP,NULL,magic, _ExpDate, Blue);
          timeBUOVB_BEOVB = iTime (SymbolPeriod(),1); 
         }
    
       if (timeBUOVB_BEOVB! = iTime (SymbolPeriod(),1) & & _bar1size > bar1size & & low1 < low2 &&    
          high1 > high2 & & close1 > standard & & open1 < close1 && 
          open2 > close2) {OrderOpenF (Symbol(), OP_BUYSTOP, lot, buyPrice, slippage, buySL, buyTP,NULL,magic, _ExpDate, Blue);
          timeBUOVB_BEOVB = iTime (SymbolPeriod(),1); 
         }}
    

    carry out compilation. Check for errors in the log entries.

    testing Check expert advisor on health and no errors. Run the tester and set the input parameters.

    < img src = “https://c.mql5.com/2/19/settings.png” title=”Figure. 5. Input parameters for testing” alt=”Figure. 5. Input parameters for testing” height=”355″ width=”574″ style=”vertical-align:middle;”/>

    Figure. 5. Input parameters for testing

    1. Select a currency pair for testing. I chose EURAUD.
    2. be sure to select the model “every tick” test, as well as point out that testing will be on historical data. I opted for the whole year of 2014.
    3. Ukazyvam D1.
    4. start the testing.
    5. when the test is complete, check the log. As a result, we see that there were no errors when testing performance.

    here’s a sample of the log after the test:

    Figure. 7. Magazine Advisor

    Figure. 7. Magazine Advisor

    making sure there are no mistakes, spend optimization Advisor.

    Optimization to optimize Adviser I chose the following parameters:

    < img src = “https://c.mql5.com/2/19/optimis__1.png” title=”Figure. 8. The optimization parameters ” alt=”Figure. 8. The optimization parameters ” height=”348″ width=”574″ style=”vertical-align:middle;”/>

    Figure. 8. The optimization parameters

    Figure. 9. setting up optimization

    Figure. 9. setting up optimization

    as a result of optimization and testing we get quite a working robot.

    the results of optimization and testing

    after spending optimization on the most popular currency pairs, we get the following results:

    pair net income Profitability Drawdown (%) gross profit gross loss
    EURAUD $523.90 2.13 3.70 $727.98 $196.86
    USDCHF $454.19 $454.19 2.25 $0.00
    $638.71 GBPUSD 1.50 $638.71 $0.00
    $638.86 EURUSD 1.85 $638.86 0.00 $
    USDJPY $423.85 5.15 2.36 $525.51 $102.08
    USDCAD $198.82 2.41 2.74 $379.08 $180.26
    AUDUSD $136.14 1.67 2.39 $339.26 $203.12

    Tab. 1. The optimization results

    More detailed results of the testing on the currency pair

    : EURAUD Figure. 10. Test results

    Figure. 10. Test results

    Figure. 11. the schedule of test results

    Figure. 11. the schedule of test results

    Conclusion

    1. for the purposes of this article, we have created a working trading expert advisor on the pattern of “Absorption””.
    2. we have seen that even without additional filters for market entry patterns of Price Action.
    3. we proved efficiency, without resorting to tricks and gimmicks, such as Martingale, averaging and so on.
    4. thanks to the proper installation of stop orders we have minimized the drawdown.
    5. We do not resort to the help of technical indicators, and created the Adviser solely on reading “bare” graphics.

    thanks for listening, I hope the article was useful.

    1 Comment
    • Alex 8:36 am September 27, 2018 Reply

      Thanks to Konstantin for an interesting and informative article, everything is chewed and explained as a beginner to learn Price Action.

    Write a comment