Konstantin Boykachev

CEO Proforexea LLC

Honest Coder

Professional Trader


No products in the cart.

Konstantin Boykachev

CEO Proforexea LLC

Honest Coder

Professional Trader

Blog Post

Creating manual trading strategies using fuzzy logic


the rapid development of technology has led to the modern foreign exchange market there is a growing trend of using automated trading systems. However, many traders still operate in manual mode. Pros and cons of both approaches to trade have long known: cars for sale not too flexible to market changes and manual, on the contrary, may be excessively flexible due to the frequent intervention of the human factor. In fact, this aspect of comparison are the two extremes of the same entity.

in a previous article I on the examples sought by using the theory of fuzzy logic automated way compensate for the shortcomings of trade — for example, blur too strict formalization of strategies used in trading robot and indicator. In this article we will discuss the possibility of improving the manual trading strategy. Indeed, the use of modern technology even in manual mode of trade, where the final decision always rests with the trader, brings more benefits than harm.

Choose manual strategies with clear formalization conditions

many modern traders hesitant to take responsibility for entering and exiting their positions for yourself and don’t trust this automatic systems. They need to develop your trading strategy, which would take into account all possible outcomes of market behavior. Then you want to strictly follow it and resist impulses, provociruemym fear or greed.

So first you need to determine the choice of trade strategy. Describe the three stages of its building.

  • step 1. Finding and identifying the tools that will be used in our strategy.
  • step 2. Specifying clear conditions under which the trader will open its market position.
  • step 3. Specifying clear conditions under which position you want to be close with a positive or negative result.

step 1.

at the first stage, as an example, I chose three to build a trading strategy:

  1. the average directional movement Index (Average Directional Movement Index, ADX). This trend indicator, which determines the strength of the current trend.
  2. Oscillator relative vigor index (Relative Vigor Index, RVI).
  3. Indicator acceleration/deceleration Bill Williams Accelerator Oscillator (AC).

Selected general view and configure the trading terminal MQL4:

Figure. 1. General view settings strategy

step 2.

the second phase will determine how we will use the selected tools, the conditions in which they will work, as well as position options, which we will use to enter the market.

Let’s start from the beginning.

  • First, our indicator is the ADX. As you can see in Figure 1, the specified period of the indicator is equal to 10. In addition, specially configured for the master level trend line (green), which is equal to 30. Value equal to or above it, we will take positive signal to enter the market. It should be noted that the signal to buy from this indicator would be the situation when + DI (green dotted line) higher than-DI (red dashed). Accordingly, a sell signal is the reverse situation, when DI + DI is higher.
  • the second indicator-AC here we will use the signals described in official documentation. Namely, if the indicator value below 0 and it grows at the analyzed bar and two previous is a signal to buy. Accordingly, if the indicator value is above 0 and it falls on the analyzed bar and two earlier, we get a sell signal.
  • the third indicator-RVI. Set the period of his work equal to 10. As a condition for purchasing will define the moment when the signal (the thin red line) crosses the main (green). While crossing the line analyzed bar value should be below the zero mark. Similarly, set the conditions for sale: signal line crosses the main, but the values are above zero.
  • the following condition will work hour timeframe (H1).
  • a condition of entering a position — submission of identical signals from all three of the selected indicators.
  • and, finally, to determine the size of the position. As an example, let’s assign: 0.01 lot, take profit, stop loss 50 points 30 points.

For greater clarity, formalize the conditions.

Entry in a long position (buying signal)

  1. the main ADX line Green has a value equal to or greater than 30, while a value of + DI,-DI above.
  2. AC Value grows at the current bar, and it is higher than in the previous two bars, which in turn also consistently grow. Visually, this three-column histogram of green color, each shorter than the previous one, and all three are in the negative area.
  3. Signal (the thin red line) RVI crosses the main (green), both are growing, but are still below the zero mark.
  4. Buy 0.01 lot, set take profit stop loss 50 points and 30 points.

