下载MetaTrader 5

交易货币篮子时可用的形态。第三部分

18 八月 2017, 09:20
Andrei Novichkov
0
2 934

概述

本文是第三篇也很可能是关于这个话题的最后一篇文章。我们已经研究和分析了主要和次要形态, 以及战术应用。我们的目标清单里没有包括复杂和模糊的技术描述, 如波浪分析或 VSA, 但我相信, 已提供的材料足够初步认识交易货币对篮子了。在本文中, 我们将尝试深入研究当结合振荡器和趋势跟踪指标时会发生的形态。在此我们将讨论组合趋势跟踪指标。

货币篮子指数作为源数据

在对 之前文章 的评论中, 我偶然发现了一个有前途的想法: 替代接收篮子当中每个货币对的指标值并定义平均值, 我们应该利用组合指标数据的方程 — 货币篮子指数。让我澄清一下。例如, 我们得到每个货币对的 WPR 标准技术指标的值, 来以计算组合的 WPR 数据。使用所获数值, 我们计算算术平均值 (通常, 我们也可以应用几何平均值)。组合 WPR 的结果显现出单一货币的行为 — "货币对篮子"。

在此, 我提出了一种获得相同数据的替代方法。以前, 我们已经讨论了货币篮子指数是什么, 以及如何计算它。您可能会记得, 这是篮中所有货币对价格的几何平均值, 即货币篮子的 "清算价格"。因此, 建议通过将标准 WPR 计算公式应用于货币篮子指数图表来获得组合的 WPR 值。相应地, 为了获得组合 RSI 或 STOCH 的值, 您应该使用它们的计算公式。这个想法似乎很有趣。让我们来考察一番。如果假设是正确的, 我们获得的组合指标值, 与使用前面文章中描述的方法收到的类似。

一开始, 我们需要两个指标, 它们的代码已附带于 wpr.zip 文件中:

  • testWPR 已在之前的文章之一里提供。使用一揽子货币对美元: EURUSD, GBPUSD, AUDUSD, NZDUSD, USDCAD, USDCHF 和 USDJPY。我们会用它作为参考进行比较。
  • WPR 技术指标代码。可以在 代码库 中找到它。我们在新指标中使用其片段来描绘我们感兴趣的方法。 

结果就是我们获得以下测试指标:

//+------------------------------------------------------------------+
//|                                                testIndex+WPR.mq5 |
//|                                   2016 MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "版权所有 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots   1


input color   clrWPR = clrGreen;
input int wprperiod  = 14; 

double ind[],ma[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                              |
//+------------------------------------------------------------------+

int OnInit()
  {
//--- 指标缓存区映射
     
  IndicatorSetDouble(INDICATOR_MINIMUM,-100);
  IndicatorSetDouble(INDICATOR_MAXIMUM, 0);   
      
   ArraySetAsSeries(ma,true);   
   SetIndexBuffer(0,ma);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE           ); 
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID            ); 
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1            ); 
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrWPR            ); 
   PlotIndexSetString (0, PLOT_LABEL, "_tstdistance_MA" );       
   
   ArraySetAsSeries(ind,true);
   SetIndexBuffer(1,ind , INDICATOR_CALCULATIONS);       
//---
   return(INIT_SUCCEEDED);
  }
  
string pair[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY"};
bool bDirect[]={false,false,false,false,true,true,true};
int iCount=7;

//计算. 索引  
double GetIndex(int shift) 
  {
   double res=1.0,t;
   double dBuf[1];
   for(int i=0; i<iCount; i++) 
     {
      t=CopyClose(pair[i],PERIOD_CURRENT,shift,1,dBuf);
      if(!bDirect[i]) dBuf[0]=1/dBuf[0];
      res*=dBuf[0];
     }//结束 for (int i = 0; i < iCount; i++)
   return (NormalizeDouble(MathPow (res, 1/(double)iCount), _Digits) );  
  }  
//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                |
//+------------------------------------------------------------------+
double HH,LL;

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
  
   if(prev_calculated==0 || rates_total>prev_calculated+1) 
     {
      int rt=rates_total;
      for(int i=1; i<rt; i++) 
        {
         ind[i]= GetIndex(i);
        }
      rt -= wprperiod;  
      for (int i = 1; i< rt; i++) 
        {
         ma[i] = GetMA(ind, i, wprperiod, _Digits);
        }        
     }
   else 
     {
         ind[0] = GetIndex(0);
         ma[0]  = GetMA(ind, 0, wprperiod, _Digits);
     }
   return(rates_total);
  }

