English Русский Español Deutsch 日本語 Português
分形线的构造

分形线的构造

MetaTrader 4示例 | 26 一月 2016, 08:56
2 997 1
Shashev Sergei
Shashev Sergei

简介

几乎所有的交易者都会使用分形. 然而, 如果您问他们什么是分形, 他们会给出最好的回答: 它是比尔.威廉姆斯系统的一个指标. 更高级的交易者将会说它是一个五个柱的序列, 其中, 如果中间柱的最高点高于序列中的其他柱, 它就是一个向上分形, 如果中间柱的最低点低于其他柱, 它就是一个向下分形. 正如这句话:“这是我可以讲述的战争”。

分形的简要介绍,特别是它们的性质和用途,在威廉姆斯的命名为"新的交易维度:如何从混乱中股票、债券和商品的利润"的书中有提供。在Chekulaev的叫做"分形(俄文版)"的文章中也可以找到一些内容. 其数学公式在Shiryaev的名为"随机震荡数学基础(俄文版)"中有很好的描述.

使用分形

有两种分形穿透需要注意 - 简单的一种是价格超过了向上分形的水平(或者跌破了向下分形水平). 在这种情况下, 最好是等着看该柱收盘价的状态, 并在下一个柱开启时建立仓位.


对应的买入卖出分形在图上已经使用箭头做标记, 位于简单分形穿透的上方. 一个复杂的穿透使用两个分形 - 最后一个和倒数第二个. 它们连成直线以期待看是否未来有柱的收盘价穿透.


当分形线被穿透时, 进场点使用蓝色和红色箭头标记. MQL4 的开发环境将能帮助我们更好地了解分形.


让我们为测试分形定义一个问题:

  • 画出分形买入/卖出
  • 画出水平穿透级别;
  • 画出分形线;
  • 使用箭头标记期待入场点.

分形买入/卖出

这是最基本的部分. 我们也应当考虑MQL4中已有的iFractal指标 (在Omega中, 我必须自己写这个指标, 因为Omega的属性, 这更困难一些). 怎样写这个指标的实例可以在代码库中找到.

穿透的水平级别

让我们使用标准水平线. 我们将把分形的价格作为价格坐标, 形成分形的时间和当前时间将作为时间坐标.

ObjectCreate("SimpleUp"+Up,OBJ_TREND,0,bufUpDate[Up],
             bufUpPrice[Up],Time[i-1],bufUpPrice[Up]);
ObjectSet("SimpleUp"+Up,OBJPROP_COLOR,Aqua);
ObjectSet("SimpleUp"+Up,OBJPROP_RAY,True);

分形线

看起来最简单的方法就是通过两个点画出趋势线. 我们做出一条射线然后等待穿透. 但是, 事实上我们没有办法比较收盘价和分形线的价格数值, 因为ObjectGet函数只能取得构成分形线的点的值. 那我们应该怎样做呢?

我们应该记得解析几何学. 我们有两个点, 所以我们就有了一个直线等式. 并且, 因为我们知道时间坐标, 我们可以很容易从直线等式中得到价格值. 标准的直线等式看起来如下:


我们会使用价格和时间替换x和y. 具体的实现在LevelCalcuate中实现, 它计算了穿透水平, 并同时使用ObjectSet函数设置了分形线的新的坐标.

ObjectCreate("LineUp"+Up,OBJ_TREND,0,bufUpDate[Up],
             bufUpPrice[Up],bufUpDate[Up-1],bufUpPrice[Up-1]); 
ObjectSet("LineUp"+Up,OBJPROP_COLOR,Blue);
ObjectSet("LineUp"+Up,OBJPROP_RAY,False);

放置箭头

我们在循环中构造所需的直线并且把它们与当前价格作比较. 如果它穿透了简单线, 我们就放置一个黄色箭头. 如果它穿透了分形线, 买入的箭头将是蓝色的, 而卖出箭头使用红色.

所有这些都在FractalLines.mq4中实现.

//+------------------------------------------------------------------+
//|                                                 FractalLines.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                       https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- 输入参数
extern int       lines=5;  //可见分形线的数量
extern int       MaxFractals=10000; // :)
extern bool       ShowHorisontalLines=true;
extern bool       ShowFractalLines=true; 
//---- 缓冲区
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//--- 我的变量
double bufUpPrice[10000];  //向上分形的价格数组
double bufUpDate[10000];   //向上分形的日期时间数组
double bufDownPrice[10000];   //向下分形的价格数组
double bufDownDate[10000]; //向下分形的日期时间数组
int Up = 0; //向上分形的计数器
int Down = 0;  //向下分形的计数器
 
