Price Action. Automating the Inside Bar Trading Strategy
Introduction
All Forex traders come across the Price Action at some point. This is not a mere chart analysis technique but the entire system for defining the possible future price movement direction. In this article, we will look at the Inside Bar pattern in details and develop an EA for tracking the Inside Bar and performing trades based on the pattern.
About Price Action
The Price Action is a non-indicator price movement detection method using simple and complex patterns, as well as auxiliary chart elements (horizontal, vertical and trend lines, Fibo levels, support/resistance levels, etc.).
At first glance, the method may seem rather complicated but actually this is not the case. The method is gaining popularity from year to year, since its advantages are evident, for example, when compared to the methods involving technical indicators.
Inside Bar
Inside Bar is a bar having its body and wicks contained entirely within the range of the previous (mother) bar. The inside bar's High lies lower and Low is located higher than the mother bar's ones. Mother and inside bars form a pattern considered to be a potential entry signal.
This is a two-sided pattern, since it may indicate either a reversal, or a trend continuation.
Fig. 1. Inside bar
Fig. 2. Inside Bar pattern layout
Inside bar rules:- The Inside Bar pattern is significant on higher timeframes, like H4 or D1.
- The pattern can indicate either a trend reversal or a continuation.
- Apply additional graphical analysis tools for more precise entry, including trend lines, support/resistance levels, Fibo levels, other Price Action patterns, etc.
- Use pending orders to avoid premature or false market entries.
- Do not use inside bars repeatedly occurring in the flat market as market entry signals.
Fig. 3. Defining the genuine inside bar on GBPUSD D1
Keeping all this in mind, let's try to define a genuine inside bar. On the above chart, we can see that a bullish bar was formed after the sharp downward movement. However, the bar lies completely within the boundaries of the previous one. The pattern is confirmed by the fact that it is formed at the support level. The third confirmation is the absence of flat. Since the pattern satisfies the rules, it can be considered genuine.
Defining Entry Points and Setting Stop Orders
So, we have found a genuine inside bar on the chart (Fig. 3). How should we enter the market and where should we set our stop orders? Let's examine the Figure 4.
Fig. 4. Setting Buy Stop and stop orders
First, we should consider the stop level setting rules using the example above:
- Set a Buy Stop pending order slightly higher than a mother bar's High price (only several points higher, for confirmation).
- Set a Stop Loss level below a support level, as well as a mother bar's Low price. This is an additional protection in case a pending order is triggered and the price reaches the support level just to bounce back and start moving in the right direction later on.
- Set a Take Profit level slightly lower than the nearest resistance level.
Fig. 5. Setting Sell Stop and stop orders
First, we should consider the stop level setting rules using the example above:
- Set a Sell Stop pending order slightly lower than a mother bar's Low price (only several points lower, for confirmation).
- Set a Stop Loss level above a mother bar's High price.
- Set a Take Profit level slightly higher than the nearest support level.
Developing an Expert Advisor Based on Inside Bar Trading
Now that we know all the necessary rules of defining a genuine inside bar, entering the market and setting stop orders, we can finally implement the appropriate Expert Advisor that will trade using the Inside Bar pattern.
Open MetaEditor from the MetaTrader 4 terminal and create a new Expert Advisor (I believe, I do not have to dwell upon this, since the website provides plenty of information on how to create an Expert Advisor). All parameters are left blank at this stage. You can name them whatever you like. The resulting code will look as follows:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+
Converting the Pattern into MQL4 Algorithm
After we have created the EA, we need to define an inside bar after a candle is closed. To do this, we introduce new variables and assign values to them. See the code below:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); } //+------------------------------------------------------------------+
As an example, let's consider that a mother bar is bearish (bar 2), while an inside one is bullish (bar 1). Let's add a number of conditions to the OnTick() function body:
void OnTick() { //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- if the second bar is bearish, while the first one is bullish if(open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first bar's Close low2<low1) //the second bar's Low is lower than the first bar's Low { //--- we have listed all the conditions defining that the first bar is completely within the second one } }
- Create customizable variables: stop orders, slippage, order expiration time, EA magic number, trading lot. Stop loss may be omitted, since it is to be defined according to the inside bar rules.
- Enter local variables to normalize the look of the variables.
- Stop orders are set at a certain distance from the bar price values. In order to implement that, add the Interval variable responsible for the interval between High/Low prices of bars and stop order levels, as well as pending order levels.
- Add the timeBarInside variable to avoid order re-opening on this pattern.
- Add the bar2size variable to ensure that a mother bar is big enough, which is a good sign that the current market is not flat.
As a result, we obtain the following code:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict extern int interval = 20; //Interval extern double lot = 0.1; //Lot Size extern int TP = 300; //Take Profit extern int magic = 555124; //Magic number extern int slippage = 2; //Slippage extern int ExpDate = 48; //Expiration Hour Order extern int bar2size = 800; //Bar 2 Size double buyPrice,//define BuyStop price buyTP, //Take Profit BuyStop buySL, //Stop Loss BuyStop sellPrice, //define SellStop price sellTP, //Take Profit SellStop sellSL; //Stop Loss SellStop double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price datetime _ExpDate=0; //local variable to define a pending order expiration time double _bar2size; datetime timeBarInside; //time of the bar, at which inside bar orders were opened, to avoid re-opening //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double _bid = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //define a lower price double _ask = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //define an upper price double _point = MarketInfo(Symbol(), MODE_POINT); //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- _bar2size=NormalizeDouble(((high2-low2)/_point),0); //--- if the second bar is bearish, while the first one is bullish if(timeBarInside!=iTime(Symbol(),Period(),1) && //no orders have been opened at this pattern yet _bar2size>bar2size && //the second bar is big enough, so the market is not flat open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first one's Close low2<low1) //the second bar's Low is lower than the first one's Low { //--- we have listed all the conditions defining that the first bar is completely within the second one timeBarInside=iTime(Symbol(),Period(),1); //indicate that orders are already placed on this pattern } } //+------------------------------------------------------------------+
Defining Stop Order Levels
Now that all preparations are complete, we only have to define stop order levels and order prices. Also, do not forget about an order expiration time calculation.
Let's add the following code to the OnTick() function body:
buyPrice=NormalizeDouble(high2+interval*_point,Digits); //define an order price considering the interval buySL=NormalizeDouble(low2-interval*_point,Digits); //define a stop loss considering the interval buyTP=NormalizeDouble(buyPrice+TP*_point,Digits); //define a take profit _ExpDate=TimeCurrent()+ExpDate*60*60; //a pending order expiration time calculation sellPrice=NormalizeDouble(low2-interval*_point,Digits); sellSL=NormalizeDouble(high2+interval*_point,Digits); sellTP=NormalizeDouble(sellPrice-TP*_point,Digits);
Correction of Execution Errors
If you have ever engaged in the development of Expert Advisors, you probably know that errors often happen when closing and setting orders, including waiting time, incorrect stops, etc. To eliminate such errors, we should write a separate function with a small built-in handler of basic errors.
//+----------------------------------------------------------------------------------------------------------------------+ //| The function opens or sets an order | //| symbol - symbol, at which a deal is performed. | //| cmd - a deal (may be equal to any of the deal values). | //| volume - amount of lots. | //| price - Open price. | //| slippage - maximum price deviation for market buy or sell orders. | //| stoploss - position close price when an unprofitability level is reached (0 if there is no unprofitability level).| //| takeprofit - position close price when a profitability level is reached (0 if there is no profitability level). | //| comment - order comment. The last part of comment can be changed by the trade server. | //| magic - order magic number. It can be used as a user-defined ID. | //| expiration - pending order expiration time. | //| arrow_color - open arrow color on a chart. If the parameter is absent or equal to CLR_NONE, | //| the open arrow is not displayed on a chart. | //+----------------------------------------------------------------------------------------------------------------------+ 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; //result of opening an order int Error = 0; //error when opening an order int attempt = 0; //amount of performed attempts int attemptMax = 3; //maximum amount of attempts bool exit_loop = false; //exit the loop string lang=TerminalInfoString(TERMINAL_LANGUAGE); //trading terminal language, for defining the language of the messages double stopllvl=NormalizeDouble(MarketInfo(OO_symbol,MODE_STOPLEVEL)*MarketInfo(OO_symbol,MODE_POINT),Digits); //minimum stop loss/ take profit level, in points //the module provides safe order opening. //--- check stop orders for buying 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)); } } //--- check stop orders for selling 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 loop 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); //attempt to open an order using the specified parameters //--- if there is an error when opening an order if(result<0) { Error = GetLastError(); //assign a code to an error switch(Error) //error enumeration { //order closing error enumeration and an attempt to fix them case 2: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt=0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 3: RefreshRates(); exit_loop = true; //exit while break; //exit switch case 4: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 5: exit_loop = true; //exit while break; //exit switch case 6: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(5000); //3 seconds of delay break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 8: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(7000); //3 seconds of delay break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 64: exit_loop = true; //exit while break; //exit switch case 65: exit_loop = true; //exit while break; //exit switch case 128: Sleep(3000); RefreshRates(); continue; //exit switch case 129: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 130: exit_loop=true; //exit while break; case 131: exit_loop = true; //exit while break; //exit switch case 132: Sleep(10000); //sleep for 10 seconds RefreshRates(); //update data //exit_loop = true; //exit while break; //exit switch case 133: exit_loop=true; //exit while break; //exit switch case 134: exit_loop=true; //exit while break; //exit switch case 135: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //set the number of attempts to zero exit_loop = true; //exit while break; //exit switch } case 136: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //set the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } 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_loop=true; break; case 141: Sleep(5000); exit_loop=true; break; case 145: exit_loop=true; 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_loop=true; break; default: Print("Error: ",Error); exit_loop=true; //exit while break; //other options } } //--- if no errors detected else { if(lang == "Russian") {Print("Ордер успешно открыт. ", result);} if(lang == "English") {Print("The order is successfully opened.", result);} Error = 0; //reset the error code to zero break; //exit while //errorCount =0; //reset the amount of attempts to zero } } return(result); } //+------------------------------------------------------------------+
As a result, we obtain the following code:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict extern int interval = 20; //Interval extern double lot = 0.1; //Lot Size extern int TP = 300; //Take Profit extern int magic = 555124; //Magic number extern int slippage = 2; //Slippage extern int ExpDate = 48; //Expiration Hour Order extern int bar2size = 800; //Bar 2 Size double buyPrice,//define BuyStop price buyTP, //Take Profit BuyStop buySL, //Stop Loss BuyStop sellPrice, //define SellStop price sellTP, //Take Profit SellStop sellSL; //Stop Loss SellStop double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price datetime _ExpDate=0; //local variable to define a pending order expiration time double _bar2size; datetime timeBarInside; //time of the bar, at which inside bar orders were opened, to avoid re-opening //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double _bid = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //define a lower price double _ask = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //define an upper price double _point = MarketInfo(Symbol(), MODE_POINT); //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- _bar2size=NormalizeDouble(((high2-low2)/_point),0); //--- if the second bar is bearish, while the first one is bullish if(timeBarInside!=iTime(Symbol(),Period(),1) && //no orders have been opened at this pattern yet _bar2size>bar2size && //the second bar is big enough, so the market is not flat open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first one's Close low2<low1) //the second bar's Low is lower than the first one's Low { buyPrice=NormalizeDouble(high2+interval*_point,Digits); //define an order price considering the interval buySL=NormalizeDouble(low2-interval*_point,Digits); //define a stop loss considering the interval buyTP=NormalizeDouble(buyPrice+TP*_point,Digits); //define a take profit _ExpDate=TimeCurrent()+ExpDate*60*60; //pending order expiration time calculation sellPrice=NormalizeDouble(low2-interval*_point,Digits); sellSL=NormalizeDouble(high2+interval*_point,Digits); sellTP=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); //--- we have listed all the conditions defining that the first bar is completely within the second one timeBarInside=iTime(Symbol(),Period(),1); //indicate that orders are already placed on this pattern } } //+------------------------------------------------------------------+
Now, let's perform the compilation and check for error messages in the log.
Testing the Expert Advisor
It is time to test our Expert Advisor. Let's launch the strategy tester and set the input parameters. I have specified the parameters as follows:
Fig. 6. Input parameters for testing
- Select a symbol (it is CADJPY in my case).
- Be sure to set "Every tick" mode and define that testing is to be performed on history data. I have selected the entire year of 2014.
- Set D1 timeframe.
- Launch the test.
- After the test is complete, check the log. As we can see, no execution errors have occurred in the process.
Below is the EA testing journal:
Fig. 7. Expert Advisor testing journal
Make sure there are no mistakes and optimize the EA.
Optimization
I have selected the following parameters for optimization:
Fig. 8. Optimization parameters
Fig. 9. Optimization settings
Thus, we now have the ready-to-use robot.
Optimization and Test Results
Fig. 10. Test results
Fig. 11. Test results graph
Conclusion
- We have developed the ready-to-use Expert Advisor trading the Inside Bar pattern.
- We have made sure that Price Action patterns can work even with no additional market entry filters.
- No tricks (like Martingale or averaging) have been used.
- The drawdown has been minimized through the correct setting of the stop orders.
- No technical indicators have been used. The trading robot is based solely on reading a "bare" chart.
Thank you for reading! I hope this article has been helpful.
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/1771
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
If you wrong determining support and resistance, will burn your money.
60 TRADES WIN - 40 LOSE LITTLE= PROFITABLE STRATEGY.
60 TRADES WIN - 40 LOSE LITTLE= PROFITABLE STRATEGY.
Thanks for the article and the attached code. I find it very informative.
It seems to me that the comments for bullish/bearish candles are mixed up:
In case of candle price open is greater than close that is bearish while close is grater than open is bullish.
I know it might be a bit late for the correction if I am right but I have just come across with your code and had a look.