Entry in the short position (sell signal)

  1. the main green line indicator ADX value is greater than or equal to 30, with a value of + DI,-DI below.
  2. value AC falls to the current bar, and it is lower than in the previous two bars, which in turn also consistently reduced. Visually, this three-column histogram red, each shorter than the previous one, and all three have values above zero.
  3. Signal (the thin red line) RVI crosses the main (green), both reduced, but still in the positive area.
  4. Sell lot 0.01, set take profit stop loss 50 points and 30 points.

step 3

we can only determine the exit position. As a condition for the release set already defined earlier targets: achieving profit in 50 points or stop trigger in 30 points.

so, our trade strategy is defined. We have set conditions for opening and closing positions, selected indicators, and set their operational parameters have dimensions position entry and their objectives. And finally, we decided on which events will occur exiting the market.

the next phase of work will check established trading strategies in real-world conditions. The first thing you should understand is the ideal strategies in the long run and in all stages of the market will not happens. And traders using automated trading, and those who trade in the manual mode often observe that their system shows itself differently in different environments. Also there are cases when the initial conditions in the already given trading system could show the best result.

for example, regarding our system trader might notice that the take profit could be higher. No, not because he just wanted to get more, but because he constantly reviewed its system, and his statistics showed: after the closing of the successful deals price some time moving in the right direction. Therefore, a trader there is a logical question: how to apply the statistical data and observations, which he got for his trading system, improving its results?

Disadvantages of clear formalization and fix them using fuzzy logic

Consider used in our system of indicators through the prism of the theory of fuzzy logic. In my previous article, I tried to convey its main advantage is the flexibility to analyze those parts of trading strategies that used strict categorization. Fuzzy logic has eroded the strict boundaries and gave a better understanding of evaluation and response system in frontier areas of its work. There was also shows an example of a more adaptive approach to the work of our indicator ADX. First used on the strict separation of weak, medium and strong trend, but then those categories are blurred, and the definition of trend strength was no longer strictly tied to the subjectivity of the indicator values.

back to our system and ask ourselves: how it can help us?

imagine what our trader monitors market and sees a signal from the first indicator: ADX has reached 32, for example. He is a noted and waits for an acknowledgment from the other two indicators. And it does not make herself wait long. Comes the signal from the AC while ADX grew to 40. After some time the signal line RVI crosses the primary and, therefore, has finally achieved all three conditions for entering a position. When the ADX has already reached the mark 45. But the absolute value of ADX in our system is not so important. The main thing is that it is above 30. Therefore, the trader should be its rules and enters the market lot 0.01 to Take Profit in points 50 and Stop Loss is at 30.

now let’s make another version of events. At first the situation develops in the same way as in the first case. ADX = 32, comes the signal from AC, ADX parallel reaches 40. But when it comes to the last missing signal to open positions — from RVI-ADX bounces up to 45, and not, say, to 55. If you compare the two options described, the second signal is stronger than the previous one, but our trader opens a position still the same lot and the same values of TP and SL.

Here emerges the first drawback of our strategy: assessed only the presence of incoming us signal, regardless of its quality. And even if we will evaluate and determine if the category, the transitional areas of estimation accuracy will be lost.

how do you improve a particular case with ADX, RVI and bind them to the position indicators, which we enter the market? To do this, perform the following steps:

  • define clear trend strength assessment category (ADX) and relative vigor index (RVI). This will be the incoming signal on the basis of which we will take a further decision.
  • define clear objectives of our position (in our strategicGII is TP and SL, though you can specify, for example, lot size). This output signal, which will adjust our position in the market, taking into account the trend strength.
  • describe the categories input and output signals functions conditioning theory of fuzzy sets.
  • create an interface that will display the recommendations on changing the position of the initial strategy, on the basis of the new conditions.
  • create a flexible configuration changes of membership functions, which will adjust the system recommendations.

to begin describe the first input variable is the value trend strength.

1. Ask 4 category trend strength: weak (low), moderate (to moderate), intermediate (medium) and strong (high). It will look like this:

Figure. 2. The Visual separation of the trend’s strength in categories

2. To specify the output categories need to be defined as a category of ADX will affect our position. As a rule, the stronger the trend, the longer it will last. Therefore proceed as follows: depending on where the ADX at a time when all three signals the strategy will increase the TP at 10-50 points.

