Price Action. Automation of trading on the internal bar
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 “inner bar” and create an expert who will keep track of this pattern and its grounds make trade decisions.
About Price Action
what is Price Action? This bezyndikatornyj method for the determination of price movement. The definition is due to the resulting complex and simple patterns, as well as building support graphic elements on the chart (horizontal, vertical, and trend lines, Fibonacci retracements, support/resistance levels and so on) .
at first sight seem difficult method, but it is only at first glance. The advantages of this method are obvious, for example, when compared with methods that use technical indicators. No wonder the Price Action method with each year is gaining popularity among traders.
Internal bar
Inner bar (Inside Bar) is a bar, body and shadow which are entirely within the range of the previous (defines) the bar. Maximum internal bar is below the maximum and minimum is higher than the minimum defines bar. Defines the bar and is often referred to as the measurement. As the pattern and potential entry signal considering internal bar, together with determining.
in making trading decisions should be borne in mind that the pattern of bilateral and may indicate how the reversal and continuation of the trend.
Figure. 1. internal View bar on the chart
Figure. 2. Schematic image of the inner bar
internal Rules of the bar:
- work with pattern “bar” should be at the senior interim charts: H4, D1.
- Pattern can be either a turn, and a continuation of the trend.
- 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.
- Internal bars, repeated in the flat, it is not necessary to use as a signal to the entrance of the market.
Figure. 3. Definition of quality domestic bar on the chart of GBPUSD D1
based on the above rules, define a quality inner bar. The graph shows that after falling sharply formed bull bar, completely absorbed in determining. As proof — pattern formed on the level of support. The third confirmation is that the pattern was not formed in a flat. So it follows that pattern meets the three regulations, and therefore it should be considered quality.
Define entry points, setting of stop orders
we found on the chart (fig. 3) internal quality bar. How should enter the market and where the display stop orders? Let’s take a look at Figure 4.
Figure. 4. installation a Buy Stop orders and stop orders
consider the entry rules and stop-orders in the above example:
- Set the pending order Buy Stop at a price slightly above the prices High (on a few items for confirmation) defines the bar .
- the Stop Loss level set below the support level and below prices Low defines the bar. This gives us additional protection in case of pending orders and reversal when the price may bounce off the support level and resume movement in the right direction.
- the Take Profit Level set, before reaching the nearest resistance level.
we also remember that the inner bar may be a harbinger of how the reversal and continuation of the trend. Therefore, it makes sense to install a Sell Stop order.
Figure. 5. setting the order Sell Stop orders and stop orders
consider the entry rules and stop-orders in the above example:
- Set the pending order Sell Stop at a price slightly below the prices Low (on a few items for confirmation) defines the bar.
- the Stop Loss level set High prices above defines the bar.
- the Take Profit Level set, before reaching the nearest support level.
creating an expert advisor to trade on the internal bar
having examined the above material, we have learned to find high-quality domestic bar on the graph, learned how to properly and safely enter the market, as well as determined the levels of stop orders to limit potential loss or profit.
Next we will try to realize algorithms of Adviser and automate internal trade bar.
Open MetaEditor from 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
so we created expert advisor. Now we need to define an internal bar after closing. 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); }
as an example, we look at one of the internal design of the bar, when specifying the bar bear (2 bar), and the inner bull bar (bar 1). To do this, write a few conditions in the body of the function OnTick ():
void OnTick() {open1 = by NormalizeDouble (iOpen (Symbol(), Period 1), Digits); standard = by NormalizeDouble (iOpen (Symbol Period(), 2), Digits); close1 = 9459029(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(standard > close2 & & close1 > open1 & & high2 > high1 & & standard > close1 & & low2 < low1) {}}
- Create user-configurable variables: stop orders, slippage, expiry time Ord exponential, magic number Adviser, trade lot. stop-loss can not specify, as will install it on the internal rules of the bar.
- 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 timeBarInsidewhich is responsible for preventing the reopening of warrants of this pattern.
- enter the variable bar2size to verify that defines the 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 = 20; extern double lot = 0.1; extern int TP = 300; extern int magic = 555124; extern int = slippage 2; extern int ExpDate = 48; extern int bar2size = 800; double buyPrice, buyTP, buySL, sellPrice, sellTP, sellSL; double open1, standard, close1, close2, low2, low1, high1, high2; datetime _ExpDate =0; double _bar2size; datetime timeBarInside; 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); _bar2size =by NormalizeDouble (((high2-low2)/_point),0); if (timeBarInside! = iTime (SymbolPeriod(),1) & & _bar2size > bar2size & & standard > close2 & & close1 > open1 & & high2 > high1 & & standard > close1 & & low2 < low1) {timeBarInside = iTime (SymbolPeriod(),1); }}
definition of levels of stop orders
After all preparations we need only determine levels of stop orders and order prices. Do not forget also about calculating the expiry date of the warrant.
in the body of the function OnTick () write the following code:
=buyPrice NormalizeDouble(high2 + _point * intervalDigits); buySL =by NormalizeDouble (low2-interval * _point,Digits); buyTP =by NormalizeDouble (buyPrice + TP * _point,Digits); _ExpDate =TimeCurrent() + ExpDate *60*60; sellPrice =by NormalizeDouble (low2-interval * _point,Digits); sellSL =by NormalizeDouble (high2 + _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 =(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 = 20; extern double lot = 0.1; extern int TP = 300; extern int magic = 555124; extern int = slippage 2; extern int ExpDate = 48; extern int bar2size = 800; double buyPrice, buyTP, buySL, sellPrice, sellTP, sellSL; double open1, standard, close1, close2, low2, low1, high1, high2; datetime _ExpDate =0; double _bar2size; datetime timeBarInside; 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); _bar2size =by NormalizeDouble (((high2-low2)/_point),0); if (timeBarInside! = iTime (SymbolPeriod(),1) & & _bar2size > bar2size & & standard > close2 & & close1 > open1 & & high2 > high1 & & standard > close1 & & low2 < low1) {buyPrice =by NormalizeDouble (high2 + _point * intervalDigits); buySL =by NormalizeDouble (low2-interval * _point,Digits); buyTP =by NormalizeDouble (buyPrice + TP * _point,Digits); _ExpDate =TimeCurrent() + ExpDate *60*60; sellPrice =by NormalizeDouble (low2-interval * _point,Digits); sellSL =by NormalizeDouble (high2 + _point * intervalDigits); sellTP =by NormalizeDouble (sellPrice-TP * _point,Digits); OrderOpenF (Symbol(), OP_BUYSTOP, lot, buyPrice, slippage, buySL, buyTP,NULL,magic, _ExpDate, Blue); OrderOpenF (Symbol(), OP_SELLSTOP, lot, sellPrice, slippage, sellSL, sellTP,NULL,magic, _ExpDate, Blue); timeBarInside = 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. I installed the following:
< img src = “https://c.mql5.com/2/18/param.png” title=”input parameters for testing” alt=”input parameters for testing” height=”355″ width=”574″ style=”vertical-align:middle;”/>
Figure. 6. Input parameters for testing
- Select a currency pair for testing. I chose CADJPY.
- 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/18/optimis.png” title=”” alt=”optimization options Parameters optimization” height=”355″ 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
Figure. 10. Test results
Figure. 11. the schedule of test results
Conclusion
- for the purposes of this article, we have created a working Counsellor, which trades on the internal bar.
- 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.