Betting Modeling as Means of Developing "Market Intuition"

Eryomin Sergey | 21 January, 2008

Introduction

This article dwells on a simple mechanism of betting modeling in the real-time mode. So, what is Betting? Financial Betting - forecasting regarding the further movement (up or down) of a security and acquiring money if the forecast comes true. (Translated into English from Russian Wikipedia by MetaQuotes Software Corp.)

Actually, in betting we are interested in one thing: whether a security goes up or down. The volume of this movement is not important for us.

If we use betting in the form of a game on small timeframes, we can develop our "market intuition". We can learn to "foresee" whether a pair goes up or down. This is what will be described in this article.



Conception

They say, knowing technical analysis, fundamental analysis, rules of money management etc. is very important for a trader. Undoubtedly, all this is very important. But there is also the so called "market intuition" - when a trader looks to an absolutely clear chart without any indicators and can approximately see, in what direction a security will move. Of course, this forecast is not always exact, but errors can occur at every trading approach. Still, the ability to "foresee" the market is very useful, especially when one needs to estimate quickly the market situation.

Usually the "market intuition" is the result of large experience, numerous experiments. Very often the cost of such "experiments" equals to thousands of US dollars.

But I think, there are ways to develop this intuition that require less time and money. One of the ways is creating a game, the meaning of which is forecasting the movement direction of a security. The game will be even better, if it is connected with real trading conditions. It can also be lead together with real trading.

Undoubtedly human abilities can be exercised and developed. We can learn to draw, sing, play different musical instruments. I am sure that one can the same way learn to "see" the market. We can play computer games. Identically we can play the game "forecast the direction". But what we should know here, is what to begin with and how to develop this ability. First we need the game itself.



Setting the Task

So what we need? We need a game, using which we can play on a real chart in real time mode. And the game should have very simple rules and easy implementation. And the game should provide the maximal attention on the market itself and not on the executed operations. Besides, the game should not distract much attention from the possible real trading.

Betting seems to meet all these requirements. But in real life it is not very convenient. Not many brokerage companies offer such an opportunity. Even if you manage to find such a company, you can face some inconveniences. For example, demo accounts can distract your attention from the real trading. And the game is too risky for a real account. And usually you cannot bet for a period less than one hour.

Thus, you see this variant does not fully suit our task. Consequently, we need to write a separate program for this game - a program with no such limitations. MQL4 ideally suits our purpose.



Implementation

Let's start from a simple question: How should it look like? Obviously, a user should select one of the two given variants - up or down (his forecast about the further behavior of a security). After that the program adds a point if the supposition is correct and detracts a point if it is incorrect.

The selection implementation is better realized through objects - SYMBOL_ARROWDOWN and SYMBOL_ARROWUP. A user could place the necessary arrow on a chart. But drawing them and writing signatures would take too much time and attention. So this variant does not suit.

One more variant is to place automatically two arrows at the beginning of a new candlestick. A user should delete one arrow and the remaining one should indicate his supposition. After that at the beginning of a new candlestick, an Expert Advisor should check whether the forecast was correct. And the total score, the number of correct and the number of incorrect forecasts will be counted. For this purpose recording into an external file will be used.

It sounds easy. And it can be easily implemented.

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//------------------------------
string solution="none"; 
int point, 
    point_neg, 
    point_pos;
//------------------------------    
//+---------------------------------------------------------------+
//|                      "up" choice searching                    | 
 if(
    ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point
    &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1
    &&ObjectFind("down") != 0
    &&ObjectFind("up") == 0
    )
    {
     solution="up";
    }
//|                      "up" choice searching                    |  
//+---------------------------------------------------------------+
  
//+---------------------------------------------------------------+
//|                      "down" choice searching                  |     
 if(
    ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point
    &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1    
    &&ObjectFind("up") != 0
    &&ObjectFind("down") == 0
    )
    {
     solution="down";
    }
//|                      "down" choice searching                  |       
//+---------------------------------------------------------------+    
 
