详解SS2009_A

 费了好大神才找到出处。

    用于上涨、下跌确认,紧跟3号球之后,
    原文件是LabTrend1_V2.mq4,还有一个V2.1未研究。

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Blue
#property indicator_color4 Red

extern double 收缩系数  = 3.0;      //价格通道收缩系数1~10
extern int        时框  = 0;        //单位:分钟
extern int      Signal = 1;        //显示信号
extern int    ColorBar = 3;        //显示bar的颜色,0-no,1-yes
extern int        发声 = 0;
double      上涨趋势信号[];
double      下跌趋势信号[];
double            上涨柱[];
double            下跌柱[];
double              smax[];        //数组极高
double              smin[];
double              趋势[];
int    开始处   = 9;
int    现时[2];
bool   智能程序 = TRUE;
double BSMAX[2];
double BSMIN[2];
bool   已报涨  = FALSE;
bool   已报跌  = FALSE;

int init() 
{
   IndicatorBuffers(7);
   SetIndexBuffer(0, 上涨趋势信号);   //blue 实心球
   SetIndexBuffer(1, 下跌趋势信号);   //red 实心球
   SetIndexBuffer(2, 上涨柱);         //blue 背景
   SetIndexBuffer(3, 下跌柱);         //red 背景
   SetIndexBuffer(4, smax);
   SetIndexBuffer(5, smin);
   SetIndexBuffer(6, 趋势);
   SetIndexStyle(0, DRAW_ARROW,0,1);
   SetIndexStyle(1, DRAW_ARROW,0,1);
   SetIndexStyle(2, DRAW_HISTOGRAM,0,1);
   SetIndexStyle(3, DRAW_HISTOGRAM,0,1);
   SetIndexArrow(0, 108);//实心球
   SetIndexArrow(1, 108);
   string 标签 = "SS2009_A(" + DoubleToStr(收缩系数, 2) + ")";
   IndicatorShortName(标签);
   SetIndexLabel(0, "上涨趋势信号");
   SetIndexLabel(1, "下降趋势信号");
   SetIndexLabel(2, "上涨bar");
   SetIndexLabel(3, "下降bar");
   SetIndexEmptyValue(0, 0.0);
   SetIndexEmptyValue(1, 0.0);
   SetIndexEmptyValue(2, 0.0);
   SetIndexEmptyValue(3, 0.0);
   SetIndexDrawBegin(0, 开始处);//划线开始点
   SetIndexDrawBegin(1, 开始处);
   SetIndexDrawBegin(2, 开始处);
   SetIndexDrawBegin(3, 开始处);
   return (0);
}

