资讯动态

麦语言函数手册实战指南:从检索到策略调试

发布时间:2026/10/15 21:23:20 来源:尧图企业网站定制
简介这份中文手册围绕文华财经麦语言程序化函数库编写适合期货量化投资者、WH系列软件用户以及刚接触策略编写的开发者参考。麦语言采用积木式编程理念将复杂算法封装为函数配合金融统计库可支持较复杂的交易逻辑。包内为doc文档一份共1个文件压缩包约309KB内容精炼便于查阅。目前已有3599人浏览学习。手册覆盖历史数据、跨周期与跨品种引用、盘口高频行情等常用函数例如CLOSE/HIGH/LOW、REF/REFX、#IMPORT、MINPRICE、VOL以及L2_BID1至L2_ASK5等一系列逐档买卖报价函数并提供具体用法与示例。读者可借此快速掌握麦语言的基础语法与函数调用方式提高策略编写与调试效率。1. 麦语言函数手册到底在解决什么问题很多人打开麦语言函数手册就蒙函数几百个每个都像英文单词缩写但真到写策略的时候一个都想不起来。我见过不少做了几年手工交易的人拿着手册照样写不出一个能稳定跑完回测的模型。问题不在识字而在于没搞清这本手册不是一个语法字典它描述的是这个语言在K线、分时和数据序列上全部可调用的能力。它回答的问题是“我想表达一个交易想法该用哪个词”。如果你没有交易模型这东西手册就是废纸如果你正想把规则变成代码这本手册就是你的对照表。读完这篇你能从“翻手册”变成“查手册”并且知道哪些坑是手册里不会写的。2. 麦语言函数手册的检索逻辑从命名到函数家族2.1 前缀命名看不懂函数时先看首字母打开麦语言函数手册第一感觉往往不是内容多而是乱。其实它的编排有很强的规律绝大多数函数的名字就是功能英文单词的缩写。MA是Moving AverageREF是ReferenceHHV是Highest High ValueLLV是Lowest Low ValueCROSS就是交叉COUNT就是计数。你不需要把几百个函数全背下来先看首字母就能猜到它属于哪一类。比如你正在写均线策略看到MA、EMA、SMA心里就有数了你需要在历史K线之间挪位置找带REF的函数你要统计某个条件在最近N根里发生多少次COUNT就在那等着。我一般会先写一个小脚本把不熟悉的函数拉出来跑一遍而不是只看文字解释MA10:MA(CLOSE,10); // 最近10根收盘价的简单平均 HHV_MA10:HHV(MA10,5); // 最近5根 MA10 的最高值 REF_HHV:REF(HHV_MA10,1); // 再把上述最高值向前挪一根K线这段代码的逻辑是先算出10周期均线再取这条均线最近5根K线的最高值最后整体向历史方向移动一根。HHV的第二个参数是窗口宽度REF的第二个参数是位移量。对照手册你会发现绝大多数函数都是“数据在前、周期或位移在后”的规律。记住这个习惯你查手册时就不用来回翻参数表了。命名还有一个隐藏好处当你想实现“最近N天最高价突破前高”这种需求直接想到HHV和REF的组合根本不需要翻到“高级函数”里去碰运气。函数手册不是给你背的是按规律检索的。如果某个函数的前缀你完全不认识那大概率是特殊场景函数比如画图、字符串处理、跨周期调用先跳过不耽误主流程。2.2 高频函数三张表行情、运算、信号我把麦语言函数手册里的常用内容压缩成三张表覆盖新手写策略时九成以上的需求。这三张表分别是行情引用类、数值运算类、信号统计类。类别常用函数参数格式一句话用途行情引用CLOSE / OPEN / HIGH / LOW / VOL无取当前K线收盘、开盘、最高、最低、成交量行情引用REF(X, N)数据X位移N取N根K线前X的值行情引用HHV(X, N) / LLV(X, N)数据X窗口N取最近N根X的最高值/最低值数值运算MA(X, N)数据X周期N简单移动平均数值运算EMA(X, N)数据X周期N指数移动平均数值运算SMA(X, N, M)数据X周期N权重M带平滑权重的均线数值运算SUM(X, N)数据X窗口N最近N根X合计数值运算STD(X, N)数据X窗口N标准差信号统计CROSS(A, B)两条线A和BA从下方穿越B成立信号统计COUNT(条件, N)条件表达式窗口N最近N根里条件成立次数信号统计BARSLAST(条件)条件表达式条件上次成立到今天隔了几根K线信号统计VALUEWHEN(条件, X)条件数据X条件最近一次成立时X的值查表的顺序应该是先判断我要做的是“取数”“算数”还是“判断信号”再对应到类别。例如你想写“过去10天最高价突破上穿”那第一优先级是HHV第二是REF第三是CROSS。如果某函数的参数是“条件”那这个位置可以直接写比较式或逻辑组合比如CLOSEOPEN AND VOL10000不需要提前定义一个变量再传进去。这类组合是麦语言函数手册里最容易理解的部分但很多人倒在“手册里没有告诉你边界”。例如VOL在部分数据源里可能包含盘中实时值和回测里的历史值口径不同OPI持仓量类似。使用时要先确认你用的K线周期和复权方式不要让数据源差异变成策略假象。2.3 手册里查不到的执行约定序列、常数和副作用函数手册通常只给接口不给执行过程这是新手把它当黑匣子用的根本原因。麦语言的处理单位是“一整段K线序列”绝大多数函数返回的不是单个数字而是一条和K线对齐的序列。你在一个赋值句里写下MA(CLOSE,5)计算机会从第一根K线算到最后一根每一根都得到一个均值。这个“逐根扫描”的机制决定了绝大多数逻辑不能只看最后一根而要看所有历史截面。这里有个容易忽略的约定用:赋值不会画线用:赋值会在主图上画线。很多新手在手册里找到“绘图函数”就结束阅读结果漏掉了这个基础差异导致临时计算变量把图搞得全是线。正确习惯是中间计算一律用:只有想输出的结果才用:。另一个约定是函数副作用。DRAWICON、DRAWTEXT这类函数会在图上画图标和文字它们不影响信号和回测结果但会让图面拥挤也会在多次回测时拖慢运行。交易指令函数则有更明显的副作用BK、SK不返回值而是触发虚拟下单。若手册里某函数有“输出到主图/副图”“回测中生效”等标注读手册时要特别留意这些不是普通计算函数。还有一类查不到的内容是执行顺序。连续赋值是从上到下依次计算的但跨周期引用、循环语句和条件分支在不同版本里行为可能有差异。遇到同一段逻辑在不同窗口期结果不同先不要怀疑函数写错把赋值顺序调换一下观察差异再用“模型测试报告”的日志位置去定位。这一条是经验手册里不会写。3. 用函数手册拼出第一张可运行指标双均线与画图3.1 从手册到K线图双均线最小写法我建议每个拿到麦语言函数手册的人先不要写交易模型先写一个能加载到行情图上的指标。因为指标是纯计算没有委托逻辑能立刻验证函数手册里的函数到底怎么用。最简双均线只要两行MA5:MA(CLOSE,5) COLORRED; // 输出5周期均线红色 MA20:MA(CLOSE,20) COLORYELLOW; // 输出20周期均线黄色注意这里用的是单个冒号:表示把结果画到主图。CLOSE是整个K线序列MA括号里第二个参数5是周期。如果你把其中一行改成MA5:MA(CLOSE,5);编译不会报错但图上那条线会消失因为赋值不画线。跑通这个最小指标后再往里面加中间变量MA5:MA(CLOSE,5); // 计算5线但不画线 MA20:MA(CLOSE,20); // 计算20线但不画线 DIFF:MA5-MA20,COLORRED; // 把差值画出来这段代码在双均线基础上增加了一个中间变量DIFF。用:存中间值用:输出最终结果。这样做的好处是你可以在编译环境里随时查看DIFF的数值和曲线确认每个函数的返回值确实如手册所描述。参数说明MA的第一个参数“CLOSE”是行情序列第二个“N”是周期必须是正整数。你换成HIGH、LOW、VOL等都可以因为它们同样是K线序列但如果你传一个常数比如MA(5,5)它会返回一个常数序列这在少数函数组合里会导致后续统计函数结果异常。3.2 参数怎么选MA、EMA、SMA的分工手册里均线函数有三个MA、EMA、SMA。它们都带“周期”参数但行为差别很大。MA是简单算术平均每个数据权重相同EMA是最新数据有更高权重的指数平均SMA带第三个参数M用来控制新数据对结果的修正力度。如果你只是想验证一套策略逻辑用MA就够了如果你想让信号反应更快EMA更合适如果你希望曲线在快和稳之间取个平衡SMA值得实验。下面这张对比代码可以直接放进编译环境MA5:MA(CLOSE,5); // 简单平均 EMA5:EMA(CLOSE,5); // 指数平均 SMA5:SMA(CLOSE,5,2); // 平滑平均 A:MA5; B:EMA5; C:SMA5;三条线画出来会发现EMA5比MA5更贴近价格SMA5的参数M决定其靠近MA5还是EMA5。这里的参数2是平滑权重你改成1再改成4曲线会明显变化。手册只会写“M为权重值”不会告诉你哪一种适合你的品种。常见做法是打开行情图把三条线叠在一起用肉眼或者用“数值显示”面板对比你关心的转折点。还有一组容易被忽略的参数在REF和HHV之间REF(X,N)的N是向前位移HHV(X,N)的N是窗口长度。两者的N方向完全不同。如果你写HHV(HIGH,5)结果是最近5根K线的最高值如果你写REF(HIGH,5)结果是5根K线之前的最高价。它们经常一起出现例如“五根K线前的5周期最高价”就是REF(HHV(HIGH,5),5)。这部分务必对着手册逐项核对否则策略的入场点会整体偏移。3.3 画图函数和提示函数让每个函数“看得见”我写指标一定会顺手加画图函数因为它能把函数返回结果直接映射成视觉信号比盯着数值高效得多。麦语言里最常用的是DRAWICON和DRAWTEXT以及STICKLINE柱状线。DIFF:EMA(CLOSE,12)-EMA(CLOSE,26); // 快线 DEA:EMA(DIFF,9); // 慢线 MACD:2*(DIFF-DEA); // 柱值 STICKLINE(MACD0,MACD,0,2,0),COLORRED; // 红柱 STICKLINE(MACD0,MACD,0,2,0),COLORGREEN; // 绿柱 DRAWICON(CROSS(DIFF,DEA),DEA,1); // 金叉画图标 DRAWTEXT(CROSS(DEA,DIFF),DEA,死叉); // 死叉写文字这段代码是MACD柱状图的经典写法。STICKLINE第一个参数是“是否画柱”的条件第二、三个参数是柱体上下边界MACD大于0时从0到MACD画红柱小于0时画绿柱。第4个参数是柱宽第5个参数0表示实心1表示空心。DRAWICON第一个参数是触发条件第二个参数是图标定位在哪个数值位置第三个参数是图标编号编号对应的图形在手册的“绘图函数”章节有一张对照表。DRAWTEXT的第三个参数是字符串用单引号包裹。它不会影响计算只是文字提示。我习惯把信号用DRAWTEXT标出来因为它比图标更直白能显示“金叉”“死叉”这样的字调试时可以快速数一下一个区间里到底出现了几次信号。不要在一个模型里堆太多DRAWICON否则图标重叠之后你会看出乱码一样的图形排查起来更慢。4. 把函数手册用进交易模型信号、委托与频率控制4.1 信号函数与指令函数别把两个概念混着查指标只是第一步要用麦语言写真正的交易模型必须分清“信号函数”和“指令函数”。信号函数负责判断条件例如CROSS、COUNT、BARSLAST指令函数负责发出委托动作最常见的是BK、SK、BP、SP。BK代表买入开仓SK代表卖出开仓SP代表卖出平多仓BP代表买入平空仓。手册通常会把这两组内容放在不同章节但新手容易在“交易函数”里找条件结果对着一个不返回值的指令函数不知道怎么传参数。最小交易模型长这样DIFF:EMA(CLOSE,12)-EMA(CLOSE,26); // 快线 DEA:EMA(DIFF,9); // 慢线 CROSS(DIFF,DEA),BK; // 金叉买入开仓 CROSS(DEA,DIFF),SK; // 死叉卖出开仓这里的CROSS(DIFF,DEA),BK;是“当前K线金叉成立时发出买入开仓信号”CROSS(DEA,DIFF),SK;是“死叉成立时发出卖出开仓信号”。SK在这里既可以是开空仓也可以理解成反手信号。麦语言的模型逻辑是逐根K线扫描信号成立的那根K线产生指令并在后续K线按价格设置成交。注意BK和SK作为指令函数也可以被其他函数引用。例如BARSLAST(BK)返回上一次买入开仓信号到当前的K线根数这在前面的章节里出现过。这一点很关键指令函数在麦语言里会留下“历史信号”信号统计函数可以拿它当普通条件用。很多人不理解为什么一个“动作函数”还能当条件其实它就是“BK成立”这个布尔状态的别名。回测时你还要关注委托价格设置。函数手册只负责“信号在哪个K线成立”至于信号成交在开盘价、收盘价还是下根K线开盘价是交易模型设置决定的。常见做法是把成交价设成“下一个K线开盘价”避免用收盘价成交带来的未来函数嫌疑。血泪经验是信号确认和成交时间错配是回测收益看起来高但实盘完全对不上的头号原因。4.2 止损止盈用BARSLAST和VALUEWHEN做状态跟踪止损止盈不能每次重新算要记忆上一次开仓时的价格最顺手的是VALUEWHEN和BARSLAST两个函数。VALUEWHEN(条件, X) 的用法是条件最近一次成立时取当时的X值。我常用它记录开仓价开仓价:VALUEWHEN(BK,CLOSE); // 最近一次BK信号时的收盘价 止损价:开仓价-20*MINDIFF; // 开仓价向下20个最小变动价位 止损:CLOSE止损价; // 最新收盘价跌破止损 止损,SP; // 发出平多仓信号这里MINDIFF是行情最近的最小变动价位用开仓价减去20个最小变动单位作为固定止损。如果你做的是空头方向反过来写开空价:VALUEWHEN(SK,CLOSE); // 最近一次SK信号时的收盘价 止损价:开空价20*MINDIFF; // 开仓价向上20个最小变动价位 止损:CLOSE止损价; // 最新收盘价升破止损 止损,BP; // 发出平空仓信号参数说明20是“回调多少个最小价位”直接决定止损宽度需要根据品种和周期调整。把20改成5会更敏感改成60会更宽松。VALUEWHEN返回的是序列从信号成立那根K线开始这个值一直保持到下一次信号成立所以你在后续任意一根K线上读它拿到的都是“最近一次开仓价”而不是当前价。另一个组合是BARSLAST加REF。BARSLAST(条件) 返回“条件上一次成立距离现在多少根K线”配合REF可以取到开仓那根K线的最高价或最低价开仓距离:BARSLAST(BK); // 距上次BK信号隔了几根K线 最近高点:REF(HIGH,开仓距离); // 取开仓那根K线的最高价注意REF(HIGH,开仓距离)取的是开仓那根K线的最高价而不是“最近N根最高价”。如果你想跟踪开仓后的最大浮盈需要用HHV结合BARSLAST计算这属于进阶写法这里不展开。但记住一个原则用BARSLAST定位事件发生的位置再用REF取那个位置的历史数据。止损触发条件我一般用收盘价而不是最低价。因为LOW是K线最低价盘中瞬时打到你止损价又收回来用最低价做条件会让回测里出现大量假止损。除非你本来就打算“只要盘中触碰就止损”那应该考虑更低周期模型而不是在日线或小时线上用LOW触发。4.3 用COUNT和BARSLAST控制交易频率交易模型里最烦人的问题是信号在短时间内重复发生导致开仓次数失控。麦语言手册提供了两个天然适合做频率控制的函数COUNT和BARSLAST。COUNT(条件,N) 统计最近N根K线里条件成立过几次BARSLAST(条件) 告诉你条件最近一次成立距离现在有多远。最简单的是“距离上次开仓不足10根K线不再开仓”金叉:CROSS(DIFF,DEA); // 金叉条件 上次开仓:BARSLAST(BK); // 距上次买入开仓的K线根数 允许:上次开仓10; // 间隔够10根才允许开仓 开仓:金叉 AND 允许; // 综合条件 开仓,BK; // 满足则买入开仓这里的10是“最小间隔周期数”。如果你交易的是15分钟K线10根就是两个半小时如果是日线10根就是两周。参数没有统一标准通常根据策略持仓周期设置。把10改成0这个限制就取消。如果你想限制“最近9根K线内最多只开一次仓”可以用COUNT。注意这里有一个新手必踩的坑COUNT会把当前K线的BK信号也统计进去。当前这根K线你正要发BKCOUNT(BK,9) 的结果已经包含了你这个信号所以限制条件往往会把自己拦住。正确的写法是先把当前K线信号去掉近9次:COUNT(BK,9)-BK; // 去掉当前K线的BK信号 允许:近9次1; // 之前9根没有开仓信号才允许 开仓:金叉 AND 允许; // 综合条件 开仓,BK; // 买入开仓减掉BK这一行是为了让当前K线的信号不参与历史统计。这是我在调试频率限制时踩过的坑加上限制条件后模型反而一根信号都没有排查到最后发现是COUNT把自己算进去了。手册里只会写COUNT统计“条件成立的次数”不会提醒你当前K线处理。这类边界条件建议每次写完都搭一个只有信号和标记的小模型验证计数结果。5. 麦语言函数手册常见问题排查五个翻车现场5.1 金叉写成大小比较信号连续成立现象策略在回测里持仓时间特别长只有第一次金叉产生开仓之后所有该平仓的位置都没触发。翻看信号图发现信号从某一根K线开始持续为真。原因有人把 CROSS(DIFF,DEA) 写成了 DIFFDEA。CROSS只表示“由下穿到上”的这一瞬间DIFFDEA 则表示当前状态只要DIFF还在DEA上方它就是真的。交易模型判断的是“条件成立则执行”于是指令信号会一直成立。解决凡是“金叉”“死叉”一律用CROSS函数。如果要用DIFFDEA实现“上方持续运行”的逻辑必须把它放在开仓之外的条件里例如作为持仓过滤。检查顺序先看是否用了CROSS再看是否需要配合REF做位移。5.2 COUNT把自己算进去频控失效现象用COUNT(BK,N)1做开仓频率限制结果一个信号都没出来或者永远开不了第二笔仓。原因当前K线满足BK时COUNT(BK,N) 已经把当前这根K线的成立次数算进去了。你拿它判断“之前没有开仓”实际它等于1导致条件恒为假。解决写成COUNT(BK,N)-BK先把当前K线信号剔除再做比较。如果模型里用了中间变量也可以先用昨天计数:REF(COUNT(BK,N),1)但REF会额外引入K线位移建议新手优先用减法写法。5.3 用最低价触发止损假止损成串现象回测报告里止损单特别多但逐笔检查行情时发现很多次价格只是短暂触碰止损线就拉了回来。原因把CLOSE止损价写成了LOW止损价。最低价是K线极端值盘中瞬时穿越不代表收盘确认尤其在小时线和分钟线上高低点经常刺穿后收回。解决默认用CLOSE判断止损。如果你确实想做盘中触碰止损需要把模型周期降到触发逻辑能覆盖的级别并用成交设置里的“限价单”配合不要拿一个大周期K线里的LOW硬做盘中行为。5.4 除零或空值污染整条线现象图上一段曲线从某根K线开始变成“无效值”后续所有依赖它的函数输出消失回测日志里出现告警。原因某个分母表达式计算结果为0或空值例如用统计次数做分母而前几根K线确实没有信号。麦语言对无效数的传播很“诚实”一个函数返回无效数使用它的上一级函数也跟着无效。解决给分母加保护分母:COUNT(BK,20); // 统计次数 安全分母:IF(分母0,1,分母); // 分母为0时改成1 结果:某统计值/安全分母; // 避免除零IF(条件, 条件为真时的值, 条件为假时的值) 在这里起到防除零作用。注意IF的三个参数会同时计算所以如果第二个参数本身也会引发无效值仍然要先把内部表达式保护起来。5.5 REF位移和HHV窗口边界搞混现象想要“最近5根最高价”写出来却在图上偏了几根想引用上一根的最高价结果引到了未来。原因HHV(HIGH,5) 取的是包括当前K线在内的最近5根最大HIGHREF(HIGH,1) 取的是上一根K线的HIGH。两者方向含义完全不同。如果写成REF(HHV(HIGH,5),0)那就等价于HHV本身没做任何位移。解决先明确你需要的边界。要引用“上一根K线往前数5根的最高价”写REF(HHV(HIGH,5),1)要引用“上一根K线自身的最高价”写REF(HIGH,1)。不要把窗口N和位移N当成同一个东西。调试时用DRAWTEXT把数值打印出来对照手册的参数说明逐位确认。以上五个翻车现场是我在跑麦语言策略时反复遇到的共性问题。你不需要背下所有函数参数但最好把这几类边界条件当成默认检查项每写一个函数就问一次它返回序列还是常数包含当前K线吗参数里哪个是窗口、哪个是位移6. 拿函数手册当调试道具信号验证和结果留存6.1 用DRAWTEXT做一个信号指示灯每次写完新模型我都会先抽出核心条件在图上用提示函数做一个“信号灯”。这样做的目的不是好看而是快速判断信号数量、出现位置是否和手工盘感一致。示例DIFF:EMA(CLOSE,12)-EMA(CLOSE,26); // 快线 DEA:EMA(DIFF,9); // 慢线 金叉:CROSS(DIFF,DEA); // 金叉条件 DRAWICON(金叉,LOW-10,1); // 金叉位置画图标 DRAWTEXT(金叉,LOW-10,金); // 金叉位置写文字金叉成立时图标和文字会同时出现在K线下方。跑一段历史区间数一数标记数量再对照行情肉眼回看比直接看资金曲线发现问题的速度快得多。6.2 用VALUEWHEN留存每次信号的开仓价信号标记确认后我会再画一条“持仓收益率”曲线开仓价:VALUEWHEN(金叉,CLOSE); // 最近一次金叉时的收盘价 持仓收益:CLOSE/开仓价-1; // 按当前价计算浮动收益率 收益曲线:持仓收益,COLORRED; // 输出收益率曲线这里VALUEWHEN的两个参数分别是条件和数据它会在金叉成立的那根K线记下当时的收盘价后续一直沿用这个值直到下一个金叉出现。算出的持仓收益是一条围绕0轴波动的曲线如果策略逻辑稳定它应该有来有回如果它变成一根陡峭直线通常意味着信号太少、单次盈亏过大或者开仓价取值有问题。这个习惯帮我避免了不少“回测美好、实盘翻车”的尴尬。我最早拿到麦语言函数手册是从头开始背函数名后来发现最该背的不是名字而是每个函数返回的是序列还是常数、是条件还是数值。每次写新模型先给信号画一个灯再去做参数调整最后才写交易细节。这个顺序已经成为我固定的调试习惯希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