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
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
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. 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):
- Set the pending order Buy Sto p costs just above the prices High (on a few items for confirmation) the outer bar.
- the Stop Loss level set Low prices below the outer bar.
- the Take Profit Level set, before reaching the nearest resistance level.
identification of entry points for the “BEOVB” installation of 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):
- Set the pending order Sell Stop at a price slightly below the prices Low (a few points, to confirm) the outer bar.
- the Stop Loss level set High prices above the outer bar.
- 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
- Select a currency pair for testing. I chose EURAUD.
- 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.
- Ukazyvam D1.
- start the testing.
- 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
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
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
Figure. 10. Test results
Figure. 11. the schedule of test results
Conclusion
- for the purposes of this article, we have created a working trading expert advisor on the pattern of “Absorption””.
- we have seen that even without additional filters for market entry patterns of Price Action.
- we proved efficiency, without resorting to tricks and gimmicks, such as Martingale, averaging and so on.
- thanks to the proper installation of stop orders we have minimized the drawdown.
- 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.
Thanks to Konstantin for an interesting and informative article, everything is chewed and explained as a beginner to learn Price Action.