DiNapoli 交易系统

Roman Vashchilin | 10 七月, 2017


内容

  1. 概述
  2. DiNapoli 等级: 基础
  3. 主要原理和概念
  4. 菲波纳奇/DiNapoli 扩展
  5. DiNapoli 等级交易技术
  6. 扫雷器 A 和扫雷器 B 策略
  7. DiNapoli 等级指标
  8. 结论
  9. 参考

1. 概述

每天均会出现新的交易策略和经典交易系统的改编版。最著名的方法之一是由交易员、财经专家和流行书籍的作者 Joe DiNapoli 创建的。他那个被广泛使用的系统是基于斐波纳契等级。

在本文中, 我们将仔细考察这个系统。我已尽力解释了基本概念和交易原则, 否则无法在不熟悉斐波纳契等级的情况下进行描述。那么, 这些等级是什么?在实践中如何解读并应用它们?更重要的是, 它们如何在交易中工作?

2. DiNapoli 等级: 基础


DiNapoli 等级基础

我们来研究 DiNapoli 等级交易的一般原则, 包括如何在图表上正确绘制它们, 解释它们相对于价格走势的读数, 并利用它们来定义入场点。

正如我曾经说过的话, DiNapoli 策略是基于菲波纳奇等级。在此方法中仅使用水平标注。不会采用菲波纳奇的弧形和扇形。

错误的菲波纳奇等级定位


正确的菲波纳奇等级定位

DiNapoli 等级本质上是支撑和阻力级别, 尽管它们的解释比传统级别更深奥。它们基于菲波纳奇等级, 并利用所谓的 市场波段 (见下文), 或更简单地说是趋势。DiNapoli 只需要三个菲波纳奇等级: 61.8%, 50% 和 38.2%。这些级别在您的图表上可作为支撑和阻力。在上行趋势的情况下, 菲波纳奇等级向上绘制, 而下行趋势情况时, 则向下。

理想情况下, 等级线在当前趋势的方向上从 0% 到 100% 排列。所有超过 100% 的菲波纳奇等级都用于设置平仓点。

行情波段

DiNapoli 等级能以两种方式应用 — 作为延伸和回调。 

回调 用来判断目标入场点, 而构建的 延伸 网格用于离场点的检测。

3. 主要原理和概念

  • 菲波纳奇节点 — 价格图表点, 回调走势结束。Joe DiNapoli 建议只在 38.2% 到 61.8% 之间的节点上操作。所有位于 38.2% 以下的节点都不太重要, 而超过 61.8% 的节点太强 (意味着趋势可能无法恢复)。
  • 行情波段 (极值之间的距离) — 价格走势从开始到结束的距离, 菲波纳奇等级依此而绘制。如果在回调结束后价格最高点或最低点发生变化, 您还应该移动等级线的端点。在此情况下, 波段增长。
  • 积累 — 位于图表上的某处, 其内检测到多个菲波纳奇节点 (多次回调的等级彼此接近) 的累积。
  • 焦点 (极值) — 行情波段的极点 (价格回调的起始等级)。当极值发生变化时, 图表上会出现另一个焦点。因此, 在一个波段区域中, 图表上可能有多个点。  
  • 目标等级 — 在价格图表上指向您期望的盈利位置。
  • 目标点 — 所有图表上的点都代表一次有计划的动作 (入场, 离场等)。
  • 反弹在趋势走势中回调完毕。在一个单独的波段半径内也许会形成若干个反弹。

延伸, 回调和焦点


价格图表持续变化, 每次行情波段都应相对于图表进行回调。在此情况下, 每次波段均会扩展, 导致图表上焦点数量的变化。称为 "反弹" 的价格回调出现在行情波段的中间。它们中的每一个都有自己的索引。

图表上的反弹