//+---------------------------------------------------------------+
//|             counting points at a positive answer              |
    if((solution=="up"&&Open[1]<Close[1])
      ||(solution=="down"&&Open[1]>Close[1]))
    {
     point=1;
     point_pos=1;
     point_neg=0;     
    }  
//|             counting points at a positive answer              |   
//+---------------------------------------------------------------+
 
//+---------------------------------------------------------------+
//|             counting points at a negative answer              |    
    if((solution=="up"&&Open[1]>Close[1])
      ||(solution=="down"&&Open[1]<Close[1]))
    {
     point=-1;
     point_pos=0;
     point_neg=1;     
    } 
//|             counting points at a negative answer              |
//+---------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------+
//|                              working with an external file                       |       
      int handle; 
      double points,     //total score
             points_pos, //score of positive answers
             points_neg; //score of negative answers 
       handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                       FILE_CSV|FILE_WRITE|FILE_READ,";");
       if(handle>0) //if there is a file, read it
       { 
        points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits);       
        FileClose(handle);
       } 
       
    if(solution!="none") //if a choice is made 
    {        
      handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                      FILE_CSV|FILE_WRITE|FILE_READ,";");
      FileWrite(handle ,points+point);         //write the total score
      FileWrite(handle ,points_pos+point_pos); //write the score of positive answers
      FileWrite(handle ,points_neg+point_neg); //write the score of negative answers                    
      FileClose(handle); 
    } 
//|                              working with an external file                       | 
//+----------------------------------------------------------------------------------+    
 
//+------------------------------------------------------------------------------------+
//|                                 working with objects                               |   
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
 if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) 
    { 
     ObjectDelete("up"); 
    } 
    
   if(ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no object
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down", OBJPROP_COLOR, Red);
 
     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up", OBJPROP_COLOR, Blue);
    }
//|                                 working with objects                               |   
//+------------------------------------------------------------------------------------+
 
Comment("Score: ", points," (",points_pos,"/",points_neg,   //show the score
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//show time (for convenience) 
//----
   return(0);
  }
//+------------------------------------------------------------------+

The code contains comments.


After attaching it to a chart, we get the following result:




We see two arrows on the last bar - up and down. In the upper left corner we see the score of the game and the terminal time of the last tick. The score is displayed in three figures: the first one is the total score, the second one (the first in brackets) is the number of positive answers (correct forecast), the third one (the second in brackets) is the number of negative answers (incorrect forecast). And the time is displayed for the convenience of operation in Full Screen mode (F11).


For "playing" the game, one should select an "unnecessary" arrow using a double click (default) and press Delete (for deleting it). The remaining arrow indicates our forecast:



Now we wait for the beginning of the next bar. If the forecast is correct, the "Score" will have the following form: "Score: 1(1/0)". If the forecast is incorrect, the "Score" will be like this: "Score: -1(0/1)". And if the closing price is equal to the opening price, the score will not change. In our example the forecast was wrong:





Improvement

Our task is fulfilled. But there is a disadvantage of such an implementation: you can make your choice during the whole candlestick, including the last seconds. And this seems unfair. It would be better, if one could make the choice within the first 30 seconds. For this purpose, let's introduce the extern int variable – "time_limit". Its value will be equal to the number of seconds, within which the choice should be made. If a user does not manage to make the selection within this period of time, the arrows will be deleted from the chart and will appear only on the next candlestick.

The changes will appear in the part "working with objects" (explanation is in comments). Here is the code:

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
extern int time_limit=30;
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//------------------------------
string solution="none"; 
int point, 
    point_neg, 
    point_pos;
//------------------------------    
//+---------------------------------------------------------------+
//|                      "up" choice searching                    | 
 if(
    ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point
    &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1
    &&ObjectFind("down") != 0
    &&ObjectFind("up") == 0
    )
    {
     solution="up";
    }
//|                      "up" choice searching                    |  
//+---------------------------------------------------------------+
  