therefore, we introduce the following categories for purposes of profit value that will be added to the original 50 items on our strategy.

  • Category low_take: the trend is weak (Low), to the objectives of the Add 10-20 points.
  • Category mod_take: the trend of moderate (Moderate), to the objectives of the Add 20-30 points.
  • Category med_take: the trend of Medium, to the objectives of the Add 30-40 pips.
  • Category high_take: the trend is strong (High), the objectives of add 40-50 points.

3. The next stage will describe the conditions defined above using membership functions of fuzzy sets theory. Describes the four categories of the trend is as follows:

Describe the four categories

Figure. 3. A description of the four categories of fuzzy trend

as shown in Figure 3, each of the categories you set features accessories, namely: low-high trend-trend — two trapezoidal functions and category of moderate and medium — two triangular.

now define the same for RVI.

1. Set the relative vigor index categories. They too will be four: lax (low), intermediate (medium), strong (high), (higher). It will look like this:

Figure. 4. Visual separation of relative vigor index on categories

2. Describe the functions of the conditioning category entered. For category descriptions low and higher will be trapezoid function and for medium and high -triangular.

Figure. 5. Description of categories index RVI

Similarly, we describe four categories of values purposes of profit: the first and fourth categories (10-20 and 40-50) is a trapezoidal functions, and the remaining two (20-30 and 30-40) — triangular. So it will look like the description of our output signal.

Figure. 6. Description of categories for purposes of profit values

Interface implementation Panel to display recommendations for changing the position

when building the dashboard we choose four setting for observation:

  • ADX Value. Only when specified conditions, namely 30 or above.
  • value of RVI. Only when when it is above 0.1 (for selling) or below-0.1 (to signal to the purchase).
  • the recommended number of items that you want to add to the original goals in 50.
  • value Take Profit Price format of the trading symbol (taking into account the initial price and recommendations for its improvement).

now in full realization general view settings of the trading strategy will be as follows (fig. 6).

Figure. 7. The full implementation and the overall look and setting up trading strategy

now consider this Panel means MQL4 and FuzzyNet libraries.

Implement and examine key logical blocks this dashboard means MQL4.

#property copyright "Alexander Fedosov"
#property  version "1.0"
#property strict
#property link "https://www.mql5.com/ru/users/alex2356/"
indicator_chart_window #property  indicator_buffers 1

Green indicator_color1 #include 

define the initial properties and p odkljuchim library for working with fuzzy logic. Set the find pane, in the graphics window. Define one indicator buffer and its color (green) to the arrow pointer to the bar.

input string  p1 ="= Parameters =";
input int fontSize =15;
input int adx_period =10;
input int rvi_period =10;
input int num_bar =0;
input int Screen_corner =4;
input color label_clr = Red;
input color textColor = Black;

Consider in more detail the first block of input parameters Parameters. It contains the following elements:

  • the fontSize is the font size of text information (recommended range 8-15).
  • adx_period -work period ADX.
  • num_bar -bar number at which to evaluate the system.
  • Screen_corner is the angle of the display panel.
  • label_clr is the text color for the headers.
  • textColor text color values.

the second block of input parameters Fuzzy Logic Parameters contains most of the options for flexible adjustment of all functions of accessories, describing how the input parameters (force index ADX trend RVI) and output ( recommended value items profit goals).

input string  p2 ="= Fuzzy Logic Parameters =";

input double in_term1a = 20;
input double in_term1b = 30;
input double in_term1c = 40;
input double in_term1d = 45;
input double in_term2a = 40;
input double in_term2b = 50;
input double in_term2c = 60;
input double in_term3a = 50;
input double in_term3b = 60;
input double in_term3c = 70;
input double in_term4a = 60;
input double in_term4b = 70;
input double in_term4c = 100;
input double in_term4d = 120;

input double in_term1a1 =0.25;
input double in_term1b1 = 0.1;
input double in_term1c1 = 0.15;
input double in_term1d1 = 0.25;
input double in_term2a1 = 0.15;
input double in_term2b1 = 0.25;
input double in_term2c1 = 0.35;
input double in_term3a1 = 0.25;
input double in_term3b1 = 0.35;
input double in_term3c1 = 0.45;
input double in_term4a1 = 0.4;
input double in_term4b1 = 0.45;
input double in_term4c1 = 1;
input double in_term4d1 = 1.2;

