麦语言 变量赋值 := 与 : 的区别:画线还是变量
这篇讲什么
文华8麦语言里 : 是输出到图表,:= 是内部赋值,两者都能被引用但效果完全不同。本文讲清判断规则、两个高频误用(中间变量全画线导致图乱、想看的值看不到),附同一策略的两种写法对比。
一句话区分
两个符号都表示「把右边的值给左边这个变量」,区别只在于要不要把结果显示到图表上:
- : 输出——在图表上画出这条线,指标窗口里能看到数值;
- := 赋值——只在模型内部计算,图上不画线,但后续代码可以正常引用。
所以判断标准只有一条:这个值你想不想在图上看到。想看到用 :,不想看到用 :=。
用错会怎样:两个方向都是坑
坑一:中间变量全用 : 。一个稍微完整点的策略有十几个中间量——真实波幅、ATR、均线差、条件标记、手数……全部画到图上,指标窗口会挤成一片,主图上叠七八条线,想看 K 线都费劲,加载速度也会变慢:
// 图会变成这样:主图上多出 6 条线,完全没法看
MA5:MA(C,5);
MA20:MA(C,20);
TR:MAX(MAX(H-L,ABS(REF(C,1)-H)),ABS(REF(C,1)-L));
ATR:MA(TR,26);
DIFF:MA5-MA20;
TC:MAX(1,INTPART(MONEYTOT*0.02/(UNIT*ATR)));坑二:想看的值用 := 。反过来也一样难受——手数算出来了、条件成立了,但图上什么都看不到,回测时想确认「到底给我开了几手」都查不到。调试阶段尤其需要把这些关键中间量输出出来。
正确的分法:三层结构
一个策略的变量可以分成三层,按层决定用哪个符号:
- 第一层:想看的指标(均线、通道上下轨、手数)→ 用 :,让它在图上可见;
- 第二层:只用于计算的中间量(真实波幅 TR、临时差值、条件标记)→ 用 :=,别污染图表;
- 第三层:信号指令(BPK/SPK 那些行)→ 不需要赋值符号,条件后直接跟逗号和指令。
// 按三层结构改写同一段策略
MA5:MA(C,5); // ① 想看的:主线
MA20:MA(C,20); // ① 想看的:主线
TR:=MAX(MAX(H-L,ABS(REF(C,1)-H)),ABS(REF(C,1)-L)); // ② 中间量
ATR:=MA(TR,26); // ② 中间量
TC:MAX(1,INTPART(MONEYTOT*0.02/(UNIT*ATR))); // ① 想看的:当前手数
CROSS(MA5,MA20),BK; // ③ 指令行,不加赋值符号
CROSSDOWN(MA5,MA20),SP;
AUTOFILTER;改写之后主图上只剩两条均线,指标窗口里多一个「当前手数」,图表干净、信息不丢。这是站内策略源码统一采用的写法。
三个容易搞混的细节
细节一::= 定义的变量照样能参与条件判断。不少人以为「不画线的变量不能用」,其实完全可以用,它只是不显示而已:
COND:=CROSS(MA5,MA20) && C>MA20;
COND,BK; // COND 没有画线,但可以正常当信号条件细节二:指令行不要加赋值符号。写 BK:=CROSS(...) 是把指令当变量赋值,逻辑上是错的,正确写法是「条件变量 + 逗号 + 指令」,或者「条件表达式 + 逗号 + 指令」。
细节三:参数不走这两个符号。可调参数(如周期 N)必须在参数表里声明,在代码里写 N:=20 只是定义了一个固定变量,加载模型时改不了——想让它可调,就得进参数表。
调试期的一个实用技巧
调试策略时,把关键中间量临时从 := 改成 :,就能在图上直接看到它们的数值,确认「条件到底有没有成立」「手数算出来是多少」。确认无误后再改回 := 让图表干净:
// 调试期:临时输出三个关键量
DIFF:MA5-MA20; // 看均线差有没有过零
ATR:MA(TR,26); // 看波动率量级
TC:MAX(1,INTPART(MONEYTOT*0.02/(UNIT*ATR))); // 看手数是否合理这个习惯能省掉大量「回测没成交但不知道为什么」的排查时间。尤其是手数算出来是 0 的情况,图上直接就看出来了。
和外盘/其他平台语法的差异
从通达信、文华6 或其他平台移植代码时,赋值符号经常对不上:有的平台只有 :、有的用 = 表示赋值。移植时务必逐个检查这一行——符号写错不会报语法错,但行为会变(本该隐藏的中间量全画到图上,或者本该显示的指标消失了)。
移植后的自检方法:加载到图表上,数一下主图有几条线。线数和预期不符,就是赋值符号用错了。
常见问题
:= 定义的变量能在后面的条件里引用吗?
可以,而且这正是它的主要用途。:= 只控制「是否画线」,不影响变量的可用性,后续的条件判断、手数计算都能正常引用。
同一个变量名定义了两次,会怎样?
后定义的会覆盖前面的,且不会报错——这类问题最隐蔽。建议一个变量只定义一次,需要复用就换个名字,或者把计算抽成独立变量。
为什么有些行没有 : 或 := 也能编译通过?
指令行(BPK、SPK、BK、SP 等)和 AUTOFILTER 不是变量赋值,它们本身就是语句,不需要赋值符号。只有「名字 = 表达式」这种形式才需要选 : 或 :=。
黑公网安备23010302002054号