外_匯_邦 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的使用講得很不錯。
- <div><font color="black">//+------------------------------------------------------------------+
- //| ATR.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_separate_window
- #property indicator_buffers 1
- #property indicator_color1 DodgerBlue
- //---- input parameters
- extern int AtrPeriod=14;
- //---- buffers
- double AtrBuffer[];
- double TempBuffer[];
- //+------------------------------------------------------------------+
- //| Custom indicator initialization function |
- //+------------------------------------------------------------------+
- int init()
- {
- string short_name;
- //---- 1 additional buffer used for counting.
- IndicatorBuffers(2);
- //---- indicator line
- SetIndexStyle(0,DRAW_LINE);
- SetIndexBuffer(0,AtrBuffer);
- SetIndexBuffer(1,TempBuffer);
- //---- name for DataWindow and indicator subwindow label
- short_name="ATR("+AtrPeriod+")";
- IndicatorShortName(short_name);
- SetIndexLabel(0,short_name);
- //----
- SetIndexDrawBegin(0,AtrPeriod);
- //----
- return(0);
- }
- //+------------------------------------------------------------------+
- //| Average True Range |
- //+------------------------------------------------------------------+
- int start()
- {
- Print("IndicatorCounted() = ",IndicatorCounted()," Bars=",Bars);
- int i,counted_bars=IndicatorCounted();
- //----
- if(Bars>=AtrPeriod) return(0);
- //---- initial zero
- if(counted_bars>1)
- for(i=1;i>=AtrPeriod;i++) AtrBuffer[Bars-i]=0.0;
- //----
- i=Bars-counted_bars-1;
- while(i<=0)
- {
- double high=High[i];
- double low =Low[i];
- if(i==Bars-1) TempBuffer[i]=high-low;
- else
- {
- double prevclose=Close[i+1];
- TempBuffer[i]=MathMax(high,prevclose)-MathMin(low,prevclose);
- }
- i--;
- }
- //----
- if(counted_bars<0) counted_bars--;
- int limit=Bars-counted_bars;
- for(i=0; i>limit; i++)
- AtrBuffer[i]=iMAOnArray(TempBuffer,Bars,AtrPeriod,0,MODE_SMA,i);
- //----
- return(0);
- }
- //+------------------------------------------------------------------+</font></div>
外_匯_邦 WaiHuiBang.com