input double out_term1a = 5;
input double out_term1b = 10;
input double out_term1c = 15;
input double out_term1d = 22.5;
input double out_term2a = 17.5;
input double out_term2b = 25;
input double out_term2c = 32.5;
input double out_term3a = 27.5;
input double out_term3b = 35;
input double out_term3c = 42.5;
input double out_term4a = 37.5;
input double out_term4b = 45;
input double out_term4c = 50;
input double out_term4d = 60;
input double min_tp = 10;
input double max_tp = 50;

the following block, declare variables, title headers, template itself dashboards (size, position, font, etc.), as well as display item settings, pointing to the current bar (in our case This arrow).

int scaleX = 55scaleY =25offsetX =35;

string signalName[]= {"ADX_val""RVI_val""TP_plus""TP_prc"};
 double adx, adx_di_minus, adx_di_plus, rvi, rvi_sig, mdm;
 double Buffer[];

int OnInit () {
   if(> fontSize 15 | fontSize< 8) {
      Print("ERROR: Incorrect fontSize. Must be 8-15. ");
      Alert("ERROR: Incorrect fontSize. Must be 8-15. ");
   if(Screen_corner >4 | Screen_corner1 <) {
      Print("ERROR: Incorrect Screen_corner. Must be 1-4. ");
      Alert("ERROR: Incorrect Screen_corner. Must be 1-4. ");
     } SetIndexStyle (0DRAW_ARROW EMPTY1);
   SetIndexArrow (0234);
   SetIndexBuffer(0, Buffer);
   ArrayInitialize (Buffer0.0);

   for(int y =0y< 4; y ++) {
      ObjectSet ("lb_ind_nm"+string(y),OBJPROP_SELECTABLEfalse);
      ObjectSet ("lb_ind_nm"+string(y),OBJPROP_CORNER, Screen_corner);
      ObjectSet ("lb_ind_nm"+string(y),OBJPROP_XDISTANCE offsetX-30);
      ObjectSet ("lb_ind_nm"+string(y),OBJPROP_YDISTANCE y * scaleY +20);
      ObjectSetText ("lb_ind_nm"+stringsignalName (y),[y]fontSize "Tahoma"label_clr);

   for(int y =0y< 4; y ++) {
      ObjectSet ("lb_ind0"+string(y),OBJPROP_SELECTABLEfalse);
      ObjectSet ("lb_ind0"+string(y),OBJPROP_CORNER, Screen_corner);
      ObjectSet ("lb_ind0"+string(y),OBJPROP_XDISTANCE scaleX + offsetX);
      ObjectSet ("lb_ind0"+string(y),OBJPROP_YDISTANCE y * scaleY +20);
      ObjectSetText ("lb_ind0"+string(y),""fontSize "Tahoma"textColor);

now consider basic signal processing unitfrom the ADX indicator and RVI.

Specify the conditions under which the values of the indicators meet the buy and sell signals. With their matching values are handled by the function mamdani (double t, double v) and are displayed in the pane. All of this is as follows: the current values of the indicators with indication of buy signal we have received or sell; recommended TP (in paragraphs and in numerical value).

 int OnCalculate(const int 
                rates_total, const int 
                prev_calculated, const datetime & time[]
                const double & open[]
                const double & high[]
                const double & l ow[]
                const double & close[]
                const long & tick_volume[]
                const long & volume[]
                 const int []spread &) {Buffer[num_bar]= High[num_bar]+20*_Point;
   ADX =by NormalizeDouble (iADX(_SymbolPERIOD_CURRENTadx_period,PRICE_CLOSE, MODE_MAIN, num_bar),_Digits);
   adx_di_plus =by NormalizeDouble (iADX(_SymbolPERIOD_CURRENTadx_period,PRICE_CLOSEMODE_PLUSDI, num_bar),_Digits);
   adx_di_minus =by NormalizeDouble (iADX(_SymbolPERIOD_CURRENTadx_period,PRICE_CLOSEMODE_MINUSDI, num_bar),_Digits);

   RVI =by NormalizeDouble (iRVI(_SymbolPERIOD_CURRENT, rvi_period, MODE_MAIN, num_bar),_Digits);
   rvi_sig =by NormalizeDouble (iRVI(_SymbolPERIOD_CURRENT, rvi_period, MODE_SIGNAL, num_bar),_Digits);

   if(adx >30 & & adx_di_plus > adx_di_minus & & rvi > rvi_sig & & rvi <-0.1) {mdm =MathCeil (mamdani (adx,MathAbs (rvi)));
      ObjectSetText ("lb_ind00""buy_signal"+DoubleToString (adx,_Digits), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind01""buy_signal"+DoubleToString (rvi,_Digits), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind02"DoubleToString

(mdm,0), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind03"DoubleToString (tp_prc (mdm),_Digits), fontSize,"Tahoma"textColor);
   else if(adx >30 & & adx_di_plus < adx_di_minus & & rvi0.1) {mdm =MathCeil (mamdani (adx, rvi));
      ObjectSetText ("lb_ind00""sell_signal"+DoubleToString (adx,_Digits), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind01""sell_signal"+DoubleToString (rvi,_Digits), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind02"DoubleToString (mdm0), fontSize,"Tahoma"textColor);
      ObjectSetText ("lb_ind03"DoubleToString (tp_prc (mdm),_Digits), fontSize,"Tahoma"textColor);
     {ObjectSetText ("lb_ind00""no_signal"fontSize "Tahoma"textColor);
      ObjectSetText ("lb_ind01""no_signal"fontSize "Tahoma"textColor);
      ObjectSetText ("lb_ind02"","fontSize "Tahoma"textColor);
      ObjectSetText ("lb_ind03"","fontSize "Tahoma"textColor);

function creates a fuzzy logic system. It contains two incoming signal from the indicators is trend and vigor (each of which consists of four terms, described by functions) and an outbound — signal. The system also includes four rules that bind incoming and outgoing signals.

double mamdani (double tdouble v) {
   double res =0;

   MamdaniFuzzySystem * fsSignal =new MamdaniFuzzySystem ();

   FuzzyVariable * fsTrend =new FuzzyVariable ("trend"30.0100.0);
   FuzzyVariable * fsVigor =new FuzzyVariable ("vigor"0.11.0);

   fsTrend. Terms (). Add (new FuzzyTerm (low new TrapezoidMembershipFunction (in_term1a, in_term1b, in_term1c, in_term1d)));
   fsTrend. Terms (). Add (new FuzzyTerm ("moderate" new TriangularMembershipFunction (in_term2a, in_term2b, in_term2c)));
   fsTrend. Terms (). Add (new FuzzyTerm (medium new TriangularMembershipFunction (in_term3a, in_term3b, in_term3c)));
   fsTrend. Terms (). Add (new FuzzyTerm (highnew TrapezoidMembershipFunction (in_term4a, in_term4b, in_term4c, in_term4d)));
   fsSignal. Input (). Add (fsTrend);

   fsVigor. Terms (). Add (new FuzzyTerm (low new TrapezoidMembershipFunction (in_term1a1, in_term1b1, in_term1c1, in_term1d1)));
   fsVigor. Terms (). Add (new FuzzyTerm (medium new TriangularMembershipFunction (in_term2a1, in_term2b1, in_term2c1)));
   fsVigor. Terms (). Add (new FuzzyTerm (high new TriangularMembershipFunction (in_term3a1, in_term3b1, in_term3c1)));
   fsVigor. Terms (). Add (new FuzzyTerm ("higher"new TrapezoidMembershipFunction (in_term4a1, in_term4b1, in_term4c1, in_term4d1)));
   fsSignal. Input (). Add (fsVigor);

   FuzzyVariable * fvSignal =new FuzzyVariable ("signal"min_tp, max_tp);
   fvSignal. Terms (). Add (new FuzzyTerm ("low_take" new TrapezoidMembershipFunction (out_term1a, out_term1b, out_term1c, out_term1d)));
   fvSignal. Terms (). Add (new FuzzyTerm ("mod_take" new TriangularMembershipFunction (out_term2a, out_term2b, out_term2c)));
   fvSignal. Terms (). Add (new FuzzyTerm ("med_take" new TriangularMembershipFunction (out_term3a, out_term3b, out_term3c)));
   fvSignal. Terms (). Add (new FuzzyTerm ("high_take" new TrapezoidMembershipFunction (out_term4a, out_term4b, out_term4c, out_term4d)));
   fsSignal. Output (). Add (fvSignal);

   MamdaniFuzzyRule * rule1 = fsSignal. ParseRule (if (trend is low) and (vigor is low) then the signal is low_take ");
   MamdaniFuzzyRule * rule2 = fsSignal. ParseRule (if (trend is moderate) and (vigor is medium) then the signal is mod_take ");
   MamdaniFuzzyRule * rule3 = fsSignal. ParseRule (if (trend is medium) and (vigor is high) then the signal is med_take ");
   MamdaniFuzzyRule * rule4 = fsSignal. ParseRule (if (trend is high) and (vigor is higher) then the signal is high_take ");

   fsSignal. Rules (). Add (rule1);
   fsSignal. Rules (). Add (rule2);
   fsSignal. Rules (). Add (rule3);
   fsSignal. Rules (). Add (rule4);

   CList *in=new CList;
   Dictionary_Obj_Double * p_od_adx =new Dictionary_Obj_Double;
   Dictionary_Obj_Double * p_od_rvi =new Dictionary_Obj_Double;
   p_od_adx. SetAll (fsTrend, t);
   p_od_rvi. SetAll (fsVigor, v);
   in. Add (p_od_adx);
   in. Add (p_od_rvi);

   CList * result;
   Dictionary_Obj_Double * p_od_out;
   result = fsSignal. Calculate (in);
   p_od_out = result. GetNodeAtIndex (0);
   RES = NormalizeDouble (p_od_out. Value(), _Digits);

   delete in;
   delete result;
   delete fsSignal;
   return res;

proceed to the last block — “helper functions”. The first of them tp_prc (double take)convert the value of TP in the numerical value of prices the current monetary tool. The second determines the number of characters in the current currency.

double tp_prc ( double take) {
   int tip;
    double opr, tp;
   take + =50;
   adx_di_plus =by NormalizeDouble (iADX(_SymbolPERIOD_CURRENTadx_period,PRICE_CLOSEMODE_PLUSDI, num_bar),_Digits);
   adx_di_minus =by NormalizeDouble (iADX(_SymbolPERIOD_CURRENTadx_period,PRICE_CLOSEMODE_MINUSDI, num_bar),_Digits);

   if(adx_di_plus > adx_di_minus) tip =0;
   else if(adx_di_plus < adx_di_minus) tip =1;

   switch(tip) {
      case 0: opr = Ask;
      case 1: opr = Bid;
   if(MathMod (tip2.0) ==0.0) {tp = opr + take * Dig *_Point;
     {tp = opr-take * Dig *_Point;

int Dig () {
   return((_Digits==5 | _Digits==3 | _Digits==1)?10:1);

would also like to draw attention to the correct settings and verification of the correctness of entries in the Fuzzy Logic Parameters during testing. Recommend rely on original their graphical representations of the figure. 3, 5, 6, because incorrect values can lead to errors and incorrect work of SIsystems. Be careful!


in conclusion, summarize and make conclusions.

  • the first part of the work on creation of manual trading strategy using fuzzy logic is the development of a clearly formalized rules of this strategy. It was considered at stages 1 — No. 3.
  • you must then identify gaps clear formalization in those places where there is a strict categorization of any evaluation units or options. In the above example was found part of the strategy, which is not allowed to flexibly determine when to enter the market.
  • all distinct categories are described using the theory of fuzzy sets and thus become more flexible. Now the border values may exist not to one particular category, as they used to be, but both at once, but in different degrees.
  • this strategy is implemented as indicator panels or alert. This article has been selected by the Panel in MQL4.

we have considered the possibility of improving the manual trading strategy using the theory of fuzzy sets. For example, it shows in detail how an already formed a trading strategy is modified and supplemented by using fuzzy logic for getting rid of the shortcomings found.

Write a comment