MQL4,一個bias策略測試時出現問題

 
#property copyright ""
#property link      ""
#property strict
//-----------------------------
extern int MAK3 = 233;    //趨勢線根數參數
extern double Lot = 0.1; //手數
//---------BiasControlTable----------
extern double BIAS = 0.1; //(1.0%=1.0)大於多少BIAS才進單
extern double BIASV = 1.0; //(110%=1.1)大於前幾根BIAS百分比才進
extern int BiasK =1; //(3=3根)大於前幾根平均BIAS才進
extern int MABi1 =30; //BIAS參數
//----------BaseCT---------
extern int AccMony = 10000; //本金倉位(會影響總獲利%)
extern double TotalSL = 20; //止損百分比%
extern int Magic=20210806;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime lastT;
double B1,S1,HighS,LowB,Bx,Bs;
int B,S;
bool BBTP,SSTP;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(lastT == Time[1])
      return;
   lastT = Time[1];
   double MAC1 = iMA(NULL,0,MAK3,0,MODE_SMA,PRICE_CLOSE,1);
   BaisBlance(Bs,1);
   BaisBlance(Bx,BiasK);

   if(Bs>BIAS && Bs>=Bx/BiasK*BIASV)
     {
      if(Close[1]>MAC1)
        {
         BUY();
        }
      if(Close[1]<MAC1)
        {
         SELL();
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
void SELL()
  {
   OrderSend(NULL,OP_SELL,Lot,Bid,3,0,0,NULL,Magic,Magic,clrRed);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void BUY()
  {
   OrderSend(NULL,OP_BUY,Lot,Ask,3,0,0,NULL,Magic,Magic,clrBlue);
  }
//+------------------------------------------------------------------+
// BUY單平倉
void closeBuyall()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         if(OrderType()==0 && OrderMagicNumber()==Magic)   //BUY單:0 或S ELL單:1
           {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),clrGreen);
           }
         else(OrderDelete(OrderTicket(),clrGreen));
        }
     }
  }
//+------------------------------------------------------------------+
// Sell單平倉
void closeSellall()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
        {
         if(OrderType()==1 && OrderMagicNumber()==Magic)   //BUY單:0 或S ELL單:1
           {
            OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),clrGreen);
           }
         else(OrderDelete(OrderTicket(),clrGreen));
        }
     }
  }
//-------------------------------------------
void BaisBlance(double &bi,int Biask)
  {
   bi=0;
   for(int i=0; i<Biask; i++)
      bi = bi + 100*(MathAbs(Close[i+1]-iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1))/iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1));
   return;
  }
//+------------------------------------------------------------------+

當我的BIAS參數大於101,就無法使用EVERYTICK回測EA。程式碼有哪裡出了問題嗎?
附加的文件:
01.png  118 kb
02.mq4  8 kb
 
X庭X XX:

當我的BIAS參數大於101,就無法使用EVERYTICK回測EA。程式碼有哪裡出了問題嗎?
 bi = bi + 100*(MathAbs(Close[i+1]-iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1))/iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1));

大概率是测试数据不足101柱造成MA为0了。程序中应在上述代码段计算MA之前作一个0判断。

 
Lin Luo:

大概率是测试数据不足101柱造成MA为0了。程序中应在上述代码段计算MA之前作一个0判断。

感謝您的回覆,言下之意,1.EA實際測試正常運作(因為以往的數據遠超過101柱)。2.測試EA需增加計算MA之前作一個0判斷(因為數據超過101柱,分母為0數學邏輯錯誤)。
但是,這計算MA之前作一個0判斷...iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1)本身是一段計算程式,我不明白如何做0判斷,是否能直接修改呢?

以下為更新,感謝你的建議
void BaisBlance(double &bi,int Biask)
  {
   bi=0;
   for(int i=0; i<Biask; i++)
     {
      if(iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1) != 0)
        {
         bi = bi + 100*(MathAbs(Close[i+1]-iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1))/iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1));
        }
     }
   return;
  }
 
Lin Luo:

大概率是测试数据不足101柱造成MA为0了。程序中应在上述代码段计算MA之前作一个0判断。

正解。

很多新手只会调用指标,没有搞清楚SMA的算法。

 

判断一个数一个是否为0都不会?那就变通一下,检查K线的个数满足条件:

void OnTick()
  {
   if(lastT == Time[1]) return;
   if(iBars(NULL,0)<=MAK3 || iBars(NULL,0)<=MABi1)return;
   //...your code 
   
   }
 
Ziheng Zhuang:

判断一个数一个是否为0都不会?那就变通一下,检查K线的个数满足条件:

感謝你,讓新手學習不一樣的寫法~~
 
庭WAN XI:
void BaisBlance(double &bi,int Biask)
  {
   bi=0;
   for(int i=0; i<Biask; i++)
     {
      if(iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1) != 0)
        {
         bi = bi + 100*(MathAbs(Close[i+1]-iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1))/iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1));
        }
     }
   return;
  }

理论上没问题了。但调用同一个MA算法,程序重算了三次,似乎有些浪费计算机资源。如果改为以下示例,仅算一次,个人觉得稍高效些。(结果意味着柱数不足MABi1时,有几柱,程序就算了几柱的bi)

void BaisBlance(double &bi,int Biask)
  {
   bi=0;
   double tempma=0;
   for(int i=0; i<Biask; i++)
     {
      tempma=iMA(NULL,0,MABi1,0,MODE_SMA,PRICE_CLOSE,i+1);
      if(tempma!= 0)
        bi+=100*(MathAbs(Close[i+1]-tempma)/tempma);
      else break;
     }
   return;
  }
 
Lin Luo:

理论上没问题了。但调用同一个MA算法,程序重算了三次,似乎有些浪费计算机资源。如果改为以下示例,仅算一次,个人觉得稍高效些。(结果意味着柱数不足MABi1时,有几柱,程序就算了几柱的bi)

感謝大神,收穫良多。