: | : | :期货程序化 | :期货程序化研究 | :期货量化学习 | :期货量化 |
返回列表 发帖

ADX函数系列

ADX函数系列

ADX函数系列包括函数DirMovement、DMI、DMIMinus、DMIPlus、ADX、AvgTrueRange等函数,详细的请看表1 ADX函数系列,它们是由威尔斯·怀尔德(Welles Wilder)创造出来的。


                                                                      表1 ADX函数系列

  

ADX函数系列

  

功能

DirMovement

全称Directional Movement,被函数DMI、DMIMinus、DMIPlus、ADX和Volatility调用

DMI

计算DX指数(Directional Movement Index,动向指数)

DMICustom

和函数DMI相同,不同的是多了三个价格输入参数

DMIMinus

计算-DI指数(负向指数)

DMIMinusCustom

和函数DMIMinus相同,不同的是多了三个价格输入参数

DMIPlus

计算+DI指数(正向指数)

DMIPlusCustom

和函数DMIPlus相同,不同的是多了三个价格输入参数

ADX

计算ADX指数(Average Directional Movement Index,平均动向指数)

ADXCustom

和函数ADX相同,不同的是多了三个价格输入参数

ADXClassic

和函数ADX相同,不同的是ADXClassic对结果取整

ADXCustomClassic

和函数ADXCustom相同,不同的是ADXCustomClassic对结果取整

ADXR

计算(ADX(len)+ADX(len)[len-1])/2的值,len需要计算bar的数量

ADXRCustom

和函数ADXR相同,不同的是多了三个价格输入参数

ADXRClassic

和函数ADXR相同,不同的是ADXRClassic对结果取整

ADXRCustomClassic

和函数ADXRCustom相同,不同的是ADXRCustomClassic对结果取整

Volatility

计算平均真实波幅,使用加权平均计算平均真实波幅

XAverageOrig

怀尔德平滑(Wilder’s Smoothing),以1/len和1-1/len为权重的加权移动平均

TrueHigh

当根bar的最高价与前一根bar的收盘价,取最高值

TrueLow

当根bar的最低价与前一根bar的收盘价,取最低值

TrueRange

计算真实波幅,TrueHigh-TrueLow

XAverage

指数移动平均函数

TrueRangeCustom

和TrueRange相同,不同的是多了三个价格输入参数

AvgTrueRange

平均真实波幅(Average True Range,简称ATR指数),使用简单平均函数计算平均真实波幅


表1中总共有23个MC内置的函数,大部分是通过直接或间接调用DirMovement来计算,所以我们只需要将DirMovement函数背后的原理及逻辑弄清楚,其它的函数也就会很清楚,进一步,由这些函数组合得到的指标也能很快掌握并且熟练应用。下面主要通过对ADX指数的计算来介绍DirMovement函数的逻辑,然后再介绍其它函数及相同功能函数之间的比较。

1. ADX

1.1 ADX简介

绝大多数指标的计算都是以每一日的收盘价的走势及涨跌幅的累计数计算出不同的分析数据,其不足之处在于忽略了每一日的高低价之间的波动幅度。比如某个股票的两天的收盘价可能是一样的,但是其中一天的波动幅度只有2%,而另一天的波动幅度是10%,如果仅仅考虑收盘价而忽略了每天市场的价格波动幅度,那么并不能很好的判断和分析市场行情。ADX指数的出现弥补了这一不足,它主要用于分析市场的涨跌力度,但并不反应市场涨跌的方向;ADX全称为Average Directional Movement Index,是对Directional Movement Index(动向指数,简称DX)的加权平均,而DX是市场正向波动和市场负向波动的绝对差除以市场正向波动和市场负向波动之和得到的,其中市场正向波动和市场负向波动分别由+DI和-DI指数(前面的”+“和”-“只是代表方向,并不起到数学符号的作用)衡量。当市场出现一波上涨或者下跌时,ADX指数会随之上升,在实盘操作中,常将ADX与+DI和-DI指标结合起来判断市场买卖点。

1.2 ADX指数计算逻辑

通过当根bar的最高价与前一根bar的最高价进行比较,计算得到当根bar的正向波动值+DM=max(high-high[1],0);通过前一根bar的最低价与当根bar的最低价进行比较,计算得到当根bar的负向波动值-DM=max(low[1]-low,0);但是每一根bar只允许有一个波动方向,也就是说只允许有一个波动值,不能同时存在正向波动值和负向波动值,这时,我们需要对+DM和-DM进行比较,取最大值作为当根bar的波动值,波动的方向和最大波动方向一致,另一个波动值赋值为0;举例说明,如果计算出+DM=2.3,-DM=2.1,那么+DM就是当根bar的波动值,方向是正向波动,同时-DM重新赋值为0。