//此函数计算分形穿透的价格数值, 计算是根据
//解析几何中的最简等式进行的
double LevelCalculate(double Price1, double Time1, double Price2, 
                     double Time2, double NewTime)
{
   double level;
   if (Time2!=Time1)// 防止被0除.
   {
      level=(NewTime-Time1)*(Price2-Price1)/(Time2-Time1)+Price1;
   }
   else
   { 
      return(Price2);
   }
   return(level);
}
 
//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                                |
//+------------------------------------------------------------------+
int init()
  {
//---- 指标
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,217);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,218);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(1,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| 自定义指标去初始化函数                                              |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- 最后一个计算的柱会被重新计算   
   if(counted_bars > 0) 
       counted_bars--;
   int limit = Bars - counted_bars;
// 我们将在穿透分形线的时刻放置箭头, 
// 评估效率
 // 此想法是从Rosh那里借来的, 希望他不会反对 :)    
  string arrowName; // 在此我们给箭头一个唯一名称
  
  //被穿透的分形的编号
  //穿透了分形线
  int FractalUp = 0;
  int FractalDown = 0;
  //分形的简单穿透
  int SimpleFractalUp = 0;
  int SimpleFractalDown = 0;
  
  double BuyFractalLevel = 0;  //穿透向上分形线水平
  double SellFractalLevel = 0; //穿透向下分形线水平
  double buf = 0; // 出现分形时的缓冲区数值; 如果等于0说明没有分形
 
//---- 主循环       
   for(int i = limit; i>0; i--)
   {   
   
       //画出简单分形水平
       
       //定义当前分形水平 
 
         BuyFractalLevel=LevelCalculate(bufUpPrice[Up],bufUpDate[Up],
                   bufUpPrice[Up-1],bufUpDate[Up-1],Time[i]);
         //把第二个坐标移动到向上分形线                              
         ObjectSet("LineUp"+Up,OBJPROP_TIME1,Time[i]);
         ObjectSet("LineUp"+Up,OBJPROP_PRICE1,BuyFractalLevel); 
         SellFractalLevel=LevelCalculate(bufDownPrice[Down],
                          bufDownDate[Down],bufDownPrice[Down-1],
                          bufDownDate[Down-1],Time[i]);
         //把第二个坐标移动到向下分形线                               
         ObjectSet("LineDown"+Down,OBJPROP_TIME1,Time[i]);
         ObjectSet("LineDown"+Down,OBJPROP_PRICE1,SellFractalLevel);
         
      //搜索简单分形
         if (Close[i]>ObjectGet("SimpleUp"+Up,OBJPROP_PRICE1)&&
                          (Up>SimpleFractalUp))
         {
            arrowName="SimleUpArrow"+Up;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         Low[i-1]-Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
            ObjectSet(arrowName,OBJPROP_COLOR,Yellow);
            SimpleFractalUp=Up;             
         }
         
         if (Close[i]<ObjectGet("SimpleDown"+Down,OBJPROP_PRICE1)&&
                          (Down>SimpleFractalDown))
         {
            arrowName="SimleUpArrow"+Down;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         High[i-1]+Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
            ObjectSet(arrowName,OBJPROP_COLOR,Yellow);
            SimpleFractalDown=Down;             
         }                                                                                                                          
 
      //搜索复杂穿透
        if ((Close[i]>BuyFractalLevel)&&(Up>FractalUp)) 
         {
            //设置向上箭头
            arrowName="UpArrow"+Up;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         Low[i-1]-Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
            ObjectSet(arrowName,OBJPROP_COLOR,Blue);
            FractalUp=Up;        
         }
                                          
        if ((Close[i]<SellFractalLevel)&&(Down>FractalDown))
         {
            //设置向下箭头
            arrowName="DownArrow"+Down;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         High[i-1]+Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
            ObjectSet(arrowName,OBJPROP_COLOR,Red); 
            FractalDown=Down;       
         }
        //画出向上分形自身
        ExtMapBuffer1[i] = iFractals(NULL, 0, MODE_UPPER, i);
        
        //如果有分形, 把它放进分形数组中
        buf = iFractals(NULL, 0, MODE_UPPER, i);
        if (buf!=0)
        {
            Up++;
            bufUpPrice[Up]=iFractals(NULL, 0, MODE_UPPER, i);
            bufUpDate[Up]=Time[i];
            //当前分形穿透水平 - 分形自身
            BuyFractalLevel=bufUpPrice[Up];
            
            if (Up>1)
            
            {
               //简单分形
               ObjectCreate("SimpleUp"+Up,OBJ_TREND,0,bufUpDate[Up],
                   bufUpPrice[Up],Time[i-1],bufUpPrice[Up]);
      ObjectSet("SimpleUp"+Up,OBJPROP_COLOR,Aqua);
      ObjectSet("SimpleUp"+Up,OBJPROP_RAY,True);   
               //在两个坐标间画出分形线
               ObjectCreate("LineUp"+Up,OBJ_TREND,0,bufUpDate[Up],
                  bufUpPrice[Up],bufUpDate[Up-1],bufUpPrice[Up-1]); 
      ObjectSet("LineUp"+Up,OBJPROP_COLOR,Blue);
      ObjectSet("LineUp"+Up,OBJPROP_RAY,False);
               //删除旧的线
               if (Up>lines+1)
               {
                  ObjectDelete("LineUp"+(Up-lines));
                  ObjectDelete("SimpleUp"+(Up-lines));                  
               }
            }     
        }
         //类似的代码块, 但是针对向下分形
        ExtMapBuffer2[i] = iFractals(NULL, 0, MODE_LOWER, i);
        buf = iFractals(NULL, 0, MODE_LOWER, i);    
        if (buf!=0)
        {
            Down++;
            bufDownPrice[Down]=iFractals(NULL, 0, MODE_LOWER, i);
            bufDownDate[Down]=Time[i];
            SellFractalLevel=bufDownPrice[Down];
                                         
            if (Down>1)
            
            {
               ObjectCreate("SimpleDown"+Down,OBJ_TREND,0,bufDownDate[Down],
                   bufDownPrice[Down],Time[i-1],bufDownPrice[Down]);        
               ObjectSet("SimpleDown"+Down,OBJPROP_COLOR,LightCoral);
               ObjectSet("SimpleDown"+Down,OBJPROP_RAY,True);
                                  
               ObjectCreate("LineDown"+Down,OBJ_TREND,0,
                            bufDownDate[Down],bufDownPrice[Down],
                            bufDownDate[Down-1],bufDownPrice[Down-1]);        
               ObjectSet("LineDown"+Down,OBJPROP_COLOR,Red);
               ObjectSet("LineDown"+Down,OBJPROP_RAY,False);
               if (Down>lines+1)
               {
                  ObjectDelete("LineDown"+(Down-lines));
                  ObjectDelete("SimpleDown"+(Down-lines));
               }            
            }
     
        }           
        if (!ShowHorisontalLines)
        {   
            ObjectDelete("SimpleDown"+Down);              
            ObjectDelete("SimpleUp"+Up);                
        }
        if (!ShowFractalLines)
        {
            ObjectDelete("LineDown"+Down);        
            ObjectDelete("LineUp"+Up);
        }          
     }   
//----
   return(0);
  }