//计算. WPR
double GetMA(const double& arr[], int index , int period, int digit) {
   double m = 0;
   HH = arr[ArrayMaximum(arr, index, period)];
   LL = arr[ArrayMinimum(arr, index, period)];   
   m = -100 * (HH - arr[index]) / (HH - LL);
   return (NormalizeDouble((m + 50) * 2, _Digits));
}


我们将它应用于 EURUSD 对, 一并还有 testWPRusd 参考指标。结果显示如下:


第一个子窗口显示我们的测试指标的曲线, 而第二个窗口显示参考指标的曲线。结果意外地令人失望。无论如何, 我们必须分析获得的结果。很快就变得明显, 测试指标不适合这种工作。它不断达到最大可能的数值。与此同时, 行情并没有什么特别的事情, 价格平静下滑。作为结果, 指标读数的梯度高得不合理。除此之外, 测试和参考指标中的极值位置相当吻合。为什么在极端情况下我们得到很好的匹配, 但如此奇怪的数值呢?答案很简单。原因在于 WPR 指标计算方程:

R% = - ((H – C)/(H – L)) x 100;

此处:

  • C: 收盘价;
  • L: 某一周期的最低价;
  • H: 某一周期的最高价.

但是我们没有最高价和最低价。测试指标使用货币篮子指数值计算其值, 而指数则依次以收盘价计算。由于这个纯粹的技术原因, 我们经常收到测试指标的极值。所以, 我们不能很自信地说这种方法本身是错误的或是非常不准确的。反而, 极值位置的匹配表明相反。是否有可能消除不期望的阻碍?

将组合的货币篮子指数指标绘制为蜡烛

当然,这是可能的。为了实现这一点, 我们应该获得源数据 (即货币篮子指数), 而不是基于收盘价的曲线, 而是作为日本蜡烛条。在此情况下, 我们将获得所有必需的数组, 并且能够执行 WPR 和其它计算。事实上, 货币篮子指数图表看起来与传统的价格图表相似, 尽管这是单一货币而非货币对的图表。我们也许会谨慎地认为, 这张货币篮子的价格图表是相对于形成篮子的所有货币。

技术上, 我们可以轻松获得这样的图表。常规的 "美元指数" 通常显示为蜡烛, 而不是单个收盘价。开发者如何获得类似的结果?所提供的测试指标使用当前时间帧内的蜡烛收盘价进行计算。如果我们用当前时间帧的蜡烛开盘价供给指标, 使用完全相同的计算, 开发者将获得定义蜡烛体实体的两个必要数值。不过, 也有坏消息。使用相同的方法来定义货币篮子指数蜡烛的最低点和最高点是不可能的。如果我们简单地计算货币对篮子蜡烛的最低和最高的平均值或几何平均值, 则所得到的值将不能提供货币篮子蜡烛的最低和最高的准确值。原因很明显: 篮子中个别货币对的最低位和最高位可能并不一定同时发生。当然这是可能的, 没有绝对保证。开发者也许要自行承担风险。他们将获得绘制蜡烛所需的所有值, 但误差幅度无法预先估计。为了获得保真值, 我们仍然应该使用即时报价或至少分钟进行计算。这样的计算令终端负担大大加剧, 所以最好把它们放在一个单独的应用程序中。

无论如何, 我们不会这样做。稍后我会解释一下原因。与此同时, 我们不得不得出结论, 所讨论的技术不适用于 WPR 为基础的组合指标, 以及其它使用开盘价和收盘价, 最低价和最高价数组进行计算的组合指标。对于其它指标类型, 此方法仍然令人感兴趣。我们将在下面介绍。

基于货币篮子指数的工具