//+---------------------------------------------------------------+
//|                      "down" choice searching                  |     
 if(
    ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point
    &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1    
    &&ObjectFind("up") != 0
    &&ObjectFind("down") == 0
    )
    {
     solution="down";
    }
//|                      "down" choice searching                  |       
//+---------------------------------------------------------------+    
 
//+---------------------------------------------------------------+
//|             counting points at a positive answer              |
    if((solution=="up"&&Open[1]<Close[1])
      ||(solution=="down"&&Open[1]>Close[1]))
    {
     point=1;
     point_pos=1;
     point_neg=0;     
    }  
//|             counting points at a positive answer              |   
//+---------------------------------------------------------------+
 
//+---------------------------------------------------------------+
//|             counting points at a negative answer              |    
    if((solution=="up"&&Open[1]>Close[1])
      ||(solution=="down"&&Open[1]<Close[1]))
    {
     point=-1;
     point_pos=0;
     point_neg=1;     
    } 
//|             counting points at a negative answer              |
//+---------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------+
//|                              working with an external file                       |       
      int handle; 
      double points,     //total score
             points_pos, //score of positive answers
             points_neg; //score of negative answers 
       handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                       FILE_CSV|FILE_WRITE|FILE_READ,";");
       if(handle>0) //if there is a file, read it
       { 
        points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits);       
        FileClose(handle);
       } 
       
    if(solution!="none") //if a choice is made 
    {        
      handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                      FILE_CSV|FILE_WRITE|FILE_READ,";");
      FileWrite(handle ,points+point);         //write the total score
      FileWrite(handle ,points_pos+point_pos); //write the score of positive answers
      FileWrite(handle ,points_neg+point_neg); //write the score of negative answers                    
      FileClose(handle); 
    } 
//|                              working with an external file                       | 
//+----------------------------------------------------------------------------------+    
 
//+------------------------------------------------------------------------------------+
//|                                 working with objects                               |   
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
 if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point)            
    { 
     ObjectDelete("up"); 
    } 
   
  int sec_lim;  
  if(!time_limit)
  {
   sec_lim=0; 
  }
  else
  {
   sec_lim=TimeCurrent()-time_limit;
  }
  if(sec_lim>ObjectGet("up",OBJPROP_TIME1)
     &&sec_lim>ObjectGet("down",OBJPROP_TIME1) 
     &&ObjectFind("down") == 0&&ObjectFind("up") == 0
     &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0
     &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0)            
    { 
     ObjectDelete("up"); 
     ObjectDelete("down");      
    } 
  
   if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no objects
      &&sec_lim<Time[0])
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down", OBJPROP_COLOR, Red);
 
     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up", OBJPROP_COLOR, Blue);
    }      
//|                                 working with objects                               |   
//+------------------------------------------------------------------------------------+
 
Comment("Score: ", points," (",points_pos,"/",points_neg,   //show the score
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//Show time (for convenience) 
//----
   return(0);
  }
//+------------------------------------------------------------------+

So, we have two changeable variables in input parameters:



The parameter "gap" indicates the number of points - the distance between arrows and the opening price of the candlestick. The variable "time_limit" indicates the number of seconds, during which a user should make his choice. If its value is "0", there will be no limitation in time, i.e. a choice can be made during the whole candlestick.



Conclusion

So, we have implemented a simple version of modeling financial betting using MQL4 language. This game can help you greatly in developing your ability to "foresee" the market, as well as can help you to learn many regularities in the movement of securities. The version is implemented in such a way, that a trader's attention is maximally concentrated on the price chart. The operations executed by a trader require minimum of time and are easy-to-understand.

I would like to share my own results of the game. I managed to make correct forecasts for 5-10 candlestick in succession (on a five-minute chart).

Using this game, a trader can learn to answer one of the most important questions: Where shall a security move? Still there are a lot of other important questions, like fixing the profit, fixing losses, choosing the volume of a trade to open, etc. Only knowing how to answer all these questions can bring a trader to a steady result.

One of other important questions is a trader's rest time. This game can be much more useful than any other game existing in the entertainment market.