来自 DiNapoli 的提示

  • 只有当回调等级和积累等级处于 38.2% - 61.8% 的范围内, 接收的信号才会产生结果。其它信号则被忽略。
  • 使用最后一次到达的菲波纳奇等级作为止盈位, 并将止损位设置在 161.8% 和 261.8%。
  • 图表上的波段数量总是等于焦点数量。
  • 焦点号码总是位于与其相关联的反弹的右侧。换言之, 在等级上形成的价格回调波段应位于焦点号码的左侧。
  • 时间帧越高, 反弹次数越少。正如您可能已经注意到的那样, 在不同的时间帧内操作时, 在较小的时间周期内价格变动相当快, 而这些走势甚至不会显示在较高的时间帧上。此规则也能以相反的顺序使用: 当价格检测到强阻力/支撑时, 您可以通过使用较低的时间帧, 找出未显示在较高时间帧内的必要反弹和波段。

4. 菲波纳奇/DiNapoli 扩展

DiNapoli 扩展网格允许我们基于菲波纳奇扩展网格定义离场点。这一次, 我们将使用 100%, 161.8% 和 261.8% 的等级作为设定止盈的目标点。

菲波纳奇 (DiNapoli) 等级扩展

菲波纳奇扩展网格的构建方式如下:

  • 对于下行趋势 — 从最低价开始至价格回滚线的 38.2%及以上形成的回调峰值。
  • 对于上行趋势 — 从最低价开始至价格回调的最小值与等级 38.2%及以上的交叉。

在图表上放置菲波纳奇扩展网格

在 "DiNapoli 等级交易" 一书中, 作者极其重视 "多重焦点数字" 和 "行情波段" 等概念。当交易工具频繁横盘时这些形态很典型。这种形态比简单的波段更复杂。主要的困难是剔除不必要的等级。

我来简要地列出我在阅读这本书后所做的结论。这本书无可争议的优点在于它不是由理论家写的, 而是由经验丰富的交易员和管控者所撰写的。另一个有力的坚实论据是它使用经过数百年时间测试的菲波纳奇等级, 并在数学上得到均衡和验证。此外, 本书中提供的例子不仅描述了商品和股票市场, 还描述了货币期货交易, 其原则可以应用于外汇市场。

由 DiNapoli 引入的许多新概念也需要仔细研究和全面的了解。

5. DiNapoli 等级交易技术

现在, 我们来研究使用 DiNapoli 等级进行交易。简言之, 在他书中描述的基本思想令我们能够开发出若干种 "激进" 和 "稳健" 等级的交易策略。

  • 激进 具有两种入场方式: 灌木丛与盆景策略。交易原则是类似的, 唯一的区别是止损的放置。
  • 稳健 也描述了两种策略: 扫雷器 A 和 B。

当采用激进的交易方式时, 假设价格从等级 38.2% 回滚, 且波段已经形成。灌木丛和盆景策略之间的唯一区别在于此后设定止损的菲波纳奇等级。

我们从 灌木丛 交易方法开始吧。按照这种方法, 当前趋势方向上产生的回调网格的价格走势跨越了 38.2% 等级则要开仓, 而止损位则要比 50% 等级更远。依据 盆景 方法, 入场与灌木丛, 不过止损位设定在 50% 以下的菲波纳奇等级上。

以下这些方法被认为是激进的, 因为有可能在图表上不会出现价格回滚。回调转化为新的趋势是很平常的, 或者价格可能进入短期横盘。所以, 如果您决定采用此方法, 请等待全部确认信号处于安全一侧。

灌木丛策略

本书还描述了盆景策略的一些负面特征。DiNapoli 强调, 要考虑到由于没有强力等级, 即交易数量不足且没有稳固的请求与之相匹配, 在此情况下, 挂单执行时可能会有相当大的滑点。因此, 选择取决于经纪公司和交易平台。另一方面, 如果您以很小交易量在市场中交易高流动性的金融工具, 则这种状况是不可能发生的。

6. 扫雷器 A 和扫雷器 B 策略

最安全、风险最小的策略是扫雷器 A 和 B。依据它们, 应在回调后执行入场, 而交易本身则采用安全措施进行。

  • 扫雷器 A. 首先, 我们等待初始回调完成 (无入场), 然后是第二次回调的形成。只有在此之后, 我们才能开仓。设置止损的方式与上一策略相同, 即在下一个菲波纳奇等级之后。
  • 扫雷器 B. 不会在第二次形成的回调之后开仓, 而是在第三、第四甚至更晚之后才会开仓。换言之, 只有在趋势彻底确定后才入场, 意味着假信号的风险大大降低。