在计算完当根bar的波动之后,还需要计算当根bar的真实波动幅度,真实波动幅度和之前的正向波动及负向波动不一样,真实波动幅度没有方向,只是用来衡量当根bar价格波动幅度,简称TR(True Range);它是通过max(high,close[1])-min(low,close[1])计算得到。将TR进行移动平均计算之后,可以得到Volatility和ATR,即平均真实波动幅度(Average True Range),具体使用加权平均还是指数平均因策略而异,ADX中计算的Volatility是使用XAverageOrig函数进行计算的。

对于不同的商品合约及不同的周期,每一根bar正向波动和负向波动值差异很大,为了使用统一的标准对市场进行判断分析,需要先对正向波动、负向波动及真实波动幅度进行加权移动平均计算,然后通过平均正向波动与平均真实波幅的比值得到正向指数+DI,通过平均负向波动与平均真实波幅的比值得到负向指数-DI,这里的平均计算统一使用XAverageOrig函数进行计算,平均计算使用多少根bar来计算没有统一的规定(本文以len代替)。

+DI和-DI计算出来之后,可以很容易得到DX指数、ADX指数和ADXR指数。DX=|(+DI)-(-DI)|/((+DI)+(-DI)),这里+DI和-DI都被括起来了;ADX是DX的加权移动平均;ADXR=(ADX+ADX[len-1])*0.5;下面通过DirMovement函数的代码来进一步严谨的介绍ADX指数计算的逻辑。

1.3 DirMovement函数代码

inputs:

       PriceValueH( numericseries ),//最高价

       PriceValueL( numericseries ), //最低价

       PriceValueC( numericseries ), //收盘价

       Len( numericsimple ),            //Len根bar

       oDMIPlus( numericref ),         //代指+DI

       oDMIMinus( numericref ),       //代指-DI

       oDMI( numericref ),            //代指DX

       oADX( numericref ),            //代指ADX

       oADXR( numericref ),           //代指ADXR

       oVolty( numericref ) ;        //代指Volatility

{这里,类似于oDMIPlus前面有o的参数,后面的括号中都是使用numericref,这个是使用在函数的参数声明语句中,定义为传址数值,它使函数可以输出多个结果,并且传递给调用该函数的脚本;powerlanguage中这种类型的参数还有numericarrayref、stringarrayref、stringref、truefalsearrayref、truefalseref}

variables:

       var0( 0 ),    //计算每根bar的正向波动值

       var1( 0 ),    //计算每根bar的负向波动值

       var2( 0 ),   

       var3( 0 ),   

       var4( 0 ),   //计算len根bar的累计正向波动值

       var5( 0 ),   //计算len根bar的累计负向波动值

       var6( 0 ),   //计算len根bar的累计真实波动幅度

       var7( 0 ),   //正向波动值的加权移动平均

       var8( 0 ),   //负向波动值的加权移动平均

       var9( 1 / Len ),     //计算中使用的加权移动平均的权重为1/len和1-1/len                

       var10( 0 ) ;    //正向指数与负向指数之和

if CurrentBar = 1 then

       begin

       for Value1 = 0 to Len - 1

              begin

              var0 = 0 ;

              var1 = 0 ;

              var2 = PriceValueH[Value1] - PriceValueH[ Value1 + 1 ] ;

              var3 = PriceValueL[ Value1 + 1 ] - PriceValueL[Value1] ;

              condition1 = var2 > var3 and var2 > 0 ;

              if condition1 then

                     var0 = var2

{当condition1条件成立的时候,当根bar为正向波动,波动值赋给var0,var1取默认值0}

              else

              begin

              condition1 = var3 > var2 and var3 > 0 ;

              if condition1 then

                     var1 = var3 ;

{condition1被重新赋值之后,如果条件满足,当根bar为负向波动,波动值赋给var1,var0取默认值0}

                     end;   

{到这里,for循环内部最大的if判断结束,下面是for循环内部其它语句}

              var4 = var4 + var0 ;   //累加正向波动值,总共计算len次

              var5 = var5 + var1 ;   //累加负向波动值,总共计算len次

              var6 = var6 + TrueRangeCustom( PriceValueH, PriceValueL, PriceValueC )[Value1] ;  

{累加真实波动幅度,总共计算len次,第len次之后,循环结束}

              end ;

       var7 = var4 / Len ;  