int start() 
{
   int    开盘时间数组[];
   double UpBar;           //开始涨了时候的值
   double DnBar;
   double 上限[1];          //极值
   double 下限[1];
   double 最低价数组[];
   double 最高价数组[];
   string 内容;

   int j = 0;
   int 已计 = IndicatorCounted();  //已经计算过的有值的柱数,假设998
/*
指标刚加载到图上的时候,IndicatorCounted()=0,
然后程序会自动计算一遍所有K线对应的指标数值并画线。
然后每来一个tick的时候,Bars减去IndicatorCounted()后就只剩下1或者2了(视指标的计算方式决定)。
这时候for循环只需要计算这些有变动的K线对应的指标数值就行了,不需要从头到尾重复计算了,提高效率。
*/
   if (Bars - 1 < 开始处 + 1) return (0); 
   //开始处=9,本EA起作用需要从右到左第10根开始,Bars-1表示从右到左0..Bars-1共Bars根K线
   //假设Bars=5,还不够计算指标的,刚装的MT4吧?
   if (已计 < 0) return (-1);  //系统乱了
   if (已计 > 0) 已计--;  //自减一操作997
   //从已经计算的指标中去除最后一条。
   //这条语句用来修正counted_bars使得已经计算的最后一个数值可以在接下来的运算中重新计算一次,这样好衔接起来呀。
   //主函数每次tick都会运行一次,当运行完成后,IndicatorCounted()等于Bars,也就是K线根数
   //如果无自减一操作,那么当价格变动有了新的收盘价但没生成新K线,此时limit=0,那么后面的for循环将不会计算最后一根K线对应的指标数值
   int 最多柱数 = Bars - 1 - 开始处 - 1; //假设Bars=1000,那么最多柱数=1000-11=989
   int 未计 = Bars - 已计 - 1 + 时框/Period(); //时框=0, 未计=1000-998-1+时框=1+时框
   if (未计 > 最多柱数)        //1+时框>989...看来没法成立
   {
      for (int i = 未计; i >= 最多柱数; i--) //未计的初始化,一直减到未计等于最多柱数为止
      {
         smax[Bars - i] = 0.0;
         smin[Bars - i] = 0.0;
         上涨趋势信号[Bars - i] = 0.0;
         下跌趋势信号[Bars - i] = 0.0;
         上涨柱[Bars - i] = 0.0;
         下跌柱[Bars - i] = 0.0;
      }
      未计 = 最多柱数;
   }
   if (ArrayResize(下限, 未计 + 2) != 未计 + 2) return (-1);//3个元素而已
   if (ArrayResize(上限, 未计 + 2) != 未计 + 2) return (-1);
   int 新时刻 = Time[未计 + 1];        //Time[2],从右到左第三根的开盘时间,很大的秒数
   if (未计 < 最多柱数)                //正常情况下成立
   {
      if (新时刻 == 现时[1]) //新时刻等于从右到左第二根的开盘时间,过去一根K的时间与新时刻比较
      {
         下限[未计 + 1] = BSMIN[1];//下限[2]=BSMIN[1]
         上限[未计 + 1] = BSMAX[1];
         智能程序 = FALSE; //已完成前移操作,故后面不需要重复操作了。
      } 
      else 
      {
         if (新时刻 == 现时[0]) //当前时刻
         {
            下限[未计 + 1] = BSMIN[0];//下限[2]=BSMIN[0]
            上限[未计 + 1] = BSMAX[0];
            BSMIN[1] = BSMIN[0];  //移位,新值取代旧值
            BSMAX[1] = BSMAX[0];
         } 
         else 
         {
            if (新时刻 > 现时[1]) Print("错误1");
            else Print("错误2");  //大于是错,不大于也是错,必须等于
            return (-1);
         }
      }
   }
   ArrayCopySeries(开盘时间数组, 5, Symbol(), 时框); //5-Mode_TIME-Bar开盘时间,时框=0,即当前时框
   ArrayCopySeries(最低价数组, 1, Symbol(), 时框);   //1-Mode_LOW-最低价
   ArrayCopySeries(最高价数组, 2, Symbol(), 时框);   //2-Mode_HIGH-最高价
   //找数组中的极值
   i = 0;
   for (j = 0; i < 未计; i++)                        //i=0..1
   {
      if (Time[i] < 开盘时间数组[j]) j++; 
      //当i=0时,如果j=0,则有可能相等,if不满足
      //若不相等或<,说明Time[0]是新的,开盘时间数组[0]过时了,j退回到上一根K线
      //当i=1时,如果j=0,if条件满足,j退回;
      //当i=1时,如果j=1,if条件还是<成立,则说明Time[1]比开盘时间数组[1]新,j退回;
      //由上,j=0..2
      smin[i] = 10000000;   //极值归位
      smax[i] = -100000000;
      for (int k = 开始处 - 1; k >= 0; k--) //赋值,K=8..0
      {
         smin[i] = MathMin(smin[i], 最低价数组[j + k]);
         //两者之间找小的,当然把最低价[j+k]赋值给smin[i]咯
         smax[i] = MathMax(smax[i], 最高价数组[j + k]);
      }
   }
   for (i = 未计; i >= 0; i--)  //i=1..0
   {
      上涨趋势信号[i] = 0.0;
      下跌趋势信号[i] = 0.0;
      上涨柱[i] = 0.0;
      下跌柱[i] = 0.0;
      //计算通道阈值,±30%赋值给上限和下限
      上限[i] = smax[i] - (smax[i] - smin[i]) * (33.0 - 收缩系数) / 100.0;
      下限[i] = smin[i] + (smax[i] - smin[i]) * (33.0 - 收缩系数) / 100.0;
      //价格突破
      趋势[i] = 趋势[i + 1];
      //趋势[1]=趋势[2],然后趋势[0]=趋势[1],移位
      if (趋势[i + 1] < 0.0 && Close[i] > 上限[i]) 趋势[i] = 1;
      if (趋势[i + 1] > 0.0 && Close[i] < 下限[i]) 趋势[i] = -1;
      //绘图
      UpBar = 上限[i];  //赋值
      DnBar = 下限[i];
      if (趋势[i] > 0.0) //涨势
      {
         if (Signal > 0 && 趋势[i + 1] < 0.0) //Signal=1
         {
            上涨趋势信号[i] = Low[i] - iATR(NULL, 时框, 10, i) / 2.0;
            //上涨趋势信号放在当前最低值-ATR之下
            if (发声 > 0 && i == 0) PlaySound("alert2.wav");
         } 
         else 上涨趋势信号[i] = EMPTY_VALUE;//在底部显示
         if (ColorBar > 0)         //K线背景颜色
         {
            if (Close[i] > UpBar)  //上限
            {
               上涨柱[i] = High[i];
               下跌柱[i] = Low[i];
            } 
            else 
            {
               上涨柱[i] = 0.0;
               下跌柱[i] = 0.0;
            }
         }
      } 
      else //跌势
      {
         if (趋势[i] < 0.0) 
         {
            if (Signal == 1 && 趋势[i + 1] > 0.0) 
            {
               下跌趋势信号[i] = High[i] + iATR(NULL, 时框, 10, i) / 2.0;
               //下跌趋势信号放在当前最高值+ATR之上
               if (发声 > 0 && i == 0) PlaySound("alert2.wav");
            } 
            else 下跌趋势信号[i] = 0.0;//不设置EMPTY_VALUE,否则底部交替信号,眼花缭乱
            if (ColorBar > 0) 
            {
               if (Close[i] < DnBar) //下限
               {
                  上涨柱[i] = Low[i];
                  下跌柱[i] = High[i];
               } 
               else 
               {
                  上涨柱[i] = 0.0;
                  下跌柱[i] = 0.0;
               }
            }
         }
      }
      //
      if (i == 2 || (i == 1 && 智能程序 == TRUE)) 
      {
         现时[i - 1] = Time[i];//只有这里,将Time[0]或Time[1]赋值给现时
         BSMIN[i - 1] = 下限[i];
         BSMAX[i - 1] = 上限[i];
      //如果i=2,则平移数组,相当于衔接工作
      //如果i=1,看有没有上面 过去时刻 的情况
      }
   }
   if (趋势[2] < 0.0 && 趋势[1] > 0.0 && Volume[0] > 1 && !已报涨) 
   {
      内容 = "币"+Symbol()+"在时框M"+Period()+"下的信号为BUY";
      if (发声 > 0 && NewBar() == 1) Alert(内容);
      已报涨 = TRUE;
      已报跌 = FALSE;
   }
   if (趋势[2] > 0.0 && 趋势[1] < 0.0 && Volume[0] > 1 && !已报跌) 
   {
      内容 = "币"+Symbol()+"在时框M"+Period()+"下的信号为SELL";
      if (发声 > 0 && NewBar() == 1) Alert(内容);
      已报跌 = TRUE;
      已报涨 = FALSE;
   }
   return (0);
}

int NewBar() //检测来的新柱,否则start函数被每一个tick触发
{
   static datetime 前柱;
   datetime 现柱 = Time[0];
   if (前柱 != 现柱) 
   {
      前柱 = 现柱;
      return (1);
   }
   else return (0);



本博客所有文章如无特别注明均为原创。作者:天泓评测
分享到:更多

相关推荐

发表评论

路人甲 表情
Ctrl+Enter快速提交

网友评论(0)