|
//+------------------------------------------------------------------+ //| Bands.mq4 | //| Copyright ?2005, metaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property copyright "Copyright ?2005, metaQuotes Software Corp." #property link "http://www.metaquotes.net/" #property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 LightSeaGreen #property indicator_color2 LightSeaGreen #property indicator_color3 LightSeaGreen //---- indicator parameters extern int BandsPeriod=20; extern int BandsShift=0; extern double BandsDeviations=2.0; //---- buffers double MovingBuffer[]; double UpperBuffer[]; double LowerBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,MovingBuffer); SetIndexStyle(1,DRAW_LINE); SetIndexBuffer(1,UpperBuffer); SetIndexStyle(2,DRAW_LINE); SetIndexBuffer(2,LowerBuffer); //---- SetIndexDrawBegin(0,BandsPeriod+BandsShift); SetIndexDrawBegin(1,BandsPeriod+BandsShift); SetIndexDrawBegin(2,BandsPeriod+BandsShift); //---- return(0); } //+------------------------------------------------------------------+ //| Bollinger Bands | //+------------------------------------------------------------------+ int start() { int i,k,counted_bars=IndicatorCounted(); double deviation; double sum,oldval,newres; //---- if(Bars<=BandsPeriod) return(0); //Bars代表图中所有的k的数量,如果图中的k只读出来20或者20以下的个数,不足以计算布林线,则退出程序 //---- initial zero //counted_bars=IndicatorCounted() //IndicatorCounted()代表已经被计算过的bars,即刚运行程序,最初为0,运行过一次,就把几乎所有的bars已经计算过一次了。 //官方的文档说的是:IndicatorCounted()的返回值是那些 从上一次运行指标后一直没有改变的柱的数量。 //IndicatorCounted()得到的值,不包含当前的k,也就是说,假设图中有10000个Bars,指标运行前,IndicatorCounted()=0,指标运行过一次后,经过计算的Bars数量为IndicatorCounted()=9999 //当第一次计算指标时,IndicatorCounted()=0,所以下面的counted_bars=0<1,即当程序第一次运行时,执行清零任务 if(counted_bars<1) for(i=1;i<=BandsPeriod;i++) { //BandsPeriod=20,那么Bars-i在i=1到20的过程中,假设有10000个K,则Bars-i=9999到9980,9999为最久远的一个k的索引(索引从0开始) //最久远的20个K因为数据不够20个K,无法计算出指标值,所以给他们清零 MovingBuffer[Bars-i]=EMPTY_VALUE; UpperBuffer[Bars-i]=EMPTY_VALUE; LowerBuffer[Bars-i]=EMPTY_VALUE; } //---- int limit=Bars-counted_bars; //未经计算的柱数量,一般指标只要运行了一下,这个值总是等于1 if(counted_bars>0) limit++; //counted_bars>0,代表指标已经运行过了,即不是最开始加载指标的首次运行了。limit++使limit经过这一步运算,总是等于2 for(i=0; i<limit; i++) MovingBuffer=iMA(NULL,0,BandsPeriod,BandsShift,MODE_SMA,PRICE_CLOSE,i); //上面的limit=2,这样第一次循环,i=0,第二次循环i=1,第三次i=2不满足2<2了,就不执行了,循环只进行两次,计算了MovingBuffer[0]和MovingBuffer[1] //为什么需要添加"if(counted_bars>0) limit++;"这么一行,导致计算了MovingBuffer[0]和MovingBuffer[1],而不是只计算MovingBuffer[0]?? 理由暂时不明。。。 //---- i=Bars-BandsPeriod+1; //假设10000个Bars,则i=9980+1=9981 //下面:依然假设Bars有10000个,在第一次运行程序的时候counted_bars=0,if不成立,本行不执行,i保留上一行的值9981,下面的循环可以运行9982次 if(counted_bars>BandsPeriod-1) i=Bars-counted_bars-1; //只要不是刚加载指标运行,if都会成立,则i的值永恒为0,下面的循环,也只会运行1次。 //上面一行为何不是counted_bars>BandsPeriod-1而不是counted_bars>BandsPeriod,也不是counted_bars>BandsPeriod+1?? 还没搞明白。。。 while(i>=0)//第一次运行的时候,假设有10000个Bars(索引从9999->0),i=9981,则指标在下面会填充UpperBuffer[9981]-->UpperBuffer[0]这些索引的值,留下9999-9982这些索引的18个k无法填充。为啥不是19或者20?没想明白呢。。不影响使用 { sum=0.0; k=i+BandsPeriod-1; //假设程序第一次运行的时候,正在进行第一次循环,i=9981,k=9981+20-1=10000,第二次大循环运行时,i=9980,则k=9999 oldval=MovingBuffer; while(k>=i) { newres=Close[k]-oldval; //在20个范围内,每个k偏离均线的距离 sum+=newres*newres; //这两行配合下面的一句话就是布林的公式了 k--; } //均方差公式在布林的意义不太确定,经查阅均方差的意义,好像是。。。假设布林参数为1.0,会有一些"有点异常"的价格排除在布林之外, //假设参数为2.0,则会把一些"特别异常"的价格排除在外) //自己的理解是,假设在当前K,Close[0]这个位置,则当前中轨到上轨或下轨的距离是:20个K平均偏移均线的程度---至此终于看懂"能看懂的布林代码"啥意思了。是把均方差替换成平均值了 //S = ((x1-x的平均值)^2 + (x2-x的平均值)^2+(x3-x的平均值)^2+...+(xn-x的平均值)^2)/n)的平方根 //得到S后,再*BandsDeviations就是deviation了。默认BandsDeviations=2.0,就是两倍的均方差 deviation=BandsDeviations*MathSqrt(sum/BandsPeriod); UpperBuffer=oldval+deviation; LowerBuffer=oldval-deviation; i--; } //---- return(0); } //+------------------------------------------------------------------+ |
布林线指标详解
回复:0 浏览:210
- 楼主admin 圈主
- 2019-05-05 11:47