简介:本资源是文华财经官方麦语言函数手册的完整整理版,面向量化交易初学者、程序化策略开发者及期货/证券技术分析人员,解决麦语言函数调用不熟、参数理解不清、高频数据引用困难等核心问题。手册系统涵盖历史价格引用(CLOSE/HIGH/LOW等简写支持)、周期回溯(REF/REFX)、跨品种指标导入(#IMPORT)、最小变动价位查询(MINPRICE)、成交量统计(VOL)及L2级逐笔买卖盘口数据(L2_BID1–L2_ASK5等共15个高频函数),并附详细语法说明与典型用例。资源为单文件Word文档(.doc),体积精炼仅309KB,便于快速查阅与离线学习。目前已有3601人下载学习,内容源自2004年上线、经数十万用户验证的成熟平台,突出积木式编程理念与‘小语法、大函数’设计思想,是掌握国内使用最广的程序化模型开发工具不可或缺的权威参考。
1. 麦语言函数手册:不是语法书,是期货程序化交易的“积木箱”和“信号黑匣子”
你写完一个双均线金叉策略,发现回测曲线漂亮,实盘却总在关键位置滑点、跳空、信号滞后——不是模型逻辑错了,而是你没摸清麦语言里那几十个“看似简单、实则咬人”的函数边界。麦语言函数手册,不是教你怎么写CROSS(MA(C,5),MA(C,20))的入门指南,它是国内数十万期货交易员每天调用、调试、踩坑、再重写的实战工具箱。它把金融工程里最硬核的统计计算(比如ZIGZAG的转向判定、SAR的极值收敛)、最敏感的行情时序(REFX的未来函数陷阱、L2_BIDVOL的秒级主动成交识别)、最易被忽略的合约细节(MINPRICE('RB2410')返回 0 是因为没加载该合约)全封装进一个个带参数的函数名里。它适合三类人:刚从 Python 转来、被BACKSET和VALUEWHEN绕晕的新手;想把同策略迁移到文华平台、却卡在#IMPORT周期对齐的老手;还有那些在深夜盯盘时突然发现ISLASTBK没触发、翻遍文档才意识到AUTOFILTER和NOFILTER冲突的实战派。这不是理论堆砌,这是你下一笔开仓前,必须确认自己没漏掉的第 7 个参数、第 3 个周期偏移、第 1 个数据加载前提。
2. 函数分类与底层逻辑:为什么麦语言坚持“小语法、大函数”?
麦语言不提供for循环、不支持自定义类、甚至没有原生字典结构——但它用函数组合实现了比通用语言更贴近交易直觉的表达力。这种设计不是妥协,而是针对期货高频场景的精准取舍:K 线数据天然按时间序列组织,交易信号天然依赖历史状态回溯,风控动作天然绑定头寸生命周期。函数即原子操作,每个函数解决一个不可再分的金融语义单元。理解这点,才能避开“用SUM(VOL,10)算成交量却忘了VOL在 Tick 图中是逐笔累加、在 K 线图中是周期汇总”的典型误用。
2.1 历史数据引用:REF不是“取昨天”,而是“取 N 根 K 线前的快照”
REF(X,N)表面看是取历史值,但它的行为完全由当前图表周期决定。例如,在 5 分钟 K 线图上运行REF(CLOSE,1),返回的是上一根 5 分钟 K 线的收盘价;若切换到日线图,同一行代码返回的是前一天的日线收盘价。更关键的是,REF对数据源有强依赖:如果本地数据只加载了最近 30 天,而你写REF(CLOSE,50),结果恒为 0,不会报错也不会警告。
// 正确用法:先确保数据长度足够 IF (BARPOS > 100) THEN MA20 := MA(CLOSE, 20); REF_MA20 := REF(MA20, 5); // 取 5 根 K 线前的 20 日均线值 END IF;提示:
BARPOS返回当前 K 线在图表中的绝对位置(从 1 开始),不是时间戳。它能帮你规避“数据不足导致 REF 返回 0”的静默失败。实际项目中,我习惯在所有含REF的计算前加IF BARPOS > N+10 THEN ... END IF,多留 10 根缓冲,避免开盘前几根 K 线计算异常。
2.2 未来函数:REFX和ZIGZAG是“信号放大器”,也是“回测幻觉制造机”
麦语言明确标注『未来函数』的函数(如REFX,BACKSET,ZIGZAG,PEAK)本质是基于完整序列做全局优化的算法。REFX(CLOSE,5)不是预测,而是直接读取未来第 5 根 K 线的CLOSE值;ZIGZAG(HIGH,10,1)则需扫描整段HIGH序列,找出所有价格波动超 10%的转折点,再反向标记。这导致两个致命问题:第一,实盘中无法获取未来数据,所有含未来函数的策略在实盘必然失效;第二,回测时因使用全部历史数据,信号出现时间比真实场景早得多,造成“完美回测、实盘崩溃”的经典幻觉。
// 危险示范:含未来函数的策略片段(禁止实盘!) ZIG := ZIGZAG(HIGH, 5, 1); // 5%之字转向 PEAK_VAL := PEAK(HIGH, 5, 1, 1); // 上一个波峰价 IF (HIGH == PEAK_VAL) THEN BPK; // 在波峰处开多——但波峰是回测时算出来的,实盘根本不知道 END IF;注意:文华系统对含未来函数的公式会自动禁用“信号提示”功能(即不显示买卖箭头),但不会阻止你编译通过。务必在公式编辑器右下角检查黄色感叹号图标——只要出现,就代表存在未来函数,该公式仅限研究,不可用于实盘模型。
2.3 L2 高频数据函数:L2_BID1到L2_ASKVOL5不是“行情快照”,而是“主动成交意图探测器”
L2_BID1看似只是取买一价,但它在 Tick 图和 K 线图下行为完全不同:Tick 图中返回该笔成交发生时刻的买一价;K 线图中返回该 K 线最后一秒的买一价。更重要的是,这一系列函数(L2_BIDVOL,L2_ASKVOL,L2_BKBIGCOUNT)的核心价值在于区分“被动挂单”和“主动吃单”。例如L2_BIDVOL返回的是当前秒内所有以卖一价成交、且方向为买入的成交量总和,它直接反映多头主动进攻的强度,而非盘口静态挂单量。这正是高频策略(如冰山单探测、大单跟随)的底层数据源。
// 实用技巧:用 L2_BIDVOL 和 L2_ASKVOL 构建“主动买卖比” BID_VOL := L2_BIDVOL; ASK_VOL := L2_ASKVOL; IF (BID_VOL > 0 AND ASK_VOL > 0) THEN BUY_RATIO := BID_VOL / (BID_VOL + ASK_VOL); // 主动买占比 SELL_RATIO := ASK_VOL / (BID_VOL + ASK_VOL); // 主动卖占比 IF (BUY_RATIO > 0.7) THEN // 主动买占比超 70%,触发轻仓试多 BK(1); END IF; END IF;提示:L2 函数要求行情软件开启 Level2 行情权限,且合约必须支持逐笔委托。若调用
L2_BID1返回 0 或无效值,先检查:① 当前合约是否在文华支持的 L2 合约列表中;② 是否已订阅该合约的 Level2 行情;③ 图表周期是否为TICK或SEC1(秒线),其他周期(如MIN1)下 L2 函数可能返回空值。
3. 数据加载与跨周期引用:#IMPORT的四大铁律与三个必填参数
#IMPORT是麦语言实现“多周期协同分析”的核心机制,但它不像 Python 的pandas.read_csv那样宽容。它强制要求:被引用指标必须已存在于目标合约的指定周期图表中,且该指标本身不能含未来函数。很多新手卡在#IMPORT ['rb2410', 'DAY', 'MACD'] AS D_MACD编译失败,不是语法错,而是rb2410的日线图上根本没加载过MACD指标。
3.1#IMPORT的完整语法解析与安全写法
标准语法为:#IMPORT [CODE, PERIOD, FORMULA] AS VAR,其中:
CODE:文华码(如'rb2410')或空(默认当前合约);PERIOD:严格限定为MIN1,MIN3,MIN5,MIN15,MIN30,HOUR1,DAY,WEEK,MONTH(注意无SEC1);FORMULA:必须是已在目标周期图表中加载的指标名称,且不能带括号和参数(如MA(5)错误,MA正确);VAR:自定义变量名,后续代码中通过此名访问导入数据。
// 安全写法:先确认目标图表存在,再导入 // 假设当前图表为 rb2410 的 5 分钟图,需引用其日线 MACD #IMPORT ['rb2410', 'DAY', 'MACD'] AS D_MACD; // 导入日线 MACD 指标 // D_MACD.DIF, D_MACD.DEA, D_MACD.MACD 均可直接使用 IF (D_MACD.DIF > D_MACD.DEA AND REF(D_MACD.DIF,1) <= REF(D_MACD.DEA,1)) THEN // 日线 MACD 金叉,触发 5 分钟图开仓 BPK; END IF;注意:
#IMPORT加载的数据是静态快照,不是实时流。它在公式初始化时读取一次,之后不再更新。若需动态跟踪,必须配合REF或VALUEWHEN捕获变化点。
3.2 跨周期引用的周期对齐陷阱:MIN5引用DAY为何有时返回空?
麦语言规定“只能短周期引用长周期”,即MIN5图可#IMPORTDAY数据,但DAY图不能#IMPORTMIN5数据。然而,对齐逻辑极易出错:MIN5图的第 1 根 K 线(9:00-9:05)对应DAY图的哪一根?答案是当天的第一根日线。但#IMPORT在MIN5图中取DAY数据时,返回的是该MIN5K 线所属交易日的日线值。这意味着:在夜盘时段(如rb2410夜盘 21:00 开始),MIN5K 线属于次日,但DAY数据尚未生成,此时#IMPORT返回空值。
// 排查技巧:用 DATE 和 TIME 辅助判断数据有效性 CURRENT_DATE := DATE; // 返回 700101 格式日期 CURRENT_TIME := TIME; // 返回 0-235959 格式时间 // 若 CURRENT_TIME > 150000(下午 3 点)且 CURRENT_DATE 为今日,则日线数据应已就绪 IF (CURRENT_TIME > 150000 AND CURRENT_DATE == TODAY_DATE) THEN #IMPORT ['rb2410', 'DAY', 'MA'] AS D_MA; IF (D_MA.MA10 > 0) THEN // 检查是否非零(有效) // 安全使用 D_MA.MA10 END IF; END IF;3.3 避坑:#IMPORT常见问题与血泪排查记录
现象 → 原因 → 解决
现象 1:#IMPORT编译通过,但变量值始终为 0
→ 原因:目标合约(CODE)在指定周期(PERIOD)下未加载FORMULA指标,或该指标本身含未来函数(如ZIGZAG)被系统拒绝加载。
→ 解决:打开目标合约的指定周期图表 → 右键“指标” → 确认FORMULA已添加且无黄色感叹号 → 若含未来函数,改用MA,EMA等非未来函数替代。
现象 2:#IMPORT在模拟交易中正常,实盘时部分时段数据丢失
→ 原因:实盘行情延迟或断线,导致PERIOD周期数据未及时更新,#IMPORT读取到旧快照或空值。
→ 解决:在使用前增加有效性校验,如IF (D_MA.MA10 > 0 AND BARPOS > 10) THEN ... END IF,并设置AUTOFILTER防止无效信号触发。
现象 3:#IMPORT引用多个合约,编译报错“变量名重复”
→ 原因:#IMPORT的AS VAR名称在全局作用域唯一,若两次#IMPORT使用相同VAR(如都AS MA_DATA),后一次覆盖前一次。
→ 解决:为每个#IMPORT指定唯一变量名,如#IMPORT ['rb2410', 'DAY', 'MA'] AS RB_DAY_MA,#IMPORT ['cu2406', 'DAY', 'MA'] AS CU_DAY_MA。
现象 4:#IMPORT后计算CROSS(D_MA.DIF, D_MA.DEA)无信号
→ 原因:D_MA.DIF和D_MA.DEA是日线数据,在MIN5图中每 5 分钟才更新一次,但CROSS函数检测的是连续两根 K 线的值变化。若日线数据在MIN5图中连续多根 K 线值相同,CROSS永远不触发。
→ 解决:改用VALUEWHEN捕获首次变化,如LAST_CROSS := VALUEWHEN(CROSS(D_MA.DIF, D_MA.DEA), BARPOS); IF (BARPOS == LAST_CROSS) THEN BPK; END IF。
现象 5:#IMPORT的FORMULA名称大小写不匹配
→ 原因:麦语言对指标名大小写敏感,MACD和macd被视为不同指标。
→ 解决:在目标图表中右键指标 → “属性” → 查看准确名称(通常为全大写),严格按此拼写FORMULA。
4. 金融统计与数理函数:STD和SLOPE的精度陷阱与周期选择
麦语言的统计函数(STD,SLOPE,CORR)表面与 Excel 或 Python 的numpy.std一致,但底层实现针对金融时序做了特殊处理:它们默认忽略空值(0),且计算窗口严格按N个周期滚动,不因数据缺失而缩短。这导致一个隐蔽问题:当N=20时,若前 19 根 K 线CLOSE为 0(如新合约上市初期),STD(CLOSE,20)仍会用最后 1 个有效值计算标准差,结果失真。
4.1STD与STDP的本质区别:样本 vs 总体,以及为何实盘必须用STD
STD(X,N)计算N 个周期内的样本标准差,公式为sqrt(sum((x_i - mean)^2) / (N-1));STDP(X,N)计算总体标准差,公式为sqrt(sum((x_i - mean)^2) / N)。区别看似微小,但在交易中影响显著:STD因分母为N-1,对短期波动更敏感,更适合捕捉入场时机的波动率突变;STDP分母为N,数值更平滑,适合长期风险评估。实盘中,STD是波动率策略(如布林带)的标配,因其能更快响应价格加速。
// 布林带标准写法(使用 STD) MID := MA(CLOSE, 20); UPPER := MID + 2 * STD(CLOSE, 20); LOWER := MID - 2 * STD(CLOSE, 20); // 注意:此处 STD 必须与 MA 周期一致(20),否则上下轨失去统计意义提示:
STD对N的选择极其敏感。N=10时布林带窄,信号多但假突破多;N=60时布林带宽,信号少但胜率高。我一般用STD(CLOSE,20)作为基准,再叠加STD(CLOSE,5)观察短期脉冲——当短期 STD 突破长期 STD 的 1.5 倍时,预示波动率爆发,常伴随趋势启动。
4.2SLOPE的线性回归陷阱:SLOPE(CLOSE,5)不等于(C-REF(C,4))/4
SLOPE(X,N)计算的是X序列在N个周期内的线性回归斜率,即拟合直线y = a*x + b的系数a。它不是简单的首尾差值除以周期数。例如SLOPE(CLOSE,5)对序列[100,102,101,103,105]的计算,是求这 5 个点的最佳拟合直线斜率,结果约为1.2,而非(105-100)/4 = 1.25。这个差异在价格走缓时微小,但在加速行情中会被放大。
// 验证斜率有效性:结合 `STD` 过滤噪音 SLOPE_20 := SLOPE(CLOSE, 20); STD_20 := STD(CLOSE, 20); // 当斜率绝对值大于 0.5 倍标准差时,认为趋势有效 IF (ABS(SLOPE_20) > 0.5 * STD_20) THEN IF (SLOPE_20 > 0) THEN // 上升趋势确认,可加仓 BK(1); ELSE // 下降趋势确认,可开空 SK(1); END IF; END IF;注意:
SLOPE的N值不宜过小(<5)或过大(>60)。N=5时易受单根 K 线噪声干扰;N=60时滞后严重,错过趋势初期。我固定用SLOPE(CLOSE,20)作为趋势主信号,再用SLOPE(CLOSE,5)作过滤——仅当两者同向时才执行。
4.3CORR相关系数:跨品种对冲策略的“配对稳定性”探测器
CORR(X,Y,N)计算X与Y在N个周期内的皮尔逊相关系数,范围 [-1,1]。它是跨品种套利(如螺纹钢与铁矿石)的核心指标。但新手常犯错:直接CORR(CLOSE, 'I2409', 20)—— 麦语言不支持字符串合约名作为参数!正确做法是先用GETPRICE获取另一合约价格,再计算。
// 螺纹钢(rb2410)与铁矿石(I2409)相关性监控 RB_CLOSE := CLOSE; // 当前合约(rb2410)收盘价 I_CLOSE := GETPRICE('I2409'); // 获取 I2409 最新价 CORR_RB_I := CORR(RB_CLOSE, I_CLOSE, 20); // 20 日相关系数 // 当相关性跌破 0.7(历史均值下沿),暂停套利 IF (CORR_RB_I < 0.7) THEN // 暂停所有跨品种指令 NOFILTER; // 确保指令不被过滤 END IF;提示:
CORR对N的选择决定策略频率。N=5适合日内短线配对;N=60适合月度展期套利。我习惯用CORR(X,Y,20)为主信号,再用CORR(X,Y,5)辅助判断短期背离——当CORR_5 < 0.3而CORR_20 > 0.8时,大概率是短期扰动,可忽略。
5. 头寸管理与信号过滤:AUTOFILTER与NOFILTER的生死抉择
麦语言的头寸函数(BARSBK,ISLASTBP,FEE)和信号过滤机制(AUTOFILTER,NOFILTER,FILTER)共同构成实盘风控的“最后一道闸门”。它们不参与策略逻辑,却决定策略能否存活。一个常见误区是:把AUTOFILTER当成“自动去重”,却不知它强制执行“先买后卖、先开后平”的严格顺序,任何违反此顺序的指令(如连续BPK)都会被静默丢弃。
5.1AUTOFILTER的工作逻辑与适用场景
AUTOFILTER的规则是硬编码的:
- 指令配对:
BPK必须与SP配对,SPK必须与BP配对; - 顺序强制:
BPK后只能跟SP或BP(平今),不能跟第二个BPK; - 状态锁定:一旦发出
BPK,系统进入“持有多单”状态,直到SP执行完毕。
这意味着:AUTOFILTER适合单边趋势跟踪策略(如海龟法则),不适合网格交易或多空双向同时运行的策略。
// 正确使用 AUTOFILTER 的趋势策略 // 条件:20 日均线向上 + 收盘价突破 10 日高点 UP_TREND := SLOPE(MA(CLOSE,20),5) > 0; BREAK_HIGH := CLOSE > REF(HHV(HIGH,10),1); IF (UP_TREND AND BREAK_HIGH) THEN BPK; // 开多 END IF; // 平仓条件:收盘价跌破 10 日均线 IF (CLOSE < MA(CLOSE,10)) THEN SP; // 平多 END IF; AUTOFILTER; // 放在公式末尾,启用自动过滤注意:
AUTOFILTER必须放在公式最后一行,且不能与FILTER、NOFILTER共存。若公式中已写FILTER(CLOSE>OPEN,3),再加AUTOFILTER会导致编译错误。
5.2NOFILTER的真实用途:不是“关过滤”,而是“精确控制每一笔”
NOFILTER的字面意思是“不启用系统默认过滤”,但它真正的价值在于让策略完全掌控信号生命周期。例如,在网格策略中,你需要BPK后立即SPK(形成对冲),这在AUTOFILTER下会被禁止。NOFILTER解放了这种能力,但代价是:你必须手动处理所有信号冲突。
// 网格策略片段(必须用 NOFILTER) GRID_STEP := 5; // 网格间距(点数) BASE_PRICE := 3500; // 基准价 // 第一层网格:价格每跌 5 点,开一手多 IF (CLOSE <= BASE_PRICE - GRID_STEP * 1) THEN BPK(1); END IF; // 第二层网格:价格每涨 5 点,开一手空 IF (CLOSE >= BASE_PRICE + GRID_STEP * 1) THEN SPK(1); END IF; NOFILTER; // 关闭自动过滤,允许多空同时存在提示:用
NOFILTER时,务必自行加入头寸检查,避免无限开仓。例如在BPK前加IF (OPI == 0) THEN BPK(1); END IF,确保只有空仓时才开新仓。
5.3 避坑:头寸函数与信号过滤的五大翻车现场
现象 → 原因 → 解决
现象 1:BARSBK返回 0,但实际已开仓
→ 原因:BARSBK计算的是上一次BPK信号距离当前 K 线的根数,若当前 K 线就是BPK发出的那根,则BARSBK=0。新手误以为 0 代表“未开仓”。
→ 解决:用OPI > 0判断是否持有多单,BARSBK仅用于计算持仓时间。
现象 2:FEE返回 0,导致手续费计算为 0
→ 原因:FEE函数依赖用户在文华软件中为当前合约设置的手续费参数。若未设置或设置为 0,FEE返回 0。
→ 解决:在文华软件中,右键合约 → “合约资料” → “手续费” 手动输入(如rb2410的平今手续费为3元/手)。
现象 3:ISLASTBK在BPK后一根 K 线返回 0
→ 原因:ISLASTBK检测的是上一根 K 线是否发出了BK指令(非BPK)。BK是“买开”指令,BPK是“买开并平昨”指令,二者在系统中是不同信号。
→ 解决:若需检测BPK,用ISLASTBPK;检测BK,用ISLASTBK。
现象 4:AUTOFILTER下SP指令不执行
→ 原因:AUTOFILTER要求SP必须在BPK之后发出,且中间不能有BP(平今)指令干扰。若策略中写了BPK; BP; SP;,SP会被过滤。
→ 解决:删除中间的BP,或改用NOFILTER并手动管理。
现象 5:FILTER与AUTOFILTER共存导致编译失败
→ 原因:二者逻辑冲突,系统禁止同时存在。
→ 解决:二选一。趋势策略用AUTOFILTER;复杂策略(如多条件触发)用FILTER(COND,N)手动控制。
6. 实战验证与调试技巧:用DRAWTEXT和DRAWNUMBER把黑匣子变成透明仪表盘
麦语言没有断点调试,没有print日志,所有逻辑都在后台静默运行。要把策略“黑匣子”变成可观察的“仪表盘”,唯一可靠的方式是用绘图函数把关键变量实时画在图表上。我从不用DRAWTEXT写“开仓”“平仓”这种废话,而是画出REFX的未来值、#IMPORT的跨周期数据、SLOPE的斜率数值——让每一根 K 线都成为你的调试探针。
6.1DRAWTEXT的高效用法:只画“异常值”和“决策点”
DRAWTEXT(COND,P,TEXT)的COND参数是性能瓶颈。若写DRAWTEXT(1, CLOSE, 'DEBUG'),每根 K 线都渲染文字,CPU 占用飙升。正确做法是只在关键决策点画,且用VALUEWHEN锁定首次触发。
// 画出 ZIGZAG 转向点(仅首次,避免重复) ZIG := ZIGZAG(HIGH, 5, 1); ZIG_CHANGE := CROSS(ZIG, REF(ZIG,1)) OR CROSS(REF(ZIG,1), ZIG); FIRST_ZIG := VALUEWHEN(ZIG_CHANGE, BARPOS); DRAWTEXT(BARPOS == FIRST_ZIG, HIGH, 'ZIG'), COLORRED; // 画出 MA20 与 CLOSE 的金叉点(仅首次) GOLD_CROSS := CROSS(CLOSE, MA(CLOSE,20)); FIRST_CROSS := VALUEWHEN(GOLD_CROSS, BARPOS); DRAWTEXT(BARPOS == FIRST_CROSS, LOW, 'GOLD'), COLORGREEN;提示:
DRAWTEXT的TEXT参数支持换行符\n,可画多行信息。例如DRAWTEXT(BARPOS==FIRST_CROSS, LOW, 'GOLD\n'+NUMTOSTR(CLOSE,2)+'\n'+NUMTOSTR(MA(CLOSE,20),2)),显示金叉时的价格和均线值。
6.2DRAWNUMBER的精度控制:用数字代替文字,看清策略心跳
DRAWNUMBER(COND,DATA,NUMBER,PRECISION,COLOR)是调试神器。PRECISION参数(小数点后位数)决定你能看清多少细节。例如DRAWNUMBER(1, CLOSE, SLOPE(CLOSE,20), 3, COLORBLUE),能把斜率精确到千分位,一眼看出趋势加速/减速。
// 同时画出多个关键指标,形成“策略仪表盘” DRAWNUMBER(BARPOS > 50, LOW*0.995, STD(CLOSE,20), 4, COLORCYAN), 'STD20'; DRAWNUMBER(BARPOS > 50, LOW*0.990, SLOPE(CLOSE,20), 4, COLORRED), 'SLOPE20'; DRAWNUMBER(BARPOS > 50, LOW*0.985, CORR(CLOSE, GETPRICE('I2409'), 20), 3, COLORYELLOW), 'CORR_I'; // 用不同垂直位置(LOW*0.995 等)错开,避免重叠注意:
DRAWNUMBER的NUMBER参数必须是数值型,不能是字符串。若要显示文本+数字,用NUMTOSTR(NUMBER, PRECISION)转换,如DRAWTEXT(1, HIGH, 'STD:'+NUMTOSTR(STD(CLOSE,20),3))。
6.3 终极调试技巧:用BACKGROUNDSTYLE和FILLRGN可视化策略状态
BACKGROUNDSTYLE(i)设置背景色(i=0白色,i=1黑色),FILLRGN(COND,DATA1,DATA2,COLOR)填充区域。二者结合,可将整个图表变成状态指示器。
// 用背景色标识“高波动区间” VOLATILE := STD(CLOSE,10) > REF(STD(CLOSE,10),1) * 1.2; BACKGROUNDSTYLE(IF(VOLATILE,1,0)); // 高波动时背景变黑 // 用填充色标识“多头强势区间” BULLISH := CLOSE > MA(CLOSE,20) AND SLOPE(CLOSE,20) > 0; FILLRGN(BULLISH, HIGH, LOW, COLORLIGHTGREEN); // 多头区填充浅绿 // 用填充色标识“空头强势区间” BEARISH := CLOSE < MA(CLOSE,20) AND SLOPE(CLOSE,20) < 0; FILLRGN(BEARISH, HIGH, LOW, COLORLIGHTRED); // 空头区填充浅红从那以后我每次写完新策略,第一件事不是回测,而是加三行DRAWNUMBER:一行画BARPOS(确认数据长度),一行画REF(CLOSE,1)(确认历史引用正常),一行画OPI(确认头寸函数可用)。这三行代码就像手术前的三次器械清点,缺一不可。它不保证策略盈利,但能保证你看到的每一个信号,都是策略真实输出的,而不是数据加载失败或函数误用的幻影。希望帮到你。
本文还有配套的精品资源,点击获取