ptLibert 发表于 2012-9-18 12:06:13

逐行和逐根

一。序列

要理解什么是逐行和逐根,首先要理解什么是“序列”。

在多数股软里,K线就是内置的序列。当然,一根K线实际上是由开高低收量额组成的。
所以也就有对应的close,open,high,low,vol,amount等五个内置序列。

序列是很特别的一类数据。它跟数组很相像:每个序列都由多个元素组成,可以通过下标访问。

序列跟数组的区别:
数组在声明时已经定义好元素数量,之后不会改变;而序列在声明时并不指明元素数量。它的数量由K线数量决定,随着行情进行,K线不断增加,序列也相应的自动增加,并且是一一对应。

序列的下标:金语言中,序列下标0代表最近的一根K线所对应的序列数据;下标1代表前一根K线所对应的数据。

ptLibert 发表于 2012-9-18 12:06:58

本帖最后由 ptLibert 于 2012-9-19 22:42 编辑

那么,在看过我们的指标实例之后,稍有传统语言编程经验的人都会立刻产生一个疑问。

那就是,实际上,在飞狐/tradestation等股软中,序列常常不通过下标直接使用。

例如这样的一句:

[*]a1 : close - open;

复制代码
计算得到开盘价减去收盘价的值。并且是对于每根K线,a1都会得到一个对应的值。
也就是说,a1也是序列。

既然序列是数组,为什么可以不通过下标就直接使用?
根据传统编程经验,要得到数组中每一个元素的值,必须写一个循环,计算每个元素,产生新的结果。

例如这样:for i=1 to sizeof( close ) do begin
    a1 := close - open;
end;为什么在指标中,可以不写这个循环呢?

答案是:指标引擎在背后默默的帮我们做了这份工作。

ptLibert 发表于 2012-9-18 12:08:38

在股票类数据运算中,序列用得太多,太频繁,如果指标引擎不替用户做这份循环计算工作的话,那么用户编写程序的时候,将会非常的麻烦。




任何一个简单的操作,都要写上一大堆的循环。




有心人可以去观摩一个股软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=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=iMAOnArray(DiffBuffer,Bars,SignalSMA,0,MODE_SMA,i);
   for ( i=0; i<limit; i++ )
      MacdBuffer = 2*(DiffBuffer-SignalBuffer);
//---- done
   return(0);
  }
//+------------------------------------------------------------------+




而在一般股软里,只需要这几行:
DIFF : EMA(CLOSE,S) - EMA(CLOSE,P);
DEA  : EMA(DIFF,M);
MACD : 2*(DIFF-DEA), COLORSTICK;








ptLibert 发表于 2012-9-18 12:09:05

言归正传,所谓“逐行模式”和“逐根模式”,就是指标引擎在背后帮用户进行循环工作时的两种不同的工作模式。

ptLibert 发表于 2012-9-18 12:09:28

考察macd指标中的两行语句:DIFF : EMA(CLOSE,S) - EMA(CLOSE,P);
DEA  : EMA(DIFF,M);在逐行模式和逐根模式中,它们是怎样做循环的呢?




-----------------------------------------------------------------------------------------------------------  
逐行模式
假设当前有N根K线。
    计算过程:
          计算diff的第1个元素,计算diff的第2个元素,............计算diff的第N个元素。
          计算dea的第1个元素,计算dea的第2个元素,..........计算dea的第N个元素。 
   
          新行情到来




          计算diff的第1个元素,计算diff的第2个元素,.....计算diff的第N个元素,计算diff的第N+1个元素。
          计算dea的第1个元素,计算dea的第2个元素,.....计算dea的第N个元素,计算dea的第N+1个元素。
-----------------------------------------------------------------------------------------------------------








-----------------------------------------------------------------------------------------------------------
逐根模式
计算过程:
          计算diff的第1个元素,
          计算dea的第1个元素,
          计算diff的第2个元素,
          计算dea的第2个元素,
          ............计算diff的第N个元素。
          ..........计算dea的第N个元素。




          新行情到来
          ............计算diff的第N+1个元素。
          ..........计算dea的第N+1个元素。
-----------------------------------------------------------------------------------------------------------












ptLibert 发表于 2012-9-18 12:09:53

看到区别了吗,行模式下,每次新行情的到来,指标引擎都要把需要计算的序列从头到尾全部计算一遍。
而逐根模式下,每次新行情到来,指标引擎只计算最新一根的值。

当然,逐行模式和逐根模式还有更多的区别和适用范围。
下面再逐一解释。

ptLibert 发表于 2012-9-18 12:10:07

本帖最后由 ptLibert 于 2012-9-19 22:29 编辑

逐根和逐行的差异

差异一:计算结果
逐行和逐根可能产生不一样的计算结果。
逐行模式,每次计算都对序列中所有元素重新计算,所以,有些情况下,某些以前计算过的值可能被修改。
也就是调用了俗称所谓“未来函数”一族函数的时候。
在这种情况下,不但调用未来函数的该行语句的序列结果会发生改变,后续语句如果用到被影响的变量,那么它们之前的值也都可能因此发生改变。

而对于逐根模式,每次计算都只计算最新一根,所以即使调用了未来函数,那么它也只改变到该函数直接影响的序列,而很可能不会将改变带给下面的计算。

差异二:计算速度
一般来说,逐行计算在K线图第一次打开时,速度要略快于逐根模式。
因为,对于很多指标,一次整行算完的话,作一些算法上的优化会比较方便。
但是,在新行情到来时,逐根计算就非常有优势了;此模式下,只计算最后一根的数值。


在测评模式下,逐根模式的速度优势可以完全的体现出来。
测评相当于一次性渐次灌入成千上万的行情。逐行的话,要对整行重复计算成千上万次,而逐根模式只需要对单根计算这么多次。
整体时间消耗的差别是几十倍上千倍的。

ptLibert 发表于 2012-9-18 12:10:24

适用范围

1、一般技术指标比较适用逐行模式。尤其是用到一些传统的未来函数时。例如,backset,zig,refx
2、交易策略指标比较适合逐根模式。

wh8510 发表于 2012-9-19 21:35:42

谢谢楼主 又学习了

jrtj 发表于 2012-10-17 15:42:37

逐行和逐根, 在智能交易系统里都应该支持,这样才好,
很多MT4转换过来的都不支持逐根。
页: [1] 2 3 4
查看完整版本: 逐行和逐根