简介:麦语言是文华财经推出的国内第一套程序化函数库,采用"小语法,大函数"的积木式编程理念,将复杂算法封装为各类函数,配合丰富的金融统计函数库,可支撑逻辑复杂的金融应用。这份函数手册系统整理了麦语言核心函数体系,涵盖历史数据引用(AVPRICE、SETTLE、CLOSE、HIGH、LOW、OPEN、OPI等)、周期引用(REF、REFX)、跨周期数据导入(#IMPORT)、最小变动价位查询(MINPRICE)、成交量获取(VOL)及高频行情数据引用(L2_BID/ASK系列)等多种实用功能,每个函数均附有用法说明与示例,便于开发者快速查阅调用。资源为单个doc文档,压缩包约309KB,体积精简、内容聚焦,适合文华财经麦语言模型开发人员、量化策略编写者及程序化交易爱好者作为参考手册使用。已有3599人浏览学习,是快速掌握麦语言函数用法的实用资料,文档内容编排清晰,便于日常开发中快速对照使用。
1. 麦语言函数手册:入门者缺的不是语法,而是一张按场景组织的函数地图
麦语言函数手册是期货、股票类行情软件里最常被翻的参考文档,它定义了指标公式怎么写、函数怎么调、信号怎么出。大多数新手都会抱着手册从头背到尾,但按字母背函数恰恰是最低效的姿势:手册里几百个函数,高频使用的只有四五十个。我做策略这几年的体会是,函数手册应该当积木箱用——取数类、计算类、信号类各拿几块,按场景拼装。这篇文章就把手册拆成三类函数、三条高频写法、一张参数表和五条血泪踩坑,新手能照着写出第一条可回测策略,熟手能对照坑位做一次查漏。
2. 麦语言函数手册先拆框架:取数、计算、信号三类函数决定你查手册的姿势
拿到手册先别急着往后翻。我习惯先做一次分类:取数类、计算类、信号类。手册里绝大多数条目都能归进这三类,分类的价值在于写公式本质上就是在回答三个问题——拿什么数据、怎么加工、什么时候触发。想清楚这个问题,再去手册里找对应函数,命中率会高很多。
2.1 取数函数:OPEN、CLOSE、REF、HHV 是策略的数据来源,N 参数方向别搞反
取数函数是最底层的一批,直接决定策略能看到什么数据。行情字段类函数最常见:开盘价、收盘价、最高价、最低价、成交量,在麦语言里分别写作 OPEN、CLOSE、HIGH、LOW、VOL,不带参数,取当前K线对应字段。这些字段看起来简单,但配合引用函数之后,才是策略的数据骨架。
引用类取数函数分两个方向:一个往过去取单点,一个往区间取极值。单点方向是 REF(X, N),取 N 根K线之前的 X 值,比如 REF(CLOSE, 1) 是上一根K线的收盘价,REF(VOL, 1) 是上一根K线的成交量,常用来做「放量」判断。区间方向是 HHV(X, N) 和 LLV(X, N),取最近 N 根K线内 X 的最大值和最小值。注意这两个函数的区间是包含当前K线的,这是手册里最容易看漏的一个细节。
// 麦语言示例:突破前20根K线最高点,且放量 HH20 := REF(HHV(HIGH, 20), 1); LEN := BARSCOUNT(CLOSE); BREAK := CLOSE > HH20 && LEN > 20; VOL_BIG := VOL > REF(VOL, 1) * 1.5;逻辑说明:HHV(HIGH, 20) 包含当前K线的最高价,如果直接拿 CLOSE 和它比较,当前收盘价永远不可能高于当前K线的最高价,条件永远不成立。所以先算 20 根K线的最高价,再用 REF 把它整体移到昨天,当前收盘价和「昨天的前20根最高价」比较,才是真正的突破。LEN 用 BARSCOUNT 取有效K线总数,确保图表头部数据量不足 20 根时不参与判断。VOL_BIG 是放量条件,VOL 是当前成交量,REF(VOL, 1) 是上一根成交量,乘以 1.5 表示量能放大五成。参数说明:20 是突破周期,1.5 是放量倍数,都值得做成参数来回测不同取值。
除了价格和成交量,取数类还有 BARSLAST(COND) 取「最近一次条件成立到现在经过的K线数」,以及部分终端提供的 HHVBARS、LLVBARS 取「区间极值出现在哪一根K线」。这类函数取的不是价格而是时间位置,做回撤定位和历史高低点标记时非常好用。
2.2 计算函数:MA、EMA、SMA 的差异直接决定策略信号密度
计算类是手册里最大的一块,均线族是典型。MA(X, N) 是简单算术平均,N 根K线的 X 值相加除以 N,每一根权重相同,滞后性最大。EMA(X, N) 是指数加权平均,越靠近当前的K线权重越大,反应更快,滞后更小。SMA(X, N, M) 是带平滑系数的平均,第三参数 M 控制平滑程度,M 越小对最近价格变化越敏感。
| 函数 | 计算方式 | 滞后性 | 典型用途 |
|---|---|---|---|
| MA(X, N) | 算术平均,权重相同 | 最大 | 趋势判断、布林带中轨 |
| EMA(X, N) | 指数加权,近端权重大 | 中等 | MACD 快慢线 |
| SMA(X, N, M) | 平滑系数 M 控制 | 由 M 决定 | RSI、自定义平滑序列 |
三者用在同一个策略里,信号密度差别很大。MA 对价格突变反应慢,信号少但稳定;EMA 对最近价格更敏感,信号多但容易被来回打脸。写策略前先想清楚自己要「少而稳」还是「多而快」,再选均线类型,而不是随手抄一个 MA 了事。
除了均线族,计算类常用的还有:SUM(X, N) 区间求和、STD(X, N) 区间标准差、AVEDEV(X, N) 区间平均绝对偏差、MAX(A, B) 和 MIN(A, B)、ABS(X) 取绝对值、ROUND(X) 四舍五入。布林带就是 MA 加两个 STD 的组合,MACD 的 DIF 就是 EMA(CLOSE, 12) 减 EMA(CLOSE, 26)。RSI 的写法更能体现 SMA 第三参数的用法:
// 麦语言示例:RSI 指标的典型写法 LC := REF(CLOSE, 1); UP := SMA(MAX(CLOSE - LC, 0), 14, 1); DOWN := SMA(ABS(CLOSE - LC), 14, 1); RSI := UP / DOWN * 100;逻辑说明:LC 取上一根收盘价,CLOSE - LC 就是本根K线的涨跌额,MAX(..., 0) 把下跌部分截成 0,所以 UP 平滑的是「上涨能量」,ABS 取绝对值后 DOWN 平滑的是「波动总量」,两者比值再乘 100 就是 RSI。SMA 第三个参数固定为 1,这是 RSI 公式的标准配置,改成其他值会得到完全不同的曲线形态。参数说明:14 是 RSI 的经典周期,也有人用 9 或 6,周期越短越灵敏。
2.3 信号函数:CROSS、COUNT、FILTER 组合出「什么时候动手」
第三类是信号判断函数,返回的不是数值而是条件。CROSS(A, B) 在 A 从下往上穿越 B 时返回真,就是金叉;CROSS(B, A) 对应死叉。COUNT(COND, N) 统计最近 N 根K线内条件成立了多少次。FILTER(COND, N) 在条件成立发出信号后,N 根K线之内不再重复触发,用来过滤连续信号。还有 IF(COND, A, B) 做条件取值,AND、OR、NOT 做条件拼接。
这几类函数组合起来,配合平台的信号字(常见的是 BK 买开、SK 卖开、SP 卖平、BP 买平这一组),就组成了可回测的策略模型块。注意信号字在不同终端上写法可能略有差异,以你用的软件自带手册为准。
// 麦语言示例:金叉确认后开多,死叉直接平多 MA5 := MA(CLOSE, 5); MA20 := MA(CLOSE, 20); GOLD := CROSS(MA5, MA20); CONFIRM := COUNT(GOLD, 3) >= 1; CONFIRM, BK; CROSS(MA20, MA5), SP;逻辑说明:前两行定义快慢均线,第三行生成金叉条件,第四行用 COUNT 确认最近 3 根K线内确实出现过金叉,第五行把确认后的信号接到 BK 上。为什么不用 GOLD 直接开仓?因为 CROSS 只在穿越那一根K线返回真,如果恰好那根K线的收盘价在盘中反复穿越,信号容易闪烁,COUNT 的确认机制能压掉一部分杂信号。第六行死叉直接 SP 平多。参数说明:3 是确认窗口,窗口越大信号越少但越滞后;BK 和 SP 之间的配对关系要严格对应,否则会出现重复开仓或者空仓平仓的报错。
3. 按策略场景查手册:三条高频写法从查函数到成稿
分类讲完,落到实战。这一章选三个最常见的场景:均线策略、震荡过滤、回撤统计。每个场景都按「需求描述 → 查手册找哪些函数 → 最小可跑写法 → 参数怎么改」的顺序走一遍。你以后写自己的策略,也可以照这个顺序拆。
3.1 均线金叉策略:CROSS + BK 的最小可回测写法
第一个场景是最多人上手的双均线。需求很明确:快线上穿慢线开多,快线下穿慢线平多。需要查的函数就是 MA 和 CROSS,策略本体三行就能跑:
// 双均线策略:5日上穿20日开多,下穿平多 MA5 := MA(CLOSE, 5); MA20 := MA(CLOSE, 20); CROSS(MA5, MA20), BK; CROSS(MA20, MA5), SP;逻辑说明:四行代码,含义分别是计算快线、计算慢线、金叉买开、死叉卖平。这是一个能直接丢进回测的最小策略。但实际用起来,你要做好连续亏损几次的准备。常见做法是给策略加趋势过滤:只在大周期均线向上时做多,比如要求 MA20 本身也在上行,用 MA20 > REF(MA20, 1) 表达。还可以加成交量过滤:金叉当天放量才开仓,用 VOL > REF(VOL, 1) * 1.5。
// 加了趋势过滤和量能过滤的双均线策略 MA5 := MA(CLOSE, 5); MA20 := MA(CLOSE, 20); TREND_UP := MA20 > REF(MA20, 1); VOL_BIG := VOL > REF(VOL, 1) * 1.5; GOLD := CROSS(MA5, MA20) && TREND_UP && VOL_BIG; GOLD, BK; CROSS(MA20, MA5), SP;逻辑说明:TREND_UP 判断慢线处于上行状态,VOL_BIG 判断放量,两个条件用 && 和 CROSS 拼在一起,金叉信号被过滤掉了大半,剩下的是趋势共振和量能确认都满足的开仓点。过滤条件加得越多,交易次数越少,单笔质量通常越高,但也可能错过行情,这是过滤器数量和收益之间需要反复权衡的地方。参数说明:5 和 20 是经典组合,改成 10 和 30 会减少交易次数、拉长持仓周期,改成 3 和 10 则更偏短线,具体取值建议放到参数优化里跑一遍再定,不要拍脑袋。
3.2 震荡行情过滤:FILTER 和 COUNT 的适用边界
第二个场景是震荡过滤。双均线策略在趋势行情里表现不错,但在来回震荡的行情里会连续金叉死叉,被反复打脸止损。手册里能救场的函数有两个:FILTER 和 COUNT,但它俩的过滤逻辑完全不同,用错场景等于没过滤。
FILTER(COND, N) 的思路是「信号发出后强制冷却 N 根K线」,期间不管条件再触发多少次都不响应。COUNT(COND, N) 的思路是「最近 N 根K线内条件至少成立 K 次才确认」,本质是信号次数投票。
// 用 FILTER 冷却连续信号,间隔10根K线 MA5 := MA(CLOSE, 5); MA20 := MA(CLOSE, 20); GOLD := CROSS(MA5, MA20); GOLD_FILTERED := FILTER(GOLD, 10); GOLD_FILTERED, BK;// 用 COUNT 做三次确认,减少单根K线闪烁 MA5 := MA(CLOSE, 5); MA20 := MA(CLOSE, 20); GOLD := CLOSE > MA5 && MA5 > MA20; CONFIRM := COUNT(GOLD, 5) >= 3; CONFIRM, BK;逻辑说明:第一段 FILTER 的语义是「金叉出现后 10 根K线之内不再理会新的金叉」,适合信号密集、需要强制冷却的场景,缺点是会错过冷却期内的真突破。第二段 COUNT 的语义是「最近 5 根K线里至少有 3 根满足多头排列条件才开仓」,它过滤的不是冷却而是「偶然性」,适合在震荡里做确认。注意第二段的触发条件从 CROSS 换成了状态条件,因为 CROSS 只有一根K线为真,COUNT 它没有意义;改成 CLOSE > MA5 && MA5 > MA20 这种持续成立的条件,COUNT 才能统计出有效票数。参数说明:FILTER 的 10 是冷却周期,震荡越剧烈冷却期要越长;COUNT 的 5 和 3 是投票窗口和阈值,阈值越高越不容易触发,但也会把启动初期的行情直接过滤掉。
3.3 最大回撤统计:HHV、HHVBARS、BARSLAST 的配合
第三个场景不写开平仓信号,而是做风控统计。想知道策略历史上最大回撤是多少、回撤从哪根K线开始,需要用到极值类和时间定位类函数。这里的核心思路是:先找一段时间内的最高收盘价,用当前价格和它的差值算回撤幅度,再定位这个最高点出现在哪。
// 统计60根K线内的最大回撤和起点位置 PEAK := HHV(CLOSE, 60); DD := (PEAK - CLOSE) / PEAK * 100; MAXDD := HHV(DD, 60); STARTBAR := HHVBARS(CLOSE, 60);逻辑说明:PEAK 是最近 60 根K线的最高收盘价,DD 是当前价格相对这个高点的回撤百分比,MAXDD 是这 60 根K线里最深的一次回撤,STARTBAR 用 HHVBARS 返回峰值所在位置距离当前K线的根数。如果手册里没有 HHVBARS,可以用近似写法替代:BARSLAST(CLOSE = HHV(CLOSE, 60)),含义是「最近一次收盘价等于区间最高价的那根K线距离现在多远」。两种写法都行,区别是归类不同——HHVBARS 是专用函数,BARSLAST 是通用条件定位函数,理解这个替换逻辑后,遇到手册里缺函数时就不慌了。参数说明:60 是统计窗口,窗口越大覆盖的历史越长,但对近期变化的敏感度越低;如果要统计策略全生命周期的最大回撤,直接把窗口换成 BARSCOUNT(CLOSE) 即可。
4. 高频函数参数清单:一张表带走多数策略的调参起点
函数手册翻多了你会发现,高频函数就那么几十个,参数规律也高度相似。这一章把最常用的一批函数整理成一张速查表,并说清楚参数 N 的取值逻辑。
4.1 麦语言常用函数参数速查表
| 函数 | 原型示例 | 核心参数 | 典型取值 | 用途 |
|---|---|---|---|---|
| MA | MA(X, N) | N 计算周期 | 5 / 10 / 20 / 60 | 简单均值 |
| EMA | EMA(X, N) | N 计算周期 | 12 / 26 | 指数均值,MACD 用 |
| SMA | SMA(X, N, M) | N 周期 + M 平滑 | RSI 固定 M=1 | 带平滑系数均值 |
| REF | REF(X, N) | N 往前移几根 | 1 | 引用历史值 |
| HHV / LLV | HHV(X, N) | N 区间长度 | 20 / 55 | 区间极值 |
| CROSS | CROSS(A, B) | 无 | 无 | 上穿下穿判断 |
| COUNT | COUNT(COND, N) | N 统计窗口 | 3 / 5 / 10 | 条件次数统计 |
| FILTER | FILTER(COND, N) | N 冷却根数 | 5 / 10 / 20 | 信号去重 |
| BARSLAST | BARSLAST(COND) | 条件表达式 | 无 | 距上次满足的K线数 |
| BARSCOUNT | BARSCOUNT(X) | 无 | 无 | 有效K线总数 |
| STD | STD(X, N) | N 计算周期 | 20 | 标准差,布林带用 |
| SUM | SUM(X, N) | N 求和周期 | 5 / 20 | 区间累加 |
| ABS | ABS(X) | 无 | 无 | 取绝对值 |
| IF | IF(COND, A, B) | 条件 + 两个返回值 | 无 | 条件取值 |
| MAX / MIN | MAX(A, B) | 两个比较值 | 无 | 取较大 / 较小 |
这张表覆盖了我在实际策略里九成以上的函数需求。表格里每一行对应手册里一个完整条目,真实手册里每个函数还会带上返回值类型和示例,但那些信息在写策略时很少被反复查看,真正需要记牢的是「函数名 + 核心参数方向 + 典型取值」。
4.2 参数 N 的取值逻辑:固定周期、自适应周期和过拟合警告
参数 N 的取值直接决定策略性格。固定周期是最常见的做法,数字本身来自经验和品种特性:5 和 10 偏短线,20 和 30 偏波段,60 偏趋势。但固定周期有个问题:行情波动快慢会变,一个在震荡市里表现好的周期,放到单边市里可能完全失灵。所以现在不少策略开始用自适应周期,思路是用 ATR(平均真实波幅)来衡量当前波动率,N 随波动率缩放。比如把固定 20 改成基于 ATR 的动态值,波动大的时候周期自动缩短,波动小的时候周期自动拉长,让指标跟着市场节奏走。
// 自适应周期均线示例:用ATR调整周期长度 ATR20 := MA(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1)), ABS(LOW - REF(CLOSE, 1))), 20); N_DYNAMIC := MAX(5, ROUND(20 * ATR20 / REF(ATR20, 20))); MA_DYNAMIC := MA(CLOSE, N_DYNAMIC);逻辑说明:N_DYNAMIC 的逻辑是:当前 ATR 与 20 根前的 ATR 比较,波动放大时 N 自动增大、波动收窄时 N 自动减小,再用 MAX 保底不让周期低于 5。MA_DYNAMIC 就是套用动态周期的均线。参数说明:20 是 ATR 参考周期,5 是最小周期下限,这两个值都要单独测试。需要提示的是,自适应参数不是万能的,它引入的 N 本身是计算出来的,如果 ATR 算法里含有未来数据,自适应就变成了自欺欺人,用之前务必检查每一步是否只用当前及之前的数据。
最后说过拟合。同一段历史行情上,反复调参调到曲线完美,是策略开发里最典型的玄学误判。你把 N 从 20 改成 22,回测收益提升明显,不一定是参数变好了,可能只是恰好踩中了这段行情的噪声。常见做法是分两段验证:一段用来调参,另一段完全不动,等参数定死后跑一遍;如果第二段表现明显变差,说明参数过拟合了,这个 N 的取值不可用。
5. 麦语言函数使用避坑指南:5 个让回测翻车的常见坑
这一章写的是我自己和身边做策略的朋友都踩过的坑。每一条按「现象 → 原因 → 解决」写,可以直接拿去做排查清单。
5.1 坑一::=和:混用,图上多出一堆不该出现的线
现象:指标图上密密麻麻多出十几条曲线,跟预期完全不符,有些看似是中间量的线也画出来了。
原因:麦语言里:=是赋值给中间变量,只参与计算不输出;:是声明一条指标线,会直接画到图上。混用的最常见结果是:把应该用:=的中间变量写成了:,中间量全部变成了输出线。
解决:定一个死规矩——策略内部所有中间计算一律用:=,只有确定要输出到图上的指标线才用:。如果你写的是策略而不是指标,干脆全部用:=,需要看哪条线就临时把它的赋值改成输出,看完再改回来。
5.2 坑二:REF(X, 0) 不是延迟,写错整条策略信号对不上
现象:想表达「上一根K线满足某条件」,写 REF(COND, 0),结果回测里信号位置错乱,或者时报错。
原因:REF 的 N 参数语义是「往前数第 N 根」,N=0 就是当前这根,没有任何延迟意义。新手常把 0 理解成「默认往前一根」,这是把其他语言的索引习惯带进来了。
解决:REF(CLOSE, 1) 才是上一根。凡是写 REF 的地方,先默念一遍「N 等于 1 才是昨天」,再检查一遍会不会写成 0。排查时直接在图上输出 REF(CLOSE, 1) 和 REF(CLOSE, 0) 两条线,一眼就能看出差异。
5.3 坑三:混入未来函数,回测收益曲线是假的
现象:回测曲线非常漂亮,胜率高得吓人,但拿到模拟盘上跑完全不是那么回事,信号在历史图上看起来像是「提前知道答案」。
原因:策略里用了引用未来数据的函数。手册里有一类函数,比如 BACKSET、ZIG、PEAK、TROUGH 这类「从后往前标记」的函数,它们在历史K线上计算时会用到当前K线之后的数据,回测软件默认允许这种计算,所以历史信号位置非常完美,实盘中这些未来数据不存在,策略自然失效。
解决:查手册时看到「未来函数」「回填」「回溯标记」这类描述的条目,一律不进策略。验证方法用平台的信号回放或分段复盘功能,逐根K线往前推,某根K线上的信号必须只能由这根及之前的K线算出来;一旦发现信号会在K线收盘后才确认,就说明有未来数据混入。
5.4 坑四:序列长度不足,函数在K线头部返回空值
现象:MA(CLOSE, 60) 在图表最前面 59 根K线上没有值,COUNT 条件在头部统计出来的次数明显偏少,甚至策略在历史起始段完全不交易。
原因:所有需要 N 根数据才能计算的函数,在数据不足 N 根时没有合法结果。图表加载的历史K线数量越少,这个「空白区」占比越大。
解决:在条件里加上数据量守卫,用 BARSCOUNT(CLOSE) >= N 作为前提条件。比如前面章节里的BREAK := CLOSE > HH20 && LEN > 20,LEN 就是守卫。更稳妥的写法是把所有边界判断统一放在策略开头,数据量不够直接跳过信号,避免后面每个条件都带着一段空值计算。
5.5 坑五:浮点精度导致信号闪烁,等于号比价不靠谱
现象:价格明明差不多,CROSS(MA5, MA20) 却在一两根K线内来回触发又失效,或者两个计算结果理论上相等,用=判断却永远不成立。
原因:浮点运算存在精度误差。均线、标准差这类经过多次加减乘除的结果,很少能精确等于某个值,直接用=比较两个计算结果,等于在赌二进制精度恰好对齐,大概率赌不中。
解决:比较两个计算值是否相等,改用容差判断,比如ABS(A - B) < 0.0001;判断上穿下穿,不要用等号,改用差值符号变化:(MA5 - MA20) > 0 && REF(MA5, 1) - REF(MA20, 1) <= 0,这样表达的是「前一根还在下方、当前这根已经在上方」,语义和 CROSS 一致但更可控。信号闪烁还可能来自盘中未收线的K线,处理方式是在信号条件里加上对当前K线状态的判断,或者用 FILTER 冷却,二选一即可。
6. 从查手册到搭自己的函数仓库:三个进阶习惯
手册用熟了,下一步是把它变成自己的东西。这里说三个我现在每天都在用的习惯,都不是什么高深技巧,但确实让写策略的效率和准确率上了一个台阶。
第一个习惯是封装常用逻辑。把「突破N周期高点」「放量」「均线多头排列」这类出现频率极高的判断,整理成自定义函数或模板。后续写新策略时直接调用,不用每次重新翻手册拼条件,也能保证同一段逻辑在多策略里保持一致,少引入复制粘贴带来的低级错误。
第二个习惯是信号验证。每次改完参数,不要只看回测曲线,用复盘功能逐根K线核对前三次信号的触发位置,确认信号确实是K线收盘后确认的,没有提前、没有闪烁。我现在写任何新函数,都会先单独输出到图上观察形态,确认理解无误再放进策略,这是被 REF 和 HHV 方向坑过两次之后养成的习惯。
第三个习惯是参数留档。维护一张参数与绩效对照表,把每次调整的 N 值、过滤条件、回测区间和结果基准都记录下来。否则你很容易在同一段历史上来回试同一组参数而不自知——你以为在优化,其实在反复验证同一个结论。表格记录之后,每次调整都清楚改了什么、为什么改、上一步结果是什么。
这三个习惯都属于「慢就是快」:第一个省的是重复劳动,第二个防的是黑匣子式的回测幻觉,第三个防的是调参过程中的记忆失真。回头想想,最贵的教训其实不是函数本身用错了,而是用错了还不知道错在哪——所以从翻手册的第一天起,就要保持对每个函数输出形态的好奇心,先看它在图上的样子,再相信它在策略里的结果。希望帮到你。
本文还有配套的精品资源,点击获取