我们已经分析了前一篇文章中货币篮子指数的应用实例。我的意思是将移动平均线应用于货币篮子指数图表。移动平均线是可靠的工具。它的应用为我们提供了一个形态 — 移动平均线与货币篮子指数图表的交叉点。我们早前描述过。我们来考察当使用货币篮子指数作为源数据时, 我们可以看到哪些可以使用的其它金融工具。当然, 由于文章的限制, 我们无法涵盖所有可用的金融工具, 但我们仍然可以概括前景。

我们应该记住, 货币篮子指数图表是一张价格图表。我们来试试确定主要的交易者工具 (支撑和阻力等级, 通道和菲波纳奇等级) 能否与之配合使用。此外, 还有大量文章阐述了将这些工具应用于指标图表的能力。我们也来尝试应用它们。要做到这一点, 我们放置两个美元和欧元货币篮子指数 (index.zip) 的组合指标, 并进行一些标准的安置:


我们已经在两个图表上放置了标准图形工具。这不是唯一可能的选项, 但它是相当真实的:

  • 欧元上的菲波纳奇, 上升通道和水平等级
  • 美元上的两条线形成一个楔形和水平等级

让我们用矩形和垂直线标出有趣的重点, 看看欧元兑美元的价格在它们附近的表现。

  1. 欧元指数从上方通道边界和菲波纳奇等级回滚。对于美元没有什么特别的发生 — 只是略有下降。我们能够预期走势在主图表上向卖出区域运动, 且真实发生了。
  2. 另一个从欧元通道上边界回滚。我们可以期待进一步的走势向卖出区域运动, 但这并未发生, 因为美元指数在楔形上边界附近移动。事实上, 这是一个横盘走势, 带有略微的买入趋势。
  3. 然而, 随着第 2 点继续, 欧元指数通道向下突破, 结合美元在第 5 点从楔形下边界回滚。在主图表上的卖出方向出现确切的逻辑移动。
  4. 从水平的欧元等级回撤与第 7 点处美元指数楔形突破相匹配。在一开始, 欧元回滚更为激烈, 价格进入卖出方向, 但是楔形突破 "超重", 走势转为买入。 

我们可以得出一些初步的结论。我们在此只考虑了一个复杂货币对的单一剧情, 所以我们的发现不应想当然地作为一个最终的真相。为了使其更可靠, 我们应对不同时间帧和货币对进行长期观察。然而, 结果令人欣慰。我们可以在货币对指数的综合指标图标上应用常见的图形结构。在构造过程中获得的形态遵循众所周知的规则:

  • 任何信号应由其它信号确认。
  • 与标准应用相比, 处理通过价格所获得的形态更具惯性。
  • 最终定论。以这种方式获得的形态具有次要性质。它们可以在搜索入场点时使用, 也可能在设置止损时使用。换言之, 这些形态是有用的, 但只起次要的作用。

我们来从另一个角度分析整个画面。您可能记得, 货币篮子指数显示了相对于货币篮子中所有货币对的状态。所以, 欧元指数图表不仅与欧元兑美元有关, 且与其它货币对相关联。我们只在其中一个方面得出结论。也许, 所获形态的 "次要性" 原因是交易者想要摆脱货币对篮子中第二货币的影响 (这里是美元) ?我们可以通过分析篮子里的其它货币对来轻松地检验我们的假设。例如, 我们取第 2 点, 2015.09.18 00:00。在这个点上, 我们假设价格从通道的上边界回滚, 且之后通道多头突破。欧元指数图表中找到感兴趣的点, 所以我们把所有货币对包含在欧元篮子里, 看看此刻价格发生了什么:


结果非常有趣并令人鼓舞!我们感兴趣的时间标记以蓝色垂直线高亮显示。我们的预测对于大多数货币对是合理的。如果一名交易者使用当前的 (相当弱的) 形态入场, 他们就会获得盈利。针对一些货币对的止损也是可能的。我的意思是 EURAUD 和 EURGBP, 以及 (在较小程度上) EURUSD。在其它货币对上, 交易者将获得盈利。使用货币对篮子的主要原则在此被证明是正确的: 一名交易者收到一个入场信号, 则形成货币篮子的所有货币对一次性入场。最终这会导致一些货币对的亏损, 但它们当中的大部分将获利。我们已在本系列的前几篇文章中详细描述了这一原则。请记住, 我们所有的结论都是概率性的。

