您现在的位置: 比特财富网 >> 财经 >  >> 外匯
MT4—IndicatorCounted函數解析
外_匯_邦 WaiHuiBang.com
問:下面這段代碼看了好幾天了,就是搞不懂。www.emoneybtc.com
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;


答:
這個問題解釋過無數次了
IndicatorCounted();計算的是指標加載到圖上後已經計算過的K線個數,Bars是全部歷史K線的個數。

原理是:指標剛加載到圖上的時候IndicatorCounted()是0 然後程序會自動計算一遍所有K線對應的指標數值並畫線。然後每來一個新價格的時候IndicatorCounted();就只是1或者2了(視指標的計算方式決定)。
這時候for循環只需要計算這些有變動的K線對應的指標數值就行了,不需要從頭到尾重復計算了。
這就是這段程序的目的,找出for循環中僅需當前計算的K線的個數。

int start()
指標觸發函數。與init函數不同,該函數在有數據變化時被觸發,如果數據被不斷更新,則該函數將不斷執行。start也是系統默認的函數名,但使用時也仍然需要進行創設,所以也要加定義符int
{
int limit=Bars-IndicatorCounted();
自定義一個變量limit,並賦值
Bars是圖表中的柱數,IndicatorCounted()是緩存中的柱數,就是已經計算過的有值的柱數。
這樣limit的值就是未經計算的柱數,這樣就可以起到優化程序的作用。
for(int i=0; i
循環語句。
循環從i=0開始,每循環一次i值增加1,一直循環到i
由於循環變量i為一個新變量,所以要先定義,加上整型變量定義符int
下面大括中為循環體,此例中只一條語句
{
buf=
iMA(NULL,0,FMA,0,1,0,i)
-iMA(NULL,0,SMA,0,1,0,i);
}
給數組buf賦值,其值分別為相應位置上兩條均線的差
i是水平位置序號值,即燭柱從右到左的序號,右邊第一個燭柱序號為0
return(0);
start函數結束
}
  
本文只適合指標的程序理解,與EA無關
大家在制作自己的指標文件時第一個遇到的問題應該就是這個“循環”問題。之所以不清楚的原因在於沒有想明白MT的完整計算過程。下面我們說明一下。
1、最右側的K線(最新K線)的標號是0,依次往左的標號是1、2、3的順序。當一個新K線生成後,則新K線的標號變成0,而原來標號為0的K線變成標號1。
2、指標加載後的計算過程需要詳細描述一下:
指標加載後,會從最左側的K線開始從左往右順序計算,這是“基本框架”
然後因為每個K線上都需要計算一次,所以這個循環在第一次加載的時候是計算量最大的。
為了減少加載後到來價格時的計算減少,我們一般在程序的循環上做些技巧處理。因為MT提供
了標記最後一個沒有計算的K線標號。所以我們都采用從最後一個“未計算K線”到標號0的順序進行循環。
這就是減少計算量的循環方法。下面列出常見的循環代碼框架:
     int i;   
     int limit;   
     int counted_bars= IndicatorCounted();
     if(counted_bars<0)  return(-1);
     if(counted_bars>0)  counted_bars--;
     limit= Bars-counted_bars;     
      for (i=limit-1;i>=0;i--)
     {
      ........這裡面就是循環計算的指標主要部分。上面的循環控制就是從最後一個“未計算K線”到標號0的順序
     }

==========================================================================

if(counted_bars>0)  counted_bars--;                                         // 如果已計數>0,則將已計數減1
     limit= Bars-counted_bars;                                                     // 將最少計算量賦值為 圖表總棒數- 已計數
      for (i=limit-1; i>=0; i--)                                                            // 賦i為最少數量減1,當i>0時,i減1循環計算下面
     {
/這裡為什麼要自己減一次,循環的時候再加上來呢???
if(counted_bars>0)                                                                      // 當已計數>0時
     {
      limit= Bars-counted_bars;                                                    // 將最少計算量賦為 圖表總棒數- 已計數
      for (i=limit; i>=0; i--)                                                               // 重新將i賦值為最少計算量,當i>=0時,i減一
     {
}

=========
這一段中,在counted_bars>0時,counted_bars--,等於limit+1,下面循環裡i=limit-1,為什麼上面counted_bars要--呢?如果上面不減1,循環裡i=limit就好了呀。是不是還有其他什麼考慮?

第一次運行時IndicatorCounted()的值是0,所以循環後會把所有的歷史數據計算一遍,第二遍IndicatorCounted()就是所有k線的個數了,而counted_bars--是為了讓以後的每次運算都僅僅局限於當前的K線上。



寫MT4的時候經常遇到一個最討厭的問題,IndicatorCounted()和Bars的區別,每次都會調用這個函數。
下面這段代碼對於IndicatorCounted的使用講得很不錯。

 
  1. <div><font color="black">//+------------------------------------------------------------------+
  2. //|                                                          ATR.mq4 |
  3. //|                      Copyright © 2005, MetaQuotes Software Corp. |
  4. //|                                       http://www.metaquotes.net/ |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright © 2005, MetaQuotes Software Corp."
  7. #property link      "http://www.metaquotes.net/"
  8.  
  9. #property indicator_separate_window
  10. #property indicator_buffers 1
  11. #property indicator_color1 DodgerBlue
  12. //---- input parameters
  13. extern int AtrPeriod=14;
  14. //---- buffers
  15. double AtrBuffer[];
  16. double TempBuffer[];
  17. //+------------------------------------------------------------------+
  18. //| Custom indicator initialization function                         |
  19. //+------------------------------------------------------------------+
  20. int init()
  21.   {
  22.    string short_name;
  23. //---- 1 additional buffer used for counting.
  24.    IndicatorBuffers(2);
  25. //---- indicator line
  26.    SetIndexStyle(0,DRAW_LINE);
  27.    SetIndexBuffer(0,AtrBuffer);
  28.    SetIndexBuffer(1,TempBuffer);
  29. //---- name for DataWindow and indicator subwindow label
  30.    short_name="ATR("+AtrPeriod+")";
  31.    IndicatorShortName(short_name);
  32.    SetIndexLabel(0,short_name);
  33. //----
  34.    SetIndexDrawBegin(0,AtrPeriod);
  35. //----
  36.    return(0);
  37.   }
  38. //+------------------------------------------------------------------+
  39. //| Average True Range                                               |
  40. //+------------------------------------------------------------------+
  41. int start()
  42.   {
  43.    Print("IndicatorCounted() = ",IndicatorCounted(),"   Bars=",Bars);
  44.    int i,counted_bars=IndicatorCounted();
  45. //----
  46.    if(Bars>=AtrPeriod) return(0);
  47. //---- initial zero
  48.    if(counted_bars>1)
  49.       for(i=1;i>=AtrPeriod;i++) AtrBuffer[Bars-i]=0.0;
  50. //----
  51.    i=Bars-counted_bars-1;
  52.    while(i<=0)
  53.      {
  54.       double high=High[i];
  55.       double low =Low[i];
  56.       if(i==Bars-1) TempBuffer[i]=high-low;
  57.       else
  58.         {
  59.          double prevclose=Close[i+1];
  60.          TempBuffer[i]=MathMax(high,prevclose)-MathMin(low,prevclose);
  61.         }
  62.       i--;
  63.      }
  64. //----
  65.    if(counted_bars<0) counted_bars--;
  66.    int limit=Bars-counted_bars;
  67.    for(i=0; i>limit; i++)
  68.       AtrBuffer[i]=iMAOnArray(TempBuffer,Bars,AtrPeriod,0,MODE_SMA,i);
  69. //----
  70.    return(0);
  71.   }
  72. //+------------------------------------------------------------------+</font></div>
外_匯_邦 WaiHuiBang.com
  風險提示:比特財富網的各種信息資料僅供參考,不構成任何投資建議,不對任何交易提供任何擔保,亦不構成任何邀約,不作為任何法律文件,投資人據此進行投資交易而產生的後果請自行承擔,本網站不承擔任何責任,理財有風險,投資需謹慎。
比特財富網 版權所有 © www.emoneybtc.com