策略的结果是怎样?入场并不频繁。一次趋势并非总是足够长存, 并为交易系统的规则提供连续 3 个或更多的回调走势 (回滚应在 38.2% 到 61.8%之间结束)。另一方面, 这可令我们能够排除其中的价格回调不会成为趋势延续的假信号。

扫雷器 A 策略

如果您遇到一次相当长期的趋势, 多次回调 (反弹), 并遵循所有的分析规则, 您的图表很快就会散布着许多不重要的等级和线条。它们中的大多数可以简单地作为冗余数据丢弃, 这些数据不属于 DiNapoli 等级交易规则。

假设您看到一个带有几次反弹的强劲上行趋势。在某个时刻, 您会遇到所有上行走势的调整。结果就是, 价格开始重写一些反弹的低点。这种反弹应该取消, 并且丢弃它们的低点。

7. DiNapoli 等级指标

对于那些不愿意花时间通过放置菲波纳奇等级来手工绘制 DiNapoli 等级的人, 这儿有一款指标可自动完成。指标附加在下面。它也可以在 代码库 里找到。我们来分析它的更多运作详情。为方便起见, 指标名称已更改。

指标以通常的方式安装, 将文件放置到 MetaTrader 5 根目录的 Indicators 文件夹中。它没有太多的设置, 大多数是等级的颜色。颜色是可定制的, 但若您是新手, 我不建议您更改它们, 以避免显示和市场分析错误。

指标自动显示 DiNapoli 等级, 并且还包括具有反转音频信号的之字折线。红线在图表上标记放置止损的位置, 而蓝色标记显示操作开始等级。其余的等级线是价格目标。此外, 指标显示垂直时间布局线 (可在指标设置中禁用)。

指标输入

在终端的价格图表上显示 DiNapoli 等级

输入:

  • 射线中的最小点 (省缺 = 400) – 更改垂直时间等级的宽度;
  • 显示垂直线 (省缺 = true) – 显示/隐藏垂时间等级;
  • 历史柱线数量 (省缺 = 5000) – 内置之字折线指标使用的历史柱线数量;
  • 播放声音 (省缺 = true) – 在之字折线改变其方向时, 启用音频通知;
  • 声音文件 (省缺 = "expert.wav") – 选择音频通知文件;
  • 起始线颜色 (省缺 = Blue) – 起始水平线颜色;
  • 终止线颜色 (省缺 = Red) – 设置止损的水平线颜色;
  • 目标1 线颜色 (省缺 = Green) – 目标 1 的水平线颜色;
  • 目标2 线颜色 (省缺 = DarkOrange) – 目标 2 的水平线颜色;
  • 目标3 线颜色 (省缺 = DarkOrchid) – 目标 3 的水平线颜色;
  • 目标4 线颜色 (省缺 = DarkSlateBlue) – 目标 4 的水平线颜色;
  • 时间目标1 颜色 (省缺 = DarkSlateGray) – 垂直线 1 颜色;
  • 时间目标2 颜色 (省缺 = SaddleBrown) – 垂直线 2 颜色;
  • 时间目标3 颜色 (省缺 = DarkSlateGray) – 垂直线 3 颜色;
  • 时间目标4 颜色 (省缺 = DarkSlateGray) – 垂直线 4 颜色。

首先, 我们来介绍一下基本的指标参数。

初始代码参数如下所示:

//------------------------------------------------------------------------------------
//                                                                 DiNapoli Levels.mq5
//                                                                改编版指标 FastZZ.mq5
//                                                      添加 DiNapoli 目标等级和时间等级
//                                                         victorg, www.mql5.com, 2013
//------------------------------------------------------------------------------------
#property copyright   "版权所有 2012, Yurich"
#property link        "https://login.mql5.com/en/users/Yurich"
#property version     "3.00"
#property description "FastZZ 加上 DiNapoli 目标等级。"
#property description "改编版指标 'FastZZ.mq5'。"
#property description "victorg, www.mql5.com, 2013."
//------------------------------------------------------------------------------------
#property indicator_chart_window // 在图表窗口里显示指标
#property indicator_buffers 3    // 指标计算的缓存区数量
#property indicator_plots   1    // 图板数量
#property indicator_label1  "DiNapoli Levels" // 设置图形序列的标签
#property indicator_type1   DRAW_COLOR_ZIGZAG // 指标的绘制样式。N - 图形序列号码
#property indicator_color1  clrTeal,clrOlive  //  N 号线的输出颜色, 此处 N 是图形序列的号码
#property indicator_style1  STYLE_SOLID       // 图形序列的线型
#property indicator_width1  1    // 图形序列的线宽
//------------------------------------------------------------------------------------
input int    iDepth=400;              // 射线的最小值
input bool   VLine=true;              // 显示垂直线
input int    iNumBars=5000;           // 历史柱线数量
input bool   Sound=true;              // 启用声音通知
input string SoundFile="expert.wav";  // 音频文件
input color  cStar=clrBlue;           // 起始线颜色
input color  cStop=clrRed;            // 终止线颜色
input color  cTar1=clrGreen;          // 目标线 #1 颜色
input color  cTar2=clrDarkOrange;     // 目标线 #2 颜色
input color  cTar3=clrDarkOrchid;     // 目标线 #3 颜色
input color  cTar4=clrDarkSlateBlue;  // 目标线 #4 颜色
input color  cTarT1=clrDarkSlateGray; // 时间线 #1 颜色
input color  cTarT2=clrDarkSlateGray; // 时间线 #2 颜色
input color  cTarT3=clrSaddleBrown;   // 时间线 #3 颜色
input color  cTarT4=clrDarkSlateGray; // 时间线 #4 颜色
input color  cTarT5=clrDarkSlateGray; // 时间线 #5 颜色

我们进入指标的变量。

//主要变量
double   DiNapoliH[],DiNapoliL[],ColorBuffer[],Depth,A,B,C,Price[6];
int      Last,Direction,Refresh,NumBars;
datetime AT,BT,CT,Time[5];
color    Color[11];
string   Name[11]={"起始线","终止线","目标1 线","目标2 线",
                   "目标3 线","目标4 线","时间目标1","时间目标2",
                   "时间目标3","时间目标4","时间目标5"};

设定主要参数并进入变量之后, 现在是开发指标主要部分的时候了。

主要部分:

// 开始指标初始化
void OnInit()
  {
  int i;
  string sn,sn2;
  
// 设置射线端点的条件
  if(iDepth<=0)Depth=500; 
  else Depth=iDepth;   
  
// 设定历史柱线的条件     
  if(iNumBars<10)NumBars=10;
  else NumBars=iNumBars;
  
// 设置指标的显示缓冲区  
  SetIndexBuffer(0,DiNapoliH,INDICATOR_DATA); 
  SetIndexBuffer(1,DiNapoliL,INDICATOR_DATA);
  SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);
  
// 设置指标值显示的精度
  IndicatorSetInteger(INDICATOR_DIGITS,Digits()); 
  
// 设置线条消隐的空值  
  PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); 
  PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0); 
  
// 为指标设置一个简短的名称  
  sn="DiNapoli"; sn2=""; 
  for(i=1;i<100;i++)
    {
// 设置图表搜索   
    if(ChartWindowFind(0,sn)<0){break;}
    sn2="_"+(string)i; sn+=sn2;
    }
    
// 设置品种显示    
  IndicatorSetString(INDICATOR_SHORTNAME,sn);
  for(i=0;i<11;i++) Name[i]+=sn2;
  
// 用空值初始化缓冲区   
  ArrayInitialize(DiNapoliH,0); ArrayInitialize(DiNapoliL,0);

我们继续开发这个指标:

// 调整指标线颜色
  Color[0]=cStar; Color[1]=cStop; Color[2]=cTar1; Color[3]=cTar2;
  Color[4]=cTar3; Color[5]=cTar4; Color[6]=cTarT1; Color[7]=cTarT2;
  Color[8]=cTarT3; Color[9]=cTarT4; Color[10]=cTarT5;
  Depth=Depth*_Point;
  Direction=1; Last=0; Refresh=1;
  for(i=0;i<6;i++)
    {
    if(ObjectFind(0,sn)!=0)
      {
      
// 设置水平和垂直线     
      ObjectCreate(0,Name[i],OBJ_HLINE,0,0,0);
      ObjectSetInteger(0,Name[i],OBJPROP_COLOR,Color[i]);
      ObjectSetInteger(0,Name[i],OBJPROP_WIDTH,1);
      ObjectSetInteger(0,Name[i],OBJPROP_STYLE,STYLE_DOT);
//    ObjectSetString(0,Name[i],OBJPROP_TEXT,Name[i]);// 对象描述
      }
    }
  if(VLine==true)
    {
    for(i=6;i<11;i++)
      {
      if(ObjectFind(0,sn)!=0)
        {
        ObjectCreate(0,Name[i],OBJ_VLINE,0,0,0);
        ObjectSetInteger(0,Name[i],OBJPROP_COLOR,Color[i]);
        ObjectSetInteger(0,Name[i],OBJPROP_WIDTH,1);
        ObjectSetInteger(0,Name[i],OBJPROP_STYLE,STYLE_DOT);
//      ObjectSetString(0,Name[i],OBJPROP_TEXT,Name[i]);// 对象描述
        }
      }
    }
  }
  
// 添加功能, 当从图形中删除指标时, 从指标中删除图形对象
void OnDeinit(const int reason)
  {
  int i;
   
  for(i=0;i<11;i++) ObjectDelete(0,Name[i]);
  ChartRedraw();
  return;
  }

现在, 我们来计算指标缓冲区:

// 指标的迭代函数
int OnCalculate(const int total,        // 输入时间序列的大小
                const int calculated,   // 已处理的柱线调用
                const datetime &time[], // 时间值数组
                const double &open[],   // 开盘价数组
                const double &high[],   // 用于复制最大价格的数组
                const double &low[],    // 最小价格数组
                const double &close[],  // 收盘价数组
                const long &tick[],     // 参数包含即时报价交易量的历史
                const long &real[],     // 真实交易量
                const int &spread[])    // 数组包含历史点差

  {
  int i,start;
  bool set;
  double a;

// 设置柱线检查
  if(calculated<=0)
    {
    start=total-NumBars; if(start<0)start=0;
    
// 用空值初始化缓冲区  
    Last=start; ArrayInitialize(ColorBuffer,0);
    ArrayInitialize(DiNapoliH,0); ArrayInitialize(DiNapoliL,0);
    }
    
// 计算一根新柱线    
  else start=calculated-1;
  for(i=start;i<total-1;i++)
    {
    set=false; DiNapoliL[i]=0; DiNapoliH[i]=0;
    if(Direction>0)
      {
      if(high[i]>DiNapoliH[Last])
        {
        DiNapoliH[Last]=0; DiNapoliH[i]=high[i];
        if(low[i]<high[Last]-Depth)
          {
          if(open[i]<close[i])
            {
            DiNapoliH[Last]=high[Last];
            A=C; B=high[Last]; C=low[i];
            AT=CT; BT=time[Last]; CT=time[i];
            Refresh=1;
            }
          else
            {
            Direction=-1;
            A=B; B=C; C=high[i];
            AT=BT; BT=CT; CT=time[i];
            Refresh=1;
            }
          DiNapoliL[i]=low[i];
          }
          
// 设置线条颜色      
        ColorBuffer[Last]=0; Last=i; ColorBuffer[Last]=1;
        set=true;
        }
      if(low[i]<DiNapoliH[Last]-Depth&&(!set||open[i]>close[i]))
        {
        DiNapoliL[i]=low[i];
        if(high[i]>DiNapoliL[i]+Depth&&open[i]<close[i])
          {
          DiNapoliH[i]=high[i];
          A=C; B=high[Last]; C=low[i];
          AT=CT; BT=time[Last]; CT=time[i];
          Refresh=1;
          }
        else
          {
          if(Direction>0)
            {
            A=B; B=C; C=high[Last];
            AT=BT; BT=CT; CT=time[Last];
            Refresh=1;
            }
          Direction=-1;
          }
          
// 设置线条颜色
        ColorBuffer[Last]=0; Last=i; ColorBuffer[Last]=1;
        }
      }
    else
      {
      if(low[i]<DiNapoliL[Last])
        {
        DiNapoliL[Last]=0; DiNapoliL[i]=low[i];
        if(high[i]>low[Last]+Depth)
          {
          if(open[i]>close[i])
            {
            DiNapoliL[Last]=low[Last];
            A=C; B=low[Last]; C=high[i];
            AT=CT; BT=time[Last]; CT=time[i];
            Refresh=1;
            }
          else
            {
            Direction=1;
            A=B; B=C; C=low[i];
            AT=BT; BT=CT; CT=time[i];
            Refresh=1;
            }
          DiNapoliH[i]=high[i];
          }
          
// 设置线条颜色           
        ColorBuffer[Last]=0; Last=i; ColorBuffer[Last]=1;
        set=true;
        }
      if(high[i]>DiNapoliL[Last]+Depth&&(!set||open[i]<close[i]))
        {
        DiNapoliH[i]=high[i];
        if(low[i]<DiNapoliH[i]-Depth&&open[i]>close[i])
          {
          DiNapoliL[i]=low[i];
          A=C; B=low[Last]; C=high[i];
          AT=CT; BT=time[Last]; CT=time[i];
          Refresh=1;
          }
        else
          {
          if(Direction<0)
            {
            A=B; B=C; C=low[Last];
            AT=BT; BT=CT; CT=time[Last];
            Refresh=1;
            }
          Direction=1;
          }
// 设置线条颜色            
        ColorBuffer[Last]=0; Last=i; ColorBuffer[Last]=1;
        }
      }
    DiNapoliH[total-1]=0; DiNapoliL[total-1]=0;
    }
//------------
  if(Refresh==1)
    {

指标的最后计算循环:    

// 检查足够计算的柱线数
    Refresh=0; a=B-A;
    Price[0]=NormalizeDouble(a*0.318+C,_Digits);           // 起始;
    Price[1]=C;                                            // 终止
    Price[2]=NormalizeDouble(a*0.618+C,_Digits);           // 目标t№1
    Price[3]=a+C;                                          // 目标№2;
    Price[4]=NormalizeDouble(a*1.618+C,_Digits);           // 目标№3;
    Price[5]=NormalizeDouble(a*2.618+C,_Digits);           // 目标№4;
    for(i=0;i<6;i++) ObjectMove(0,Name[i],0,time[total-1],Price[i]);
    if(VLine==true)
      {
 
// 返回与指定值最接近的整数舍入值      
      a=(double)(BT-AT);
      Time[0]=(datetime)MathRound(a*0.318)+CT;             // 临时目标号码 №1
      Time[1]=(datetime)MathRound(a*0.618)+CT;             // 临时目标号码 №2
      Time[2]=(datetime)MathRound(a)+CT;                   // 临时目标号码 №3
      Time[3]=(datetime)MathRound(a*1.618)+CT;             // 临时目标号码 №4
      Time[4]=(datetime)MathRound(a*2.618)+CT;             // 临时目标号码 №5
      for(i=6;i<11;i++) ObjectMove(0,Name[i],0,Time[i-6],open[total-1]);
      }
    ChartRedraw();
    
// 如果方向改变, 则打开音频播放
    if(Sound==true&&calculated>0)PlaySound(SoundFile);
    }
  return(total);
  }
//------------------------------------------------------------------------------------

指标附加在下面。

8. 结论

我希望这篇文章能为您提供在交易中应用 DiNapoli 方法的足够数据。DiNapoli 等级提供了操纵标准菲波纳奇等级和扩展功能的原始方法。操纵等级的核心原则依然不变。DiNapoli 已经简单地引入了一些新规则, 并在市场上得到了可靠的结果。

文章中使用的程序:

 # 名称
类型
 描述
1 DiNapoli  Levels.mq5                 指标  用于自动计算并绘制 DiNapoli 等级的指标

9. 参考

  1. Joe DiNapoli. DiNapoli 等级: 运用菲波纳奇分析投资市场的实际应用。海岸投资软件有限公司, 第二版 (1998)