//+----------------------------------------------------------------- 

旧的线必须删除, 否则图表看起来就像个调色板了. 指标还提供了一些额外的设置, 例如线是否可见或者可见线的数量. 指标活动的结果如下所示.




这是为喜欢分形人的特别准备.

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1429

附加的文件 |
FractalLines.mq4 (9.4 KB)
最近评论 | 前往讨论 (1)
JunCheng Li
JunCheng Li | 15 7月 2016 在 05:51
very good! Thanks!
测试可视化: 人工交易 测试可视化: 人工交易
在历史中测试人工交易策略. 看您的交易算法怎样从简单摆设变成编程之精华!
外汇交易的战术 外汇交易的战术
本文将有助于交易初学者建立其外汇交易中的战术.
MQL5中的错误处理和日志记录 MQL5中的错误处理和日志记录
本文着力介绍和软件错误处理相关的常见问题。另外,介绍了日志项及用MQL5工具包实现日志记录。
交易新手的十个"错误"? 交易新手的十个"错误"?
本文证实了, 构造一个随意的交易系统, 它只是进行一系列的建仓和平仓而不论现实情况如何 - 价格以及当前每个订单的盈利/亏损, 而它和传统的"提醒"交易系统结果差别并不大. 我们会给出一个这样基本交易系统的典型实现.