交易危机

 找回密码
 快捷注册(禁q号)

QQ登录

只需一步,快速开始

搜索
广告位
查看: 1742|回复: 1

[代码] 布林线指标详解(一)

[复制链接]

2127

主题

6万

积分

157

精华

大型投行

金钱
61244 美元
权重
640
发表于 2018-8-1 22:23 | 显示全部楼层 |阅读模式
mayshu1977 发表于 2017-8-18 10:15
对了,BOLL线的上下轨计算公式知道么?怎么算的


小明拼了
翻家底

当年理解布林的时候,笔记
共2篇

//+------------------------------------------------------------------+
//|                                                        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=10000,子循环会一直计算到k=9981。当k=9980时就不计算了。
      i=9981时,大循环运行9982次
      在这9982次里,i在一次一次减少(大循环)
      当第一次进入大循环,i=9981,k=10000,则子循环运行20次
      当第二次进入大循环,i=9980,k=9999,则子循环运行20次
      以此类推,小循环在i的每个值时,都运行20遍
      */
      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,就是两倍的均方差
      
      /*
         布林上下线的公式
         TL = ML + (D*StdDev)
         BL = ML — (D*StdDev)
         D就是BandsDeviations
         StdDev就是上面注释中的S
      */
      
      deviation=BandsDeviations*MathSqrt(sum/BandsPeriod);
      UpperBuffer=oldval+deviation;
      LowerBuffer=oldval-deviation;
      i--;
   }
//----
   return(0);
}
//+------------------------------------------------------------------+
来源: 布林线指标详解(一)

4

主题

9227

积分

0

精华

所有交易让市场验证

操盘专家

金钱
9227 美元
权重
8
发表于 2019-1-19 21:49 来自手机 | 显示全部楼层
消灭零回复
您需要登录后才可以回帖 登录 | 快捷注册(禁q号)

本版积分规则

QQ|黄金吧|黄金论坛|手机版|指标下载|非农|目录|交易危机

版权所有: ©2014-2021 fx3q.com Powered by Discuz! X3
浙ICP备: ICP14039028

浙公网安备 33011802001420号

风险提示:杠杆风险高,交易要谨慎 声明:坛友发言和回复均为个人观点,不代表论坛立场。
若有侵权请联系fx3q@qq.com删除

快速回复 返回顶部 返回列表