简介:这份文档面向通达信公式爱好者与股票技术分析学习者,围绕“空间与时间及压力与支撑”主题,提供主图指标公式源码及配套解析,帮助读者理解价格波动幅度、周期跨度与关键压力支撑位的量化表达方式。资源包共1个doc文件,约720KB,内容以源码文本与注释说明为主,便于直接复制到通达信公式管理器中使用或二次修改。源码中涉及DRAWLINE绘制高低点连线、CONST锁定周期常量、DRAWTEXT_FIX固定位置显示幅度与周期信息,以及CALCSTOCKINDEX调用大盘数据计算整体波动幅度等函数,并给出底点到高点、近期低点到当前幅度、高点到当前周期等观察维度。目前已有67人学习,适合希望把时间与空间概念落到指标图表上的中阶用户参考,需结合其他工具综合判断。
1. 空间与时间及压力与支撑:一套把K线拆成“位置+时机”的指标思路
很多人做通达信指标,第一反应是堆均线、叠MACD,结果图上一团乱麻,信号还互相打架。这套“空间与时间及压力与支撑”的思路,本质是把两个维度拆开看:空间回答“价格现在站在哪个位置”,时间回答“这个位置该不该现在动手”。压力与支撑负责画框,空间与时间负责在框里找扣扳机的瞬间。它适合已经会写基础公式、但苦于信号杂乱、想给买卖点加一层结构过滤的从业者。我最早接触这类写法,是在一个模拟项目里被反复打脸之后——单看金叉死叉,胜率惨不忍睹,加上位置过滤才勉强能看。这篇就把这套指标的源码结构、参数含义和落地步骤讲透,让你能自己改、自己调,而不是抄一段看不懂的代码供着。
2. 压力与支撑怎么在通达信里画出来:从高低点到动态轨道
2.1 静态压力支撑与动态压力支撑的区别
压力支撑不是画一条线就完事。静态的,是拿过去某段高低点固定住,比如前期高点、前期低点,画出来就不动了。动态的,是随着价格推移不断重算,比如用均线、用通道、用分形高低点滚动更新。通达信里两者都能做,但用途完全不同。静态线适合判断大级别位置,比如周线前高,价格到那儿就得警惕;动态线适合跟趋势,比如布林带中轨、唐奇安通道,价格贴着走就说明趋势还在。
我一般会同时保留两套:一套用HHV和LLV取N周期高低点,画静态框;另一套用EMA或SAR做动态跟随。源码里常见写法是:
{静态压力支撑:取60周期高低点} N:=60; STATIC_HIGH:=HHV(H,N); STATIC_LOW:=LLV(L,N); {动态压力支撑:用20周期均线加减2倍ATR} MID:=EMA(C,20); ATR_VAL:=MA(MAX(MAX(H-L,ABS(H-REF(C,1))),ABS(L-REF(C,1))),14); DYN_HIGH:=MID+2*ATR_VAL; DYN_LOW:=MID-2*ATR_VAL;逻辑说明:HHV(H,N)取N周期内最高价,代表这段时间多头能摸到的天花板;LLV(L,N)取最低价,是地板。动态部分用EMA(C,20)做中轴,ATR_VAL算14周期平均真实波幅,上下各扩2倍,形成通道。参数上,N取60适合日线级别,太小会被噪音带偏,太大又反应迟钝;ATR倍数2是常见值,想更敏感改1.5,想更稳改2.5。注意ABS和MAX嵌套别写错括号,通达信对括号匹配很严格,少一个就报错。
2.2 用分形高低点做动态支撑压力的源码实现
分形高低点比单纯HHV/LLV更精细,它只取那些“左右两边都比它低”的高点,过滤掉一堆假突破。通达信里用REF和BARSLAST配合就能写:
{分形高点:当前高点比左右各2根都高} FRAC_HIGH:=H=HHV(H,5) AND H>REF(H,1) AND H>REF(H,2) AND H>REF(H,-1) AND H>REF(H,-2); {分形低点:当前低点比左右各2根都低} FRAC_LOW:=L=LLV(L,5) AND L<REF(L,1) AND L<REF(L,2) AND L<REF(L,-1) AND L<REF(L,-2); {取最近一个分形高点的值作为压力} LAST_FRAC_HIGH:=REF(H,BARSLAST(FRAC_HIGH)); {取最近一个分形低点的值作为支撑} LAST_FRAC_LOW:=REF(L,BARSLAST(FRAC_LOW));逻辑说明:HHV(H,5)判断当前高点是不是5周期内最高,再配合左右各2根的比较,确保它是局部尖峰。BARSLAST(FRAC_HIGH)返回上一次分形高点距离现在的周期数,REF(H,那个数)就把那个高点价格取回来。参数上,左右各2根是常用设置,想更灵敏改1根,想更稳改3根。坑在于REF的第二个参数不能为负数,如果BARSLAST返回0(当前就是分形点),REF(H,0)就是当前高价,逻辑上没问题,但画线时要注意别把当前还没走完的K线算进去,否则会漂移。
2.3 把压力支撑画到主图上的完整步骤
写好了计算逻辑,下一步是让它显示出来。通达信主图指标用DRAWTEXT、DRAWLINE、STICKLINE这些函数。我一般用水平虚线标静态线,用变色线标动态轨道:
{画静态压力支撑,用绿色虚线} STICKLINE(CURRBARSCOUNT=1,STATIC_HIGH,STATIC_HIGH,0,0),COLORGREEN; STICKLINE(CURRBARSCOUNT=1,STATIC_LOW,STATIC_LOW,0,0),COLORGREEN; {画动态轨道,用红色和蓝色} DYN_HIGH_LINE:IF(CURRBARSCOUNT>1,DYN_HIGH,DRAWNULL),COLORRED; DYN_LOW_LINE:IF(CURRBARSCOUNT>1,DYN_LOW,DRAWNULL),COLORBLUE; {在最新K线位置标注数值} DRAWNUMBER(CURRBARSCOUNT=1,STATIC_HIGH,STATIC_HIGH),COLORGREEN; DRAWNUMBER(CURRBARSCOUNT=1,STATIC_LOW,STATIC_LOW),COLORGREEN;逻辑说明:CURRBARSCOUNT=1表示只画在最后一根K线上,避免历史线乱糟糟。STICKLINE画水平线段,宽度设0就是细线。动态线用IF判断,CURRBARSCOUNT>1才输出值,否则返回DRAWNULL不画。DRAWNUMBER在最新位置标数值,方便一眼看到具体价格。参数上,颜色和线型按自己习惯改,但建议压力用冷色、支撑用暖色,或者反过来,保持一致性。注意DRAWNULL是通达信特有的空值,不能写成0,否则线会掉到0去。
3. 时间维度怎么落地:周期共振与时间窗口的源码写法
3.1 用BARSLAST和REF构建时间窗口
时间维度听起来玄,落到代码里就是“距离某个事件过去多久”。比如距离上次分形高点过去多少根K线,距离上次金叉过去多少天。通达信里BARSLAST是核心函数,配合REF就能取到任意历史时点的值:
{距离上次分形高点过去的周期数} BARS_SINCE_HIGH:=BARSLAST(FRAC_HIGH); {距离上次分形低点过去的周期数} BARS_SINCE_LOW:=BARSLAST(FRAC_LOW); {如果距离上次高点超过20周期,认为时间窗口打开} TIME_WINDOW_HIGH:=BARS_SINCE_HIGH>20; {如果距离上次低点超过20周期,认为时间窗口打开} TIME_WINDOW_LOW:=BARS_SINCE_LOW>20;逻辑说明:BARSLAST返回上一次条件成立到现在的周期数,如果从来没成立过,返回一个很大的数或者无效值,实际用的时候最好加个IF判断。TIME_WINDOW_HIGH为真,说明价格已经很久没摸到压力了,要么是蓄势,要么是趋势太弱。参数上,20周期是日线级别的常用值,对应大约一个月交易日;想做短线可以改10,做长线改40。坑在于BARSLAST在条件从未成立时返回值不稳定,最好用IF(BARSLAST(FRAC_HIGH)>0,BARSLAST(FRAC_HIGH),999)兜底。
3.2 多周期共振:日线、周线、月线的时间对齐
单周期的时间窗口容易骗人,多周期共振才靠谱。通达信支持跨周期引用,用CALCSTOCKINDEX或者直接写“MACD.MACD#WEEK”这种格式。我一般会检查日线时间窗口打开的同时,周线是不是也在窗口内:
{引用周线数据} WEEK_CLOSE:=“CLOSE#WEEK”; WEEK_HIGH:=“HIGH#WEEK”; WEEK_LOW:=“LOW#WEEK”; {周线分形高点} WEEK_FRAC_HIGH:=WEEK_HIGH=HHV(WEEK_HIGH,5) AND WEEK_HIGH>REF(WEEK_HIGH,1); {周线距离上次分形高点的周期数} WEEK_BARS_SINCE_HIGH:=BARSLAST(WEEK_FRAC_HIGH); {日线和周线同时处于时间窗口} RESONANCE_HIGH:=TIME_WINDOW_HIGH AND WEEK_BARS_SINCE_HIGH>4;逻辑说明:“CLOSE#WEEK”是通达信跨周期引用的写法,注意引号是英文双引号,不是中文引号。WEEK_BARS_SINCE_HIGH>4表示周线级别也过了4周以上,4周约等于一个月。RESONANCE_HIGH为真时,说明日线和周线都在等同一个位置,这种信号质量比单周期高不少。参数上,周线阈值4是经验值,想更严改6,想更松改2。坑在于跨周期引用会消耗更多计算资源,如果公式里大量用,刷新会变慢,建议只在关键判断上用。
3.3 时间窗口与价格位置的联合判断
光有时间窗口不够,还得看价格是不是到了关键位置。把第2章的压力支撑和第3章的时间窗口拼起来,才是完整的“空间+时间”:
{价格接近静态压力,且时间窗口打开} SELL_SIGNAL:=C>=STATIC_HIGH*0.98 AND C<=STATIC_HIGH*1.02 AND TIME_WINDOW_HIGH; {价格接近静态支撑,且时间窗口打开} BUY_SIGNAL:=C>=STATIC_LOW*0.98 AND C<=STATIC_LOW*1.02 AND TIME_WINDOW_LOW; {画信号图标} DRAWICON(SELL_SIGNAL,H*1.02,2); DRAWICON(BUY_SIGNAL,L*0.98,1);逻辑说明:C>=STATIC_HIGH*0.98 AND C<=STATIC_HIGH*1.02表示价格在压力线上下2%范围内,算“接近”。TIME_WINDOW_HIGH确保这个接近不是刚碰完又碰,而是隔了一段时间。DRAWICON画箭头,2是向下箭头,1是向上箭头。参数上,2%的容差可以改,波动大的品种改3%或5%,波动小的改1%。坑在于DRAWICON的图标编号不同版本可能略有差异,最好先在小周期上试一下,确认箭头方向没反。
4. 避坑与常见问题:源码调试中容易翻车的五个地方
4.1 未来函数导致信号漂移
现象:复盘时信号完美,实盘时信号消失或移位。原因:用了ZIG、PEAK、TROUGH这类未来函数,它们会引用未来数据。解决:把未来函数全部替换成HHV、LLV、BARSLAST等只依赖历史数据的写法。如果非要用分形,确保左右比较的REF只引用已走完的K线,别用REF(H,-1)这种。
4.2 跨周期引用数据不对齐
现象:日线图上引用的周线数据,在周中显示的是上周的值,周末又变了。原因:跨周期引用默认取的是上一周期完成后的值,周中周线还没走完,引用的就是上周的。解决:要么接受这个延迟,要么在公式里加WEEK_CLOSE判断,只在周五收盘后或周一开盘前看信号。我一般会在信号条件里加WEEKDAY=5或者DAY=1来限制。
4.3 参数过多导致过拟合
现象:回测胜率90%,实盘亏成狗。原因:参数太多,每个参数都对着历史数据调过,换一段行情就失效。解决:核心参数不超过3个,比如N周期、ATR倍数、时间窗口阈值。其他能固定就固定,能简化就简化。我见过一个公式用了17个参数,回测曲线漂亮得像假的一样,实盘一跑就原形毕露。
4.4 画线函数在历史K线上重复绘制
现象:主图上密密麻麻全是线,看不清K线。原因:DRAWLINE或STICKLINE没加CURRBARSCOUNT限制,每根K线都画。解决:所有画线函数都加CURRBARSCOUNT=1或者ISLASTBAR判断,只在最后一根K线或最新位置画。如果非要画历史线,用DRAWLINE配合FILTER过滤,别每根都画。
4.5 数值精度导致条件判断失效
现象:明明价格到了压力位,信号就是不触发。原因:浮点数比较有误差,C=STATIC_HIGH这种精确相等几乎不可能成立。解决:所有价格比较都用容差,比如ABS(C-STATIC_HIGH)/STATIC_HIGH<0.02。另外,通达信内部计算有精度限制,太小的容差比如0.001%也没意义,一般0.5%到2%比较合适。
5. 进阶技巧:把空间时间压力支撑做成可复用的信号过滤器
5.1 用FILTER函数过滤重复信号
信号太多也是灾难。FILTER函数可以让同一个信号在N周期内只出现一次:
{原始买入信号} RAW_BUY:=BUY_SIGNAL; {过滤后,10周期内只出一次} FILTERED_BUY:=FILTER(RAW_BUY,10); DRAWICON(FILTERED_BUY,L*0.98,1);逻辑说明:FILTER(RAW_BUY,10)表示如果RAW_BUY为真,接下来10个周期内即使再为真也不输出。参数上,10周期是日线常用值,想做更密集的信号改5,想更稀疏改20。注意FILTER会改变信号的时间分布,回测时要用过滤后的信号,别用原始的。
5.2 把信号强度量化成评分
光有买卖点不够,还得知道这个点有多强。我一般会做一个简单评分:
| 条件 | 分值 |
|---|---|
| 价格在静态支撑2%范围内 | +30 |
| 时间窗口打开 | +20 |
| 动态轨道下轨向上 | +20 |
| 周线共振 | +30 |
{计算评分} SCORE:=0; SCORE:=SCORE+IF(C>=STATIC_LOW*0.98 AND C<=STATIC_LOW*1.02,30,0); SCORE:=SCORE+IF(TIME_WINDOW_LOW,20,0); SCORE:=SCORE+IF(DYN_LOW>REF(DYN_LOW,1),20,0); SCORE:=SCORE+IF(WEEK_BARS_SINCE_HIGH>4,30,0); {评分大于70才出信号} STRONG_BUY:=SCORE>=70; DRAWICON(STRONG_BUY,L*0.98,1); DRAWNUMBER(STRONG_BUY,L*0.96,SCORE),COLORRED;逻辑说明:每个条件满足加对应分值,总分100。SCORE>=70作为强信号阈值,可以自己调。DRAWNUMBER把评分标在K线下方,方便一眼看出强度。参数上,分值分配按经验来,觉得哪个条件更重要就加更多分。坑在于IF嵌套太多会影响速度,如果公式卡顿,把评分逻辑拆到副图指标里算,主图只引用结果。
5.3 用VAR变量简化重复计算
通达信支持VAR或直接赋值变量,把重复计算的部分抽出来,公式更干净:
{公共变量} MY_HIGH:=HHV(H,60); MY_LOW:=LLV(L,60); MY_ATR:=MA(MAX(MAX(H-L,ABS(H-REF(C,1))),ABS(L-REF(C,1))),14); {压力支撑} P_HIGH:=MY_HIGH; P_LOW:=MY_LOW; D_HIGH:=EMA(C,20)+2*MY_ATR; D_LOW:=EMA(C,20)-2*MY_ATR; {时间窗口} T_HIGH:=BARSLAST(H=MY_HIGH)>20; T_LOW:=BARSLAST(L=MY_LOW)>20; {信号} BUY:=C>=P_LOW*0.98 AND C<=P_LOW*1.02 AND T_LOW; SELL:=C>=P_HIGH*0.98 AND C<=P_HIGH*1.02 AND T_HIGH;逻辑说明:把HHV、LLV、ATR这些算一次就够的抽成公共变量,后面直接引用,减少重复计算。T_HIGH和T_LOW用BARSLAST判断距离上次高低点的周期数。参数上,60和20这些数字统一放前面,改的时候只改一处。坑在于通达信对变量名长度有限制,别用太长的名字,也别用中文变量名,容易出兼容问题。
这套东西我断断续续改了快两年,最大的教训是:别指望一个公式解决所有问题。空间时间压力支撑,本质是给你一个观察市场的框架,不是印钞机。我现在的习惯是,每周复盘时把信号翻出来,看看哪些是位置对了但时间没到,哪些是时间到了但位置不对,慢慢就能摸出自己品种的脾气。希望帮到你。
本文还有配套的精品资源,点击获取