通达信BARSLAST 接收一个条件表达式,返回上一次这个条件成立的那一根,到当前这一根之间隔了多少根。条件在当根成立时返回 0,隔一根返回 1,往后依次加一。这个返回值是一个整数计数,不是一个真假值,把它放到真假判断的位置,得到的结果与条件本身不同。下面把返回值的来源、几个容易混的函数、以及几处常见的用法偏差按顺序讲清楚。

口径以通达信金融终端个人版的公式语言为准,公式管理器里的提示措辞与函数说明在不同版本里可能有差异,以本地版本的实际输出为准。文中的写法都可以放进公式管理器,用「测试公式」按钮先过一遍语法,再挂到图上核对数值。

一、BARSLAST(X) 返回上一次成立到当前的周期数

先看返回值的构成。函数不关心条件在历史上成立过几次,只关心最近的那一次。当前根成立,返回 0;上一根成立,返回 1;上五根成立,返回 5。中间又成立过一次,计数从新的一次重新起算。这个特性决定了它适合回答「距离上一次发生过了多久」,不适合回答「历史上发生过几次」。

COND:=CROSS(MA(CLOSE,5),MA(CLOSE,20));
DIST:=BARSLAST(COND);
DRAWTEXT(DIST=0, LOW*0.97, 'CROSS');

上面这段把距离单独存成一列输出。把它挂到副图,纵轴就是一根一根数出来的距离;把它放进 DRAWTEXT 的定位参数,就变成画在价格上的标记。同一段公式换一个挂法,读法完全不同,后面的用法都建立在这个数上。

计数单位是「根」,不是「天」。在日线上,一根就是一天;在 60 分钟线上,一根是一小时。同一个条件在两个周期上算出来的距离数值不同,因为被数的格子大小不一样。跨周期引用的时候,这个差别会被放大。

二、条件从未成立时返回什么

条件在已加载的数据里一次都没有成立,返回值就失去「最近一次」这个参照,转而与数据的起点发生关系:计数从数据起点开始累加,读出来的就是当前这一根距数据起点的距离。换一段加载范围,这个数跟着变。同一个公式,在导出数据长度不同的两台机器上,可能读出两个数。

这种情况在图上留不下标记,判断起来靠旁的线索。把距离挂到副图上,曲线从最左边开始单调上升、中间没有归零的位置,说明条件在这段数据里没有成立过,而不是条件成立得太早。归零的位置就是成立的位置。看到一条一路向上的线,先想到的是条件没触发,而不是公式哪里坏了。

把这类返回值保存下来当作固定值引用,换一段数据之后就对不上。落进记录表之前先确认对应的条件在数据范围内确实成立过;没有成立过的,那个数是数据长度,不是距离。

三、BARSCOUNT 与 BARSLAST 的差别在口径

把通达信BARSLAST 与 BARSCOUNT 并排看,两个函数都返回整数,口径不同。BARSLAST 数的是「距离」:最近一次成立的那一根,到现在隔了多少根,起点随条件移动。BARSCOUNT 数的是「累计」:从第一根有效数据起算,到当前一共有多少根,起点由数据本身决定,与条件无关。

VALID:=BARSCOUNT(CLOSE);        { 自第一根有效数据起算的根数 }
AT_HEAD:=BARSCOUNT(CLOSE)=1;    { 只落在第一根有效数据上 }
RECENT:=BARSLAST(CLOSE>REF(CLOSE,1));

口径的差别带来的后果是:同一个数在两种写法下的含义不可互换。用 BARSCOUNT 的读数去替代距离,等于把数据起点当成条件成立点;用距离去替代累计根数,等于把最近一次当成第一次。需要统计「条件累计成立了多少根」,用的是 COUNT 这一类写法,而不是这两个函数中的一个。

数据的有效起点也会影响读数。停牌段不产生新的根,因此距离只在有交易的那几根上累加。把停牌前后两根当作相邻,计数就会比实际的时间跨度小。核对读数时,先确认这段时间里有没有停牌。

四、COUNT 与 FILTER 组合时的用法

