下载MetaTrader 5

赌博模型作为培养"市场直觉"的方法

17 三月 2016, 08:56
Eryomin Sergey
0
714

简介

本文详述了在实时模式中进行赌博建模的简单机制。那什么是赌博呢?金融赌博 - 预测某证券的未来走势(上涨或下跌)并在预测正确时获利。(由 MetaQuotes Software Corp. 自 Russian Wikipedia 翻译为英语)

实际上,我们在赌博中只关注一件事:证券是上涨还是下跌?而走势中的交易量对我们并不重要。

如果在较小的时间范围内以游戏的形式进行赌博,我们可以培养“市场直觉”。我们可以学习“预见”某个货币对要上涨还是下跌。这就是本文要描述的内容。



概念

人们普遍认为,了解技术分析、基本面分析、资金管理规则等,对交易者非常重要。毋庸置疑,所有这些都很重要。但还有所谓的“市场直觉” - 即当交易者观察一张没有任何指标的空白图表时,能够大约看出证券移动的方向。当然,这种预测并非始终准确,但每种交易方法都可能发生错误。这种“预见”市场的能力仍然非常有用,尤其在需要快速评估市场状况的时候。

“市场直觉”通常是大量经验和无数试验的结果。这种“试验”的代价经常达到成千上万美元。

但我认为,存在以更少的时间和金钱来培养这种直觉的方法。方法之一是制作一个游戏,其意义就是预测一个证券的走势。如果该游戏跟实时交易条件关联,则更佳。也可以跟真实交易联系起来。

毫无疑问,人的能力是可以练习和开发的。我们可以学习绘画、唱歌和演奏不同的乐器。我相信人同样可以学习“预见”市场。我们可以玩电脑游戏。同样,也可以玩“预测方向”的游戏。但我们在这里需要了解的是开始做什么和如何培养这项能力。首先,我们需要游戏本身。



设定任务

那我们需要什么呢?需要可以实时模式在真实图表上进行的游戏。游戏的规则应该非常简单和容易操作。且游戏应该使注意力尽可能多的保持在市场上而非执行的操作。此外,游戏不应该从可能的真实交易中分散很多注意力。

赌博似乎满足以上所有要求。但在现实生活中,赌博并不很方便。没有很多经纪公司提供这种机会。即使你好不容易找到一个这样的公司,可能也会面临诸多不便。例如,模拟账户可能会分散你真实交易的注意力。对于真实帐户,这个游戏的风险过大。通常,赌博的持续时间不能少于一个小时。

可见,这种变体未能完全符合我们的任务。最终,我们需要为该游戏编写单独的程序 - 没有这种限制的程序。MQL4 完美的符合我们的目的。



实施

我们从简单的问题开始:它看起来应该是什么样子?显然,用户应该从给出的变体中二选一 - 上涨或下跌(预测某证券的未来走势)。如果猜测正确,程序加一分;如果错误则减一分。

进行选择最好通过对象实现 - SYMBOL_ARROWDOWN 和 SYMBOL_ARROWUP。用户可以在图表上放置必要的箭头。但绘制和写入签名会花费大量时间和注意力。所以该变体并不适合。

另一个变体是在新蜡烛图开始处自动放置两个箭头。用户应删除其中一个箭头,留下的箭头指示其猜测。然后,Expert Advisor 应该在新蜡烛图开始处检测预测是否正确。最后计算总分、正确和错误预测的数量。为此,要使用外部文件进行录入。

这听起来并不难。实施起来也很容易。

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+

代码中包含注释。

在添加至图表后,我们得到如下结果:




在最后的柱上可以看到两个箭头 - 向上和向下。在左上角可以看到游戏的分数和最后一次价格变动的终端时间。分数以三个数字显示:第一个是总分,第二个(括号中第一个)是正面答案(正确的预测)的数量,第三个(括号中第二个)是负面答案(错误的预测)的数量。为了操作方便,时间以全屏模式显示(F11)。

为了“玩”游戏,应该使用双击(默认)选择“不必要”的箭头并按“Delete”键(进行删除)。余下的箭头指示我们的预测。



然后等待下一个柱的开始。如果预测正确,“Score”的形式如下:"Score:1(1/0)".如果预测错误,“Score”呈现如下:"Score:-1(0/1)".如果收盘价等于开盘价,分数不变。在示例中,预测是错误的:





改进

我们的任务已经完成。但存在一个不足之处:你可以在整个蜡烛图上进行选择,包含最后几秒钟。这似乎不公平。如果在前 30 秒内进行选择,会好很多。为此,我们引入外部 int 变量 - “time_limit”。它的值等于秒数,应在该时间内作出选择。如果用户未能在该时间内做出选择,箭头将从图表删除,并在下一个蜡烛图上显示。

更改将显示在“working with objects”部分(解释请见注释)。下面是代码:

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+

我们在输入参数中有两个可变变量:


“gap”参数指示点数 - 箭头和蜡烛图开盘价的距离。“time_limit”变量指示秒数,在该时间内用户应做出选择。如果值为“0”,则没有时间限制,即可以在整个蜡烛图上做出选择。



总结

现在,我们已经使用 MQL4 语言对金融赌博进行了简单的建模。该游戏可以极大的培养你“预见”市场的能力,以及帮助学习证券走势的很多规律。该版本的实现方式可以使交易者的注意力最大化的集中在价格图表上。交易者执行的操作需要的时间最少且容易理解。

我想分享自己的游戏结果。我在连续 5-10 个蜡烛图上做出正确预测(在五分钟的图表上)。

利用该游戏,交易者可以学习回答最重要的问题之一:证券将朝什么方向移动?仍有很多其他重要的问题,例如获利、弥补损失、选择打开的交易量等等。只有了解了如何回答所有这些问题,才能获得稳定的交易结果。

还有一个重要的问题是交易者的休息时间。该游戏比当前娱乐市场上的任何其他游戏更加有用。

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/1505

附加的文件 |
trener.mq4 (6.7 KB)
MQL5.community的支付系统 MQL5.community的支付系统

MQL5.community 内置服务为MQL5开发人员和普通的无编程技巧的交易者们提供了巨大了机遇。但是,所有这些功能的实现都离不开安全的内部支付系统,为买家和卖家之间的结算提供了方便的基础。在本文中,我们将展示MQL5.community支付系统的工作方式。

怎样购买一个基于MQL5或者MQL4的交易机器 怎样购买一个基于MQL5或者MQL4的交易机器

通过建立“工作”服务功能,MQL5.community 成为了一个理想的可以提供和购买编程服务的地方。这里有成千上万的交易人员和开发者每天来访问所需信息资源,也可以方便地互相帮助。对于交易人员来说,“工作”服务是轻松获得自己所需的EA智能交易程序的好机会,对于MQL5开发者来说,这也是轻松找到客户的机会。在这篇文章中,我们将领略一下此项服务的具体功能。

在外汇市场中货币篮子的运作 在外汇市场中货币篮子的运作

本文论述了如何将货币对分组 (篮子), 以及如何使用某些指标来获取它们的有关状态数据 (例如, 超买和超卖), 以及如何在交易中应用此数据。

在 MetaTrader 4 中的投资组合交易 在 MetaTrader 4 中的投资组合交易

本文揭示了投资组合交易及其在外汇市场中的应用。研究几种简单的投资组合数学模型。本文包含在 MetaTrader4 中的实际投资交易组合的实施例子: 投资组合指标和半自动化智能交易程序。交易策略的元素, 还针对它们的优点和缺陷进行了说明。