简介:麦语言函数手册是文华财经推出的程序化函数库参考文档,面向使用文华平台进行量化策略开发的交易者与编程初学者,帮助其快速查阅函数用法、理解模型构建逻辑。手册系统梳理了历史数据引用、引用函数、导入函数、价格函数、成交量函数及日内高频数据引用等模块,涵盖 AVPRICE、SETTLE、CLOSE、REF、REFX、#IMPORT、MINPRICE、VOL 以及 L2_BID1 至 L2_ASK5 等常用函数,并配有用法说明与示例,便于对照编写与调试策略。资源包内含 1 个 doc 文档,大小约 309KB,结构紧凑,适合作为案头速查工具。目前已有 3599 人学习下载,说明其在程序化交易群体中具有较高参考价值。读者可借此掌握麦语言“小语法、大函数”的积木式编程思路,理解复杂算法封装与金融统计函数库的配合方式,从而提升策略开发效率与代码质量。
1. 麦语言函数手册:从积木式编程到策略落地的实战拆解
很多人第一次打开麦语言函数手册,翻两页就关掉了——函数列表太长,每个函数都像字典词条,看不出哪些是真正高频使用的。但如果你正在做程序化策略开发,尤其是国内期货市场的模型编写,这份手册其实是一张被低估的“积木清单”。麦语言的核心思路是“小语法、大函数”:语法规则极少,复杂算法全部封装进函数里,你只需要像搭积木一样把函数拼起来。手册覆盖了历史数据引用、日内高频数据、金融统计、逻辑判断、绘图、头寸管理等十几个类别,从CLOSE这种基础行情变量到L2_BID1这类 Level-2 盘口函数都有。它适合两类人:一是刚接触程序化交易、需要快速查函数用法的开发者;二是已经写过一些模型、但想系统梳理函数边界和参数细节的老手。下面我按实际写策略的顺序,把这份手册拆成能直接抄作业的流程。
2. 行情数据函数:从 K 线变量到跨周期引用的落地写法
2.1 基础行情变量与简写规则
麦语言里最基础的一层是行情数据函数,它们直接返回当前 K 线的开高低收、成交量、持仓量等数值。手册里明确写了简写形式:CLOSE可写C,HIGH可写H,LOW可写L,OPEN可写O,VOL可写V。这些简写在写复杂公式时能显著缩短代码长度,但要注意可读性——我一般只在局部表达式里用简写,跨多行的逻辑还是写全称,方便后面排查。
AVPRICE和SETTLE是两个容易混淆的函数。AVPRICE取均价,在盘后对国内三个期货交易所指结算价;SETTLE取结算价,但只有在日线周期盘后才能取得当日结算价。手册里特别说明:如果用在小于日线的周期上,比如 5 分钟 K 线,每根 K 线返回的是这根 K 线当日开盘到该 K 线为止的结算价(均价);用在大于等于日线的周期上,返回当根 K 线结束时间所在日的结算价。这个差异直接影响跨周期策略的数值对齐,写多周期模型时必须先确认当前周期。
OPI取持仓量,MINPRICE返回某品种的最小变动价位。MINPRICE的用法是MINPRICE(CODE),CODE 可以是文华码或交易代码。手册里给了一个注意点:某些合约(如橡胶指数)查不到最小变动价位,返回 0。这意味着如果你用MINPRICE做下单价格对齐,遇到返回 0 的合约要加一层兜底判断,否则可能算出无效价格。
// 基础行情变量示例:判断当前 K 线是否为阳线且成交量放大 IS_UP := CLOSE > OPEN; VOL_AMP := VOL > REF(VOL, 1) * 1.5; DRAWTEXT(IS_UP AND VOL_AMP, HIGH, '放量阳');上面这段代码里,CLOSE > OPEN判断收阳,REF(VOL,1)引用前一根 K 线的成交量,VOL > REF(VOL,1)*1.5表示当前成交量是前一根的 1.5 倍以上。DRAWTEXT在满足条件时于最高价位置标注文字。参数1.5是放量倍数,实盘里可以根据品种波动特性调整,一般 1.2 到 2.0 之间。
2.2 REF 与 REFX:周期引用和未来函数的边界
REF(X,N)引用 X 在 N 个周期前的值,这是最常用的引用函数。比如REF(CLOSE,5)就是 5 个周期前的收盘价。REFX(X,N)引用 N 个周期后的数据,手册里直接标注了“未来函数”。未来函数在历史回测中会引用到当前 K 线之后的数据,导致回测收益虚高,实盘无法复现。手册对REFX的警告很明确:运算量很大,占用大量 CPU 资源,导致行情刷新变慢,请谨慎使用。
我自己的习惯是:除非做纯研究性的形态识别,否则策略里一律不碰REFX。如果你在别人的模型里看到REFX、ZIGZAG、PEAK、TROUGH、BACKSET这些函数,基本可以判断这个模型的历史回测曲线有水分。手册里把这些函数都标了“未来函数”,这个标注本身就是筛选信号。
2.3 #IMPORT 跨品种跨周期引用
#IMPORT是手册里少数带#前缀的指令,用法是#IMPORT [CODE, PERIOD, FORMULA] AS VAR。它引用 CODE 对应合约在 PERIOD 周期下指标 FORMULA 的数据,VAR 是定义的变量名。手册给了五条限制:只能引用.FML/.XFML文件;只能引用 MIN1、MIN3、MIN5、MIN15、MIN30、HOUR1、DAY、WEEK、MONTH 这些周期;只能短周期引用长周期;被引用的指标中不能存在引用;如果不写文华码,默认引用当前合约。
这五条限制里,“只能短周期引用长周期”最容易踩坑。比如你在 5 分钟周期上想引用日线级别的均线,这是允许的;反过来在日线周期上引用 5 分钟数据,手册不支持。另外“被引用的指标中不能存在引用”意味着不能嵌套引用,A 引用 B、B 又引用 C 的链式结构会失败。
// 跨周期引用示例:在 5 分钟周期上引用日线 MA20 #IMPORT [CODE, DAY, MA(CLOSE, 20)] AS DAY_MA20; CROSS(CLOSE, DAY_MA20), BPK;这段代码在 5 分钟 K 线上引用日线周期的 20 日均线,当收盘价上穿该均线时买开。CODE不写时默认当前合约,DAY指定日线周期,MA(CLOSE,20)是被引用的指标公式。注意被引用的指标必须保存为.FML或.XFML文件,且不能包含其他引用。
3. 金融统计与逻辑判断函数:策略信号的核心积木
3.1 统计函数:MA、EMA、HHV、LLV 及变体
金融统计函数是策略信号计算的主力。MA(X,N)求简单移动平均,EMA(X,N)求指数加权移动平均,EMA2(X,N)求线性加权平均。手册给出了 EMA 的计算方法:EMA(X,N)=[2*X+(N-1)*EMA(X,(N-1))]/(N+1)。这个公式说明 EMA 对最新数据赋予更高权重,比 MA 反应更快,但震荡行情里也更容易产生假信号。
HHV(X,N)求 N 周期内最高值,LLV(X,N)求最低值。如果 N=0,则从本地数据第一个有效周期开始算起。HHVBARS(X,N)和LLVBARS(X,N)分别返回最高值位置和最低值位置到当前的周期数。这四个函数经常组合使用,比如计算当前价格在 N 周期区间内的相对位置。
STD(X,N)求标准差,STDP(X,N)求总体标准差。手册里用一组收盘价数据做了完整演算:数列为 2766、2805、2814、2886、2885,算术平均值 2831.20,平均绝对偏差AVEDEV为 43.44,数据偏差平方和DEVSQ为 11130.80,总体样本方差VARP为 2226.16,样本方差VAR为 2782.70。手册特别指出样本方差是总体方差的 N/(N-1) 倍,当 N 够大时两者趋于相等。这个细节在写布林带类指标时很重要——用STD还是STDP会导致带宽略有差异。
// 布林带简化实现:中轨 MA20,上下轨加减 2 倍标准差 MID := MA(CLOSE, 20); UPPER := MID + 2 * STD(CLOSE, 20); LOWER := MID - 2 * STD(CLOSE, 20); DRAWLINE(CLOSE > UPPER, HIGH, CLOSE > UPPER, UPPER, COLORRED);这里MID是 20 周期均线,STD(CLOSE,20)是 20 周期标准差,乘以 2 得到上下轨。参数 20 和 2 是经典布林带设置,短线可以改成 10 和 1.5,长线可以改成 60 和 2.5。DRAWLINE在收盘价突破上轨时从最高价到上轨画红线,用于视觉标注。
3.2 逻辑判断函数:CROSS、FILTER、EXIST、EVERY
CROSS(X,Y)表示 X 上穿 Y,返回 1 或 0。CROSS2(A,B)表示 A 从下方向上穿过 B 两次时返回 1。LONGCROSS(A,B,N)要求 A 在前 N 个周期内都小于 B,本周期上穿 B 才返回 1。这三个函数覆盖了从简单上穿到持续压制后突破的不同逻辑。
FILTER(COND,N)过滤连续出现的信号,当 COND 成立时将其后 N 周期内的数据置为 0。手册给了一个重要限制:不能与BKPRICE、BARSBK、SKPRICE、BARSSK一起使用。这意味着如果你用FILTER过滤信号,就不能同时用这些头寸函数来获取开仓价格和持仓周期,需要换一种写法。
EXIST(COND,N)判断 N 周期内是否有满足条件的情况发生,EVERY(COND,N)判断过去 N 周期内是否一直满足条件,LAST(COND,N1,N2)判断过去 N1 到 N2 周期内是否一直满足条件。这三个函数在写过滤条件时非常实用,比如“过去 5 根 K 线都是阳线”可以用EVERY(CLOSE>OPEN,5)。
VALUEWHEN(COND,DATA)当条件 COND 满足时取当时的 DATA 值,否则取得前面一个满足条件 COND 的值。这个函数在记录信号发生时的价格时很有用,比如记录上次金叉时的收盘价。
// 信号过滤示例:金叉后 5 周期内不重复触发 GOLDEN := CROSS(MA(CLOSE,5), MA(CLOSE,20)); FILTERED := FILTER(GOLDEN, 5); FILTERED, BPK;GOLDEN是 5 日均线上穿 20 日均线的金叉信号,FILTER(GOLDEN,5)表示金叉后 5 个周期内不再重复触发。参数 5 是过滤窗口,实盘里可以根据信号频率调整,高频策略用 2 到 3,低频策略用 10 以上。
3.3 数理统计函数在策略中的实际用法
SLOPE(X,N)求线性回归斜率,FORCAST(X,N)求线性回归预测值。这两个函数在写趋势强度判断时很有用。比如SLOPE(CLOSE,5)为正且绝对值较大,说明短期趋势向上且斜率陡峭。
ZIGZAG(X,P,N)之字转向,当 X 变化量超过 P 时转向。N 取 1 时 P 为百分比数,N 取 0 时 P 为价位差值绝对值。手册标注了未来函数。PEAK、TROUGH、PEAKBARS、TROUGHBARS都是基于 ZIGZAG 的波峰波谷函数,同样标注未来函数。这些函数在识别历史形态时有用,但不能用于实盘信号触发。
SAR(N,Step,Max)抛物转向,N 为计算周期,Step 为步长,Max 为极值。手册说明这是系统函数,计算步骤后台自动完成。例:SAR(17,0.03,0.3)表示 17 周期抛物转向,步长 3%,极限值 30%。SAR 在趋势行情里能跟踪止损,但震荡行情里会频繁翻转。
4. 高频数据与头寸函数:Level-2 盘口和交易指令的实战细节
4.1 L2 盘口函数:买卖五档与主动成交
手册里 L2 系列函数覆盖了买卖五档价格和数量、主动买卖成交量、大单统计等。L2_BID1到L2_BID5取买一到买五价,L2_ASK1到L2_ASK5取卖一到卖五价。在 K 线图时返回当前秒周期最后时刻的值,在 Tick 图时返回该笔 Tick 时刻的值。L2_BIDVOL1到L2_BIDVOL5和L2_ASKVOL1到L2_ASKVOL5分别取对应档位的数量。
L2_BIDVOL和L2_ASKVOL取秒周期主动买的成交量和主动卖的成交量。L2_BIDBIGCOUNT和L2_ASKBIGCOUNT取主动买和主动卖的大单成交次数。L2_BIDBIGTOTVOL和L2_ASKBIGTOTVOL取主动买卖的大单成交量。大单阈值通过L2_SETBIGVOL(nVol)设置,成交手数大于 nVol 的为大单。
CALVOLPRICELIST初始化盘口大单价格表,主要在BIDBIGVOLPRICE和ASKBIGVOLPRICE前使用。BIDBIGVOLPRICE返回 Tick 图中该笔 Tick 盘口中多头满足大单条件的与最新价的最近价格,ASKBIGVOLPRICE返回空头对应的价格。手册特别注明:模型中需调用一次CALVOLPRICELIST函数。
// L2 大单统计示例:统计主动买大单次数和成交量 L2_SETBIGVOL(10); // 设置 10 手以上为大单 BIG_BUY_COUNT := L2_BIDBIGCOUNT; BIG_BUY_VOL := L2_BIDBIGTOTVOL; DRAWTEXT(BIG_BUY_COUNT > 3, LOW, '大单买');L2_SETBIGVOL(10)把大单阈值设为 10 手,L2_BIDBIGCOUNT返回当前秒周期主动买的大单成交次数,L2_BIDBIGTOTVOL返回对应成交量。DRAWTEXT在大单次数超过 3 次时标注。阈值 10 手适合流动性较好的品种,小品种可以降到 5 手。
4.2 头寸函数:信号过滤与持仓状态判断
AUTOFILTER对模型的所有信号按照先买后卖、先开后平的顺序过滤。规则是:连续的同方向指令只有第一个有效;交易指令必须配对出现,前面有买开则后面只允许卖平。手册建议如果使用自动过滤函数,就不要在代码中再使用其他语句进行过滤。
BARSBK返回上一次买开信号距离当前 K 线的 K 线数,BARSSK返回上一次卖开信号距离当前 K 线的 K 线数。ISLASTBK、ISLASTSK、ISLASTBP、ISLASTSP、ISLASTBPK、ISLASTSPK分别判断上一个交易信号是否是 BK、SK、BP、SP、BPK、SPK。这些函数在写加仓、减仓逻辑时是基础工具。
FEE返回当前合约的手续费,手册注明不能与未来函数同时使用,如ISLASTBAR、EMA2、ZIGZAG、BACKSET、PEAK、PEAKBARS、TROUGH、TROUGHBARS、REFX等。这个限制意味着如果你在模型里用了FEE做成本计算,就不能同时用这些未来函数,否则会冲突。
ISLASTBUYLONG、ISLASTSELLSHORT、ISLASTEXITLONG、ISLASTEXITSHORT判断上一个信号是否是 BUYLONG、SELLSHORT、EXITLONG、EXITSHORT。这些函数在写多空双向策略时用来判断当前持仓方向。
// 头寸管理示例:上次买开后超过 10 周期且盈利则平仓 BARS_SINCE_BK := BARSBK; PROFIT := CLOSE - BKPRICE; BARS_SINCE_BK > 10 AND PROFIT > 0, BP;BARSBK返回上次买开距今的 K 线数,BKPRICE是买开价格,CLOSE - BKPRICE计算浮动盈亏。条件为持仓超过 10 周期且盈利时平仓。参数 10 是持仓周期阈值,可以根据策略平均持仓时间调整。
4.3 绘图函数与颜色常数
手册里的绘图函数包括DRAWLINE、DRAWTEXT、DRAWSL、DRAWNUMBER、FILLRGN、POLYLINE、PARTLINE、STICKLINE、VERTLINE等。DRAWLINE(C1,P1,C2,P2,COLOR)当 C1 和 C2 均满足时从 P1 画直线到 P2。DRAWTEXT(C,P,TEXT)当 C 满足时在 P 位置写文字。DRAWSL画斜线,参数包括条件、起点、斜率、长度、延长方式和颜色。
颜色常数包括COLORRED、COLORGREEN、COLORBLUE、COLORMAGENTA、COLORYELLOW、COLORLIGHTGREY、COLORLIGHTRED、COLORLIGHTGREEN、COLORLIGHTBLUE、COLORBLACK、COLORWHITE、COLORCYAN。RGB(R,G,B)自定义颜色,R、G、B 范围 0 到 255。
// 绘图示例:均线多头排列时填充区域 MA5 := MA(CLOSE, 5); MA10 := MA(CLOSE, 10); FILLRGN(MA5 > MA10, MA5, MA10, COLORRED); DRAWTEXT(CROSS(MA5, MA10), LOW, '金叉');FILLRGN在 MA5 大于 MA10 时用红色填充两线之间的区域,DRAWTEXT在金叉位置标注文字。COLORRED是颜色常数,也可以换成RGB(255,0,0)。
5. 避坑与排查:麦语言函数手册里没写透的五个坑
5.1 未来函数导致回测虚高
现象:模型历史回测收益曲线非常漂亮,但实盘信号总是慢半拍,成交价格和回测差异很大。原因:模型里用了REFX、ZIGZAG、PEAK、TROUGH、BACKSET等未来函数,这些函数在历史 K 线上引用了当前 K 线之后的数据。解决:逐一检查模型里是否包含手册标注“未来函数”的函数,如果有,要么替换成非未来函数版本,要么接受实盘无法复现的事实。我一般会在模型开头加一行注释,列出所有用到的函数,逐个对照手册标注。
5.2 #IMPORT 引用失败
现象:#IMPORT语句报错或返回空值。原因:可能是被引用的指标文件不是.FML/.XFML格式,或者引用了不支持的周期,或者被引用的指标里又包含了引用,或者写了长周期引用短周期。解决:先确认被引用指标已保存为正确格式,再检查周期是否在 MIN1、MIN3、MIN5、MIN15、MIN30、HOUR1、DAY、WEEK、MONTH 列表内,然后确认引用方向是短引用长,最后检查被引用指标内部没有嵌套引用。
5.3 FILTER 与头寸函数冲突
现象:用了FILTER过滤信号后,BKPRICE、BARSBK、SKPRICE、BARSSK返回异常值或报错。原因:手册明确写了FILTER不能与这些头寸函数一起使用。解决:如果必须过滤信号又要获取头寸信息,可以改用AUTOFILTER做整体过滤,或者用VALUEWHEN手动记录信号发生时的价格和周期数。
5.4 L2 函数在非 Level-2 环境返回空值
现象:模型里用了L2_BID1、L2_ASK1等函数,但在普通行情环境下返回 0 或空值。原因:L2 系列函数依赖 Level-2 行情数据,普通行情只有一档买卖价,没有五档和逐笔成交。解决:在模型里加一层判断,比如ISLASTBAR或行情类型判断,非 L2 环境下跳过 L2 相关逻辑。另外CALVOLPRICELIST必须在BIDBIGVOLPRICE和ASKBIGVOLPRICE之前调用一次,否则大单价格返回无效值。
5.5 MINPRICE 返回 0 导致下单价格无效
现象:用MINPRICE计算最小变动价位后做价格对齐,某些合约返回 0,导致计算出的下单价格不合理。原因:手册注明某些合约(如橡胶指数)查不到最小变动价位,返回 0。解决:在使用MINPRICE的地方加兜底判断,如果返回 0 则用一个默认值替代,比如该品种常见的最小变动价位,或者直接用CLOSE做价格对齐。
6. 进阶技巧:用 VALUEWHEN 和 ISLASTBAR 做信号确认与回测验证
6.1 VALUEWHEN 记录信号发生时的价格
VALUEWHEN(COND,DATA)在条件满足时取当时的 DATA 值,否则取前面一个满足条件的值。这个函数在记录信号发生时的价格时非常实用。比如你想记录每次金叉时的收盘价,并在后续 K 线上引用这个价格,可以用VALUEWHEN(CROSS(MA5,MA10), CLOSE)。和REF不同,VALUEWHEN不需要知道信号发生在几个周期前,它会自动向前查找最近一次满足条件的值。
// 记录金叉时的收盘价,并在价格回落至该价位时提示 GOLDEN := CROSS(MA(CLOSE,5), MA(CLOSE,10)); GOLDEN_PRICE := VALUEWHEN(GOLDEN, CLOSE); DRAWTEXT(CLOSE < GOLDEN_PRICE AND GOLDEN_PRICE > 0, LOW, '回踩金叉价');GOLDEN是金叉信号,VALUEWHEN(GOLDEN,CLOSE)记录金叉发生时的收盘价,后续 K 线如果收盘价低于这个价格就标注提示。注意GOLDEN_PRICE > 0是兜底判断,避免在第一个金叉出现前引用到无效值。
6.2 ISLASTBAR 做最后一根 K 线的特殊处理
ISLASTBAR判断当前周期是否为最后一根 K 线。这个函数在回测和实盘切换时很有用。比如你只想在最后一根 K 线上输出调试信息,或者只想在最后一根 K 线上执行某些计算,可以用ISLASTBAR做条件判断。但手册在FEE函数的说明里提到ISLASTBAR不能与FEE同时使用,因为ISLASTBAR在某些实现里被视为未来函数——它引用了“当前是最后一根 K 线”这个未来信息。
// 只在最后一根 K 线输出持仓状态 ISLASTBAR, DRAWTEXT(ISLASTBAR, CLOSE, '当前持仓: ' + NUMTOSTR(BARSBK, 0));这段代码只在最后一根 K 线上标注持仓周期数。NUMTOSTR把数值转成字符串,BARSBK返回上次买开距今的 K 线数。注意这种写法只适合调试,不适合作为交易信号。
6.3 回测验证的检查清单
在把模型投入实盘之前,我习惯走一遍检查清单。第一,搜索模型里是否包含REFX、ZIGZAG、PEAK、TROUGH、BACKSET、PEAKBARS、TROUGHBARS,如果有,确认是否接受未来函数带来的回测偏差。第二,检查#IMPORT语句的周期和文件格式是否符合手册限制。第三,确认FILTER没有和BKPRICE、BARSBK、SKPRICE、BARSSK混用。第四,如果用了 L2 函数,确认行情环境支持 Level-2 数据。第五,用MINPRICE的地方加兜底判断。第六,把模型分别在 5 分钟、15 分钟、日线三个周期上跑一遍,观察信号数量和回测曲线是否合理。
| 检查项 | 常见问题 | 处理方式 |
|---|---|---|
| 未来函数 | REFX/ZIGZAG/PEAK 等 | 替换或接受回测偏差 |
| #IMPORT | 周期不支持、文件格式错误 | 对照手册五条限制逐项检查 |
| FILTER | 与头寸函数冲突 | 改用 AUTOFILTER 或 VALUEWHEN |
| L2 函数 | 非 Level-2 环境返回空值 | 加行情类型判断 |
| MINPRICE | 部分合约返回 0 | 加兜底默认值 |
这张表是我每次上线新模型前必过的流程。看起来简单,但每一条都对应过真实的翻车经历。从那以后我每次写完模型,都会先把这张表走一遍,再去看回测曲线。希望帮到你。
本文还有配套的精品资源,点击获取