逐行和逐根
一。序列
要理解什么是逐行和逐根,首先要理解什么是“序列”。
在多数股软里,对于每个品种,K线是分析的基础对象,而很多根K线就组成了所谓的“序列”。 一根K线实际上是由开高低收量额组成的,所以也就有对应的close,open,high,low,vol,amount等五个内置序列。
序列是很特别的一类数据。它跟数组很相像:每个序列都由多个元素组成,可以通过下标访问。
序列跟数组的区别: 数组在声明时已经定义好元素数量,之后不会改变;而序列在声明时并不指明元素数量。它的数量由K线数量决定,随着行情进行,K线不断增加,序列也相应的自动增加,并且是一一对应。
序列的下标:在星语言中,序列下标0代表最近的一根K线所对应的序列数据;下标1代表前一根K线所对应的数据。
序列计算引擎
那么,在看过系统中的一些公式指标实例之后,稍有传统语言编程经验的人都会立刻产生一个疑问。
那就是,在这些指标公式里,序列并不通过下标直接使用。
例如这样的一句:
a1: close - open;
这句话所起的作用是,计算开盘价减去收盘价的值。并且是对于每根K线,a1都会得到一个对应的值。a1也是序列。
既然序列是数组,为什么可以不通过下标就直接使用? 根据传统编程经验,要得到数组中每一个元素的值,必须写一个循环,计算每个元素,产生新的结果。
例如这样:
for i=1 to sizeof( close ) do begin a1[i] := close[i] - open[i]; end;
为什么在指标中,可以不写这个循环呢?
答案是:指标引擎在背后默默的帮我们做了这份工作。
在股票类数据运算中,序列用得太多,太频繁,如果指标引擎不替用户做这份循环计算工作的话,那么用户编写程序的时候,将会非常的麻烦。 任何一个简单的操作,都要写上一大堆的循环。 有心人可以去观摩一个股软metaTrader的指标。metaTrader的内置语言是不替用户做序列循环计算的。 实现相同功能,它的源码要比其他的股软长的多 举个简单例子,macd,在metaTrader里面要写这么多代码:
//+------------------------------------------------------------------+ //| Custom MACD.mq4 | //| Copyright ?2004, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property copyright "Copyright ?2004, MetaQuotes Software Corp." #property link "http://www.metaquotes.net/" //---- indicator settings #property indicator_separate_window #property indicator_buffers 3 #property indicator_color1 Silver #property indicator_color2 Red #property indicator_color3 Green #property indicator_width1 2 //---- indicator parameters extern int FastEMA=12; extern int SlowEMA=26; extern int SignalSMA=9; //---- indicator buffers double DiffBuffer[]; double MacdBuffer[]; double SignalBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
//SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexStyle( 0, DRAW_LINE );
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle( 2, DRAW_HISTOGRAM);
SetIndexDrawBegin(1,SignalSMA);
IndicatorDigits(Digits+1);
//---- indicator buffers mapping
//SetIndexBuffer(0,MacdBuffer);
SetIndexBuffer(0,DiffBuffer);
SetIndexBuffer(1,SignalBuffer);
SetIndexBuffer(2,MacdBuffer);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("MACD("+FastEMA+","+SlowEMA+","+SignalSMA+")@@#");
//SetIndexLabel(0,"MACD");
//SetIndexLabel(1,"Signal");
SetIndexLabel(0,"Diff");
SetIndexLabel(1,"Dea");
SetIndexLabel(2,"MACD");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| *****Moving Averages Convergence/Divergence ***** |
//| DIFF : EMA(CLOSE,S) - EMA(CLOSE,P); |
//| DEA : EMA(DIFF,M); |
//| MACD : 2*(DIFF-DEA), COLORSTICK |
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
for(int i=0; i<limit; i++)
DiffBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
for(i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArray(DiffBuffer,Bars,SignalSMA,0,MODE_SMA,i);
for ( i=0; i<limit; i++ )
MacdBuffer[i] = 2*(DiffBuffer[i]-SignalBuffer[i]);
//---- done
return(0);
}
//+------------------------------------------------------------------+