由于针对单个点的分析不能作为任何假设的依据, 所以我们没有作出最后的结论。不过, 获得的结果可能激励交易者进行深入研究, 包括安排实验, 收集统计数据和发布结果。

返回文章的开头, 我们现在可以概括不用蜡烛图表形成一个货币篮子指数的组合指标的原因:

  • 对于单个货币对, 所检查的形态具有辅助性质。
  • 篮内的所有货币对并非都这样。只是需要依据历史进行分析。


简单的趋势指标

为了确认我们的结论, 我们来开发一款简单的组合指标, 遵照以下原则工作:

  • 计算并显示两条移动平均线 ("快速" 和 "慢速") 之间的差值, 用于源数据数组 (这里是欧元货币篮子指数的数组)。我们可以很容易看出, 操作原理与 MACD 指标相似。我们希望这个指标能够检测偏离。

指标代码 (包含在 testIndexMACD.zip):

//+------------------------------------------------------------------+
//|                                                testIndexMACD.mq5 |
//|                                   2016 MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "版权所有 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots   1


input color   clr = clrBlue;
input int InpFastEMA = 12;   // 快速 EMA 周期
input int InpSlowEMA = 26;   // 慢速 EMA 周期

double ind[],ma[];
//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                              |
//+------------------------------------------------------------------+
//int h,h1;
int OnInit()
  {
//--- 指标缓存区映射
   ArraySetAsSeries(ind,true);
   SetIndexBuffer(0,ind);        
   
   IndicatorSetString(INDICATOR_SHORTNAME,"testIndexMACD");
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_HISTOGRAM/*DRAW_LINE*/);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,clr);
   PlotIndexSetString(0,PLOT_LABEL,"_tstMACD_");    


   ArraySetAsSeries(ma,true);
   SetIndexBuffer(1,ma , INDICATOR_CALCULATIONS);   

//---
   return(INIT_SUCCEEDED);
  }
  
string pair[]={"EURUSD","EURJPY","EURCHF","EURGBP","EURNZD","EURCAD","EURAUD"};
bool bDirect[]={true,true,true,true,true,true,true};
int iCount=7;
  
double GetValue(int shift) 
  {
   double res=1.0,d;
   double dBuf[1];
   for(int i=0; i<iCount; i++) 
     {
      d=CopyClose(pair[i],PERIOD_CURRENT,shift,1,dBuf);
      if(!bDirect[i]) dBuf[0]=1/dBuf[0];
      res*=dBuf[0];
     }//结束 for (int i = 0; i < iCount; i++)
   return (NormalizeDouble(MathPow (res, 1/(double)iCount), _Digits) );  
  }  
//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                |
//+------------------------------------------------------------------+
double t;
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(prev_calculated==0 || rates_total>prev_calculated+1) 
     {
      int rt=rates_total;
      for(int i=1; i<rt; i++) 
        {
         ma[i]= GetValue(i);
        }
      rt=rates_total - InpSlowEMA;  
      for(int i=1; i<rt; i++) 
        {
         ind[i] = GetMA(ma, i, InpFastEMA, _Digits) - GetMA(ma, i, InpSlowEMA, _Digits);
        }        
     }
   else 
     {
         ma[0]= GetValue(0);
         ind[0] = GetMA(ma, 0, InpFastEMA, _Digits) - GetMA(ma, 0, InpSlowEMA, _Digits);
     }
//--- 返回 prev_calculated 的值用于下次调用
   return(rates_total);
  }

//+------------------------------------------------------------------+

double GetMA(const double& arr[], int index , int period, int digit) {
   double m = 0;
   for (int j = 0; j < period; j++)  m += arr[index + j];
   m /= period;
   return (NormalizeDouble(m,digit));
}

将此指标放置于图表上, 当使用欧元指数作为来源时, 我们将会看到以下内容:


... 并检测其中一个片段上的偏离。价格图表上的阻力线指示下降趋势, 但我们指标的变化动态会警示趋势走弱或即将结束。事实上, 我们可以看到一个趋势的未来逆转。其它货币对的价格行为确认了我们的结论:

这种特殊状况证实了我们以前的结论, 即本文中研究的形态应该谨慎地应用于独立货币对。与此同时, 我们将这些形态应用于整个篮子的货币对时会更有信心。

结论

我们已完成了交易货币对篮子时出现的形态分析。我们来总结一下应用所有已描述形态进行交易的一般规则。

  • 当组合指标的图表与超卖/超买等级交叉, 且读取基准货币和报价货币的组合振荡指标(WPR, STOCH) 之间有差异时, 此刻产生的形态精准度较高。我们可在蜡烛收盘后入场, 即确认超卖/超买等级的突破和可能的新趋势。入场在单个货币对上执行 — 您启动指标的那一个。指标到达接近零点区域或指标的相反边界范围之后, 我们可以离场:

    在后一种情况下, 当接近零点附近的区域时, 已开单应将止损移至盈亏平衡价位。注意虚的买入信号。这已在 此处 讨论过。也可以根据指标设置止损。如果指标未移向零点, 当超买/超卖等级突破以后, 可被触发。代之, 它若反转, 再次与超买/超卖交叉, 巩固并开始在范围边界之后移动。
  • 显示货币篮子状态的组合振荡器指标 (WPR, STOCH) 存在相同的形态。以下是欧元的组合 WPR 图表:

    入场和离场规则保持不变, 尽管入场是针对所有篮子内货币执行而非单个。注意能够止损的点位。此处仅用于描绘目的。一名交易者未必会在那修复亏损。此处和前一段落中使用的指标可在附带的 wpr2.zip 存档中找到。
  • 除了上述两个之外, MA 图表的交集可以作为辅助形态。如果这种情况发生在超买/超卖等级突破附近, 这就是对两种形态的强化。
  • 当应用组合趋势指标时形成的形态也具有辅助性。没有理由推荐入场, 但它们可以使用前两种形态作为附加信号。

在此阶段, 不可能用数字和意义深长的统计给出准确的交易建议。缺乏历史研究是所有已描述形态的严重缺点。我们将在以后的文章中解决这个问题。

文章中使用的程序:

 # 名称
类型
 描述
1 wpr.zip 存档
含有参考的 testWPRusd 指标 (代码和执行模块), 以及 WPR 技术指标代码 - wpr.mq5
2
testIndex+WPR.mq5 指标 测试组合指标绘制 WPR 基于货币篮子指数计算方程得到的值。
3
 index.zip    存档  两个结合美元和欧元货币篮子指数的指标
 4  testIndexMACD.zip   存档  基于 MACD 的简单趋势指标
5
 wpr2.zip  存档  示意入场和离场的指标


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

附加的文件 |
testIndex8WPR.mq5 (6.93 KB)
index.zip (3.25 KB)
testIndexMACD.ZIP (1.65 KB)
wpr.zip (3.22 KB)
wpr2.zip (4.83 KB)
基于 MQL5 源代码创建文档 基于 MQL5 源代码创建文档

本文研究从所需的标签标记开始自动为 MQL5 代码创建文档。它还提供了如何使用、如何正确配置 Doxygen 软件, 以及如何以不同格式接收结果 (包括 html, HtmlHelp 和 PDF) 的说明。

排序方法并利用 MQL5 进行可视化 排序方法并利用 MQL5 进行可视化

Graphic.mqh 函数库以 MQL5 设计, 用来处理图形。本文提供了一个实际应用的例子, 并解释了排序的思路。这里描述排序的一般概念, 因为每种排序类型至少已经具有一篇单独的论文, 而有些排序类型更是详细研究的对象。

图形界面 XI: 重构函数库代码 (集成编译 14.1) 图形界面 XI: 重构函数库代码 (集成编译 14.1)

随着函数库的增长, 其代码必须重新优化以便减少其大小。本文中描述的函数库版本已变得更加面向对象。这令代码更容易学习。最新变化的详细描述将令读者能够根据自己的需求独立开发函数库。

图形界面 XI: 渲染控件 (统合构建14.2) 图形界面 XI: 渲染控件 (统合构建14.2)

在新版本的函数库中, 所有控件将在 OBJ_BITMAP_LABEL 类型的单独图形对象上绘制。我们还将继续描述代码的优化: 讨论函数库核心类的变化。