{正向波动值的平均值,第一次平均是通过简单平均计算的,之后是通过加权移动平均计算的}

       var8 = var5 / Len ;  //负向波动值的平均值

       oVolty = var6 / Len ; //真实波动幅度的平均值

       end

else   

{上面是判断当currentbar=1成立时,使用简单平均去计算平均正向波动值、平均负向波动值和平均真实波动幅度,之后else部分(即,currentbar>1时)使用加权移动平均去计算平均正向波动值、平均负向波动值和平均真实波动幅度}

       begin

       var0 = 0 ;

       var1 = 0 ;

       var2 = PriceValueH - PriceValueH[1] ;

       var3 = PriceValueL[1] - PriceValueL ;

       condition1 = var2 > var3 and var2 > 0 ;

       if condition1 then

              var0 = var2

       else

       begin

       condition1 = var3 > var2 and var3 > 0 ;

       if condition1 then

              var1 = var3 ;

              end;

       var7 = var7[1] + var9 * ( var0 - var7[1] ) ;

{即,var7=(1-1/len)*var7[1]+1/len*var0,权重分别为1-1/len和1/len}

       var8 = var8[1] + var9 * ( var1 - var8[1] ) ;

       oVolty = oVolty[1] + var9 * ( TrueRangeCustom( PriceValueH, PriceValueL, PriceValueC )

        - oVolty[1] ) ;

       end ;

if oVolty > 0 then

       begin

       oDMIPlus = 100 * var7 / oVolty ;

       oDMIMinus = 100 * var8 / oVolty ;

{平均正向波动值与平均真实波动幅度的比值得到+DI,之所以乘以100,是为了使DI的值落在区间[0,100]内;平均负向波动值与平均真实波动幅度的比值得到-DI。}

       end

else

       begin

       oDMIPlus = 0 ;

       oDMIMinus = 0 ;

{这里当oVolty=0成立时,因为是分母为0没有意义,会导致编译出现错误,为了避免这种情况,需要在代码中进行判断,此时需要将+DI和-DI分别赋值为0}

       end ;

var10 = oDMIPlus + oDMIMinus ;

if var10 > 0 then //在代码的编写时,所有的变量做分母时都需要判断一下

       oDMI = 100 * AbsValue( oDMIPlus - oDMIMinus ) / var10

{计算得到DX值}

else

       oDMI = 0 ;  

condition1 = CurrentBar <= Len and CurrentBar > 0 ;

{从这里之后的部分,需要计算ADX和ADXR,ADX是DX的平均计算,而DX的计算已经是基于len根bar的平均计算,所以ADX的计算是二次平均计算,是基于2*len根bar的平均计算}

if condition1 then

       begin

       oADX = Cum( oDMI ) / CurrentBar ;

       oADXR = ( oADX + oADX[ CurrentBar - 1 ] ) * .5 ;   

{这里,由于currentbar<=len,即bar的数目不够,所以需要进行一次特殊的平均计算,计算ADX使用的分母是currentbar;同样,ADXR的计算也进行了特殊的计算}                                                              

       end

else

       begin

       oADX = oADX[1] + var9 * ( oDMI - oADX[1] ) ;

       oADXR = ( oADX + oADX[ Len - 1 ] ) * .5 ;

{对ADX进行加权移动平均计算,权重分别为1-1/len和1/len;ADXR的计算见代码}

       end ;

DirMovement = 1 ;  //这个函数的返回值没有意义,关键是传址参数的使用

1.4 DirMovement系列函数使用说明

DirMovement函数代码在上面已经介绍过了,这个函数的返回值没有意义,关键是传址参数的使用。

DMI函数内部调用了DirMovement,DMI函数的返回值就是DX指数的值;DMI(len)的参数是需要计算的bar的数目len,然后返回DX指数的值。

DMICustom函数的功能及内部的代码逻辑和DMI函数一样,不同的是多了三个价格参数,DMICustom(high,low,close,len)的参数分别是最高价、最低价、收盘价和bar的数目len,返回DX指数的值。

DMIMinus函数内部调用了DirMovement,它的返回值就是-DI指数的值;DMIMinus(len)的参数是需要计算的bar的数目len,然后返回-DI指数的值。

DMIMinusCustom函数的功能及内部的代码逻辑和DMIMinus函数完全一样,不同的是多了三个价格参数,DMIMinusCustom(high,low,close,len)的参数分别是最高价、最低价、收盘价和bar的数目len,返回-DI指数的值。

ADX函数调用了DirMovement函数;ADX(len)的参数是需要计算的bar的数目len,然后返回ADX指数的值。