单独一个通达信BARSLAST 的距离数,能表达的信息有限。与 COUNT 组合,可以区分「最近一次」与「这一段里的次数」;与 FILTER 组合,可以先把密集出现的成立点压成一个点,再量距离,得到的数才是两次间隔。

CNT:=COUNT(COND,60);        { 最近 60 根里 COND 成立的次数 }
ONLY:=FILTER(COND,10);      { COND 成立后 10 根内的重复成立被压掉 }
GAP:=BARSLAST(ONLY);        { 相邻两个成立点之间的间隔 }

上面三行的顺序不能换。先 COUNT 再 FILTER,得到的是两组不同口径的数;先 FILTER 再 BARSLAST,量到的是被压缩之后的间隔。函数之间的先后决定了取哪一根作为参照,这一段与信号拆解里讲的条件分层是同一件事,公式里的顺序就是口径。

再往下可以做一个条件式的判读。把距离的数与阈值比较,得到一个状态:距离落在给定的根数以内为一种状态,之外为另一种。这一步只做分类,不涉及对后面走势的看法。

NEAR:=BARSLAST(COND)<=10;
FAR:=BARSLAST(COND)>10;
STATUS:=IF(NEAR,1,IF(FAR,-1,0));

五、它引用已有数据,与 ZIG、PEAK 不是一类

通达信BARSLAST 的输入与输出都只依赖已经出现的那几根。条件在某一根成立,计数从那一根往后加,后面新来的数据只影响新的读数,不改动已经走过的位置。把公式挂到副图上逐根回放,同一根上的数值不随之后的数据变化,这是它不属于未来函数类写法的判断依据。

ZIG、PEAK、TROUGH 这一类函数相反,它们要等到后续数据确认了转折,才能定下前面某一个点的位置,因而同一个历史点上的输出会随之后的数据改变。两类函数的差别不在写法长短,而在是否引用了当前根尚未产生的数据。把距离类函数与转折类函数混在同一段公式里,回放时看到的稳定性只属于前一部分。

公式管理器里的「测试公式」按钮只做语法检查,不判断是否引用了未来数据。要确认这一点,靠的是逐根回放看同一根的读数有没有变化,不能靠按钮的通过结果。

六、两处常见误用与几步判断

第一处误用是把返回值直接放进判断位置。公式语言里的真假判断按「非零为真、零为假」处理,而 BARSLAST 在条件成立的当根返回 0,在不成立时返回正数,方向正好与条件相反。写成条件位置,得到的状态与条件相反。

MISUSE:=IF(BARSLAST(COND),1,0);   { 非零即真,方向与 COND 相反 }
OKUSE:=BARSLAST(COND)=0;          { 当根成立才为真 }

第二处误用是跨周期取值时的口径不一致。在 30 分钟图上算出的距离与在日线上算出的不是同一个数;用 #DAY、#MIN30 这类格式引用另一个周期的数据时,取回来的序列按被引用周期的格子计数,而当前图的格子是另一套。两个口径的数放在同一段条件里比较,比较的结果没有意义。要比较就先统一到一个周期上算。

现象 含义 处理
副图曲线一路向上不归零 条件在已加载的数据里没有成立过,读到的是距数据起点的根数 补长数据范围,或核对条件写法是否过严
计数结果与条件方向相反 把返回值当成真假值使用,非零为真 改成与 0 比较的写法,明确取哪一根
两个周期上的数对不上 计数单位是「根」,各周期的格子长度不同 先统一周期,再比较数值
距离比实际时间跨度小 停牌段不产生新的根,计数只累加有交易的根 核对区间内有没有停牌
回放时读数前后变化 同一段公式里混入了转折类函数 把距离类输出单独拆出来复核

把上面的判读压成几步,用于核对通达信BARSLAST 的返回值:先看曲线有没有归零的位置,确认条件是否成立过;再把返回值与 0 比较,明确取当根还是取间隔;然后确认当前图的周期与引用周期的口径是否一致;最后逐根回放,看同一根的读数稳不稳。四步之外仍对不上的,先把加载的数据范围补长,再看一遍。

本文只作技术研究口径,不涉及也不构成对任何标的的判断。

站内还有 通达信公式编写教程 的其余条目,指标原理与参数 里讲周期与参数的关系,可对照查看。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。