ADXCustom函数的功能及内部代码逻辑和ADX函数完全一样,不同的是多了三个价格参数;ADXCustom(high,low,close,len)的参数分别是最高价、最低价、收盘价和bar的数目len,返回ADX指数的值。

ADXClassic函数功能及计算逻辑和ADX函数是一样,参数也是一样的,不同的是代码的编写不一样;ADXClassic函数调用了DMI函数来计算DX指数,然后再对DX指数使用加权移动平均来计算ADX指数的值,最后再使用intportion关键字对ADX指数取整;ADXClassic(len)的参数是需要计算的bar的数目len,然后返回ADX指数的取整值(即将小数点之后的值去除)。

ADXCustomClassic函数是ADXClassic和ADXCustom的结合,即使用了三个价格参数,然后在内部调用了DMI函数来计算DX指数,然后再对DX指数使用加权移动平均来计算ADX指数的值,最后再使用关键字intportion对ADX指数取整数值;ADXCustomClassic(high,low,close,len)的参数是最高价、最低价、收盘价和需要计算的bar的数目len。

ADXR函数调用了DirMovement函数;ADXR(len)的参数是需要计算的bar的数目len,然后返回ADXR指数的值。

ADXRCustom、ADXRClassic、ADXRCustomClassic函数的计算、使用及相互区别可以参考ADX。

XAverageOrig是加权移动平均函数;XAverageOrig(pricevalue,len)的参数分别是价格值和需要计算的bar的数目len,权重分别为1-1/len和1/len,函数返回pricevalue的加权平均值,即XAverageOrig=(1-1/len)*XAverageOrig[1]+1/len*pricevalue。

TrueHigh函数返回当根bar的最高价与前一根bar的收盘价的最高值,这个函数没有参数。

TrueLow函数返回当根bar的最低价与前一根bar的收盘价的最低值,这个函数没有参数。

TrueRange函数返回当根bar的真实波动幅度,TrueRange=TrueHigh-TrueLow,这个函数没有参数。

TrueRangeCustom函数的逻辑和TrueRange的计算逻辑是一样的,不同的是它有三个价格参数;TrueRangeCustom(high,low,close)的参数是当根bar的最高价、最低价和收盘价,返回当根bar的真实波动幅度。

Volatility的值等于XAverageOrig(TrueRange,len),这个函数的内部调用函数XAverageOrig对真实波动幅度进行加权移动平均计算;Volatility(len)的参数是需要计算的bar的数目len,返回平均真实波动幅度。

XAverage是指数移动平均函数,它是一种特殊的加权平均函数;XAverage(pricevalue,len)的参数分别是价格值和需要计算的bar的数目,返回pricevalue的指数移动平均值,即XAverage=(len-1)/(len+1)*XAverage[1]+2/(len+1)*pricevalue。

AvgTrueRange函数调用Average函数计算平均真实波动幅度,即先累加真实波动幅度,然后再除以数目;AvgTrueRange(len)的参数是需要计算的bar的数目,返回平均真实波动幅度值。


论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
 
期货论坛 - 版权/免责声明   1.本站发布源码(包括函数、指标、策略等)均属开放源码,用意在于让使用者学习程序化语法撰写,使用者可以任意修改语法內容并调整参数。仅限用于个人学习使用,请勿转载、滥用,严禁私自连接实盘账户交易
  2.本站发布资讯(包括文章、视频、历史记录、教材、评论、资讯、交易方案等)均系转载自网络主流媒体,内容仅为作者当日个人观点,本网转载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网不对该类信息或数据做任何保证。不对您构成任何投资建议,不能依靠信息而取代自身独立判断,不对因使用本篇文章所诉信息或观点等导致的损失承担任何责任。
  3.本站发布资源(包括书籍、杂志、文档、软件等)均从互联网搜索而来,仅供个人免费交流学习,不可用作商业用途,本站不对显示的内容承担任何责任。请在下载后24小时内删除。如果喜欢,请购买正版,谢谢合作!
  4.龙听期货论坛原创文章属本网版权作品,转载须注明来源“龙听期货论坛”,违者本网将保留追究其相关法律责任的权力。本论坛除发布原创文章外,亦致力于优秀财经文章的交流分享,部分文章推送时若未能及时与原作者取得联系并涉及版权问题时,请及时联系删除。联系方式:http://www.qhlt.cn/thread-262-1-1.html
如何访问权限为100/255贴子:/thread-37840-1-1.html;注册后仍无法回复:/thread-23-1-1.html;微信/QQ群:/thread-262-1-1.html;网盘链接失效解决办法:/thread-93307-1-1.html

返回列表