简介:面向股票与期货交易者的文华财经、富途牛牛技术指标公式源码包,内含VAR1至VARK2等变量的完整计算逻辑,涵盖高低价差、收盘价与高低价关系、移动平均线等核心分析方法,适用于技术分析与量化策略研究。包体共3个文件,以inscode指标源码为主,配合html可视化展示页与gitignore工程配置文件,压缩包仅6KB,结构清晰便于快速查看。源码中对STICKLINE函数的使用直观呈现了价格变动可视化方式,可帮助理解技术指标图表背后的数据逻辑,支持在两大平台中直接加载和二次修改。已有261人学习下载,适合需要参考成熟指标实现、自主修改优化公式的交易者与开发者,可用于识别市场趋势方向,为交易决策和风险管理提供量化工具支撑。 做交易的人多少都有点“指标洁癖”:自己调好的参数、摸熟的买卖点提示,换一个软件就全废了。如果平时既看国内期货又看港美股,大概率要在文华财经和富途牛牛之间来回切。文华那边用的是类麦语言的公式系统,富途牛牛则是基于JavaScript的私有脚本体系,两套语法完全不搭边。我见过不少人因为换平台,不得不手动盯盘找信号,或者干脆放弃自用的指标。这篇文章就把我实际做的“文华财经指标逻辑迁移到富途牛牛”完整拆开讲:两个平台公式系统到底差在哪、迁移前要想清楚什么、源码怎么改,以及那些文档里根本不会写的坑。适合正在跨平台折腾指标公式的朋友,也适合刚入门想理解两套脚本机制的开发者。
1. 两套指标体系,本质上是两种编程思维
1.1 文华财经WH6公式语言的特点
文华财经WH6的公式语言属于典型的“指标描述型”语言,早年借鉴了国内流行分析软件的麦语言风格,最大的优点是上手极快。比如要画一条5日均线,源码就是MA5:MA(CLOSE,5);,冒号前面是输出名称,后面是计算表达式,分号结尾,完事。这种语言的语法天然面向K线序列,所有函数默认作用在全量K线上,你不需要自己管理数据数组,也不需要关心当前K线是哪一根,语言解释器替你处理了循环。
它有几个高频函数是迁移时必须重点理解的:REF(X,N)取前N根K线的值,LLV(X,N)和HHV(X,N)分别求近期最低值和最高值,CROSS(A,B)判断A上穿B,DRAWICON在图上画图标,SMA(X,N,M)做带权平滑。另外,文华公式支持N:=9;这种局部变量定义,:=表示不输出到图面上的计算赋值,而单个冒号:则表示在副图/主图上画线输出。这个细节很多新手会卡住,稍不留意就把中间变量输出到了图上。
1.2 富途牛牛脚本机制与API风格
富途牛牛的指标脚本是另一套逻辑。它以JavaScript为基底,暴露了study、plotLine、plotMarker、plotBar等API,让开发者用接近编程的方式写指标。比如定义一个指标头用study("指标名"),画一条线用plotLine("MA5", ma(close, 5), {color: "#FFD700"}),这里的close、high、low、open、volume都是内置的数据序列对象,ma()、sma()、cross()、lowest()、highest()等函数可以直接调用。
跟文华最大的不同是,富途脚本更像在“写程序”而不是“描述指标”。你可以定义局部变量、写条件判断、用for循环遍历K线,甚至通过barCount拿到当前K线总数,再结合当前索引判断自己处于哪根K线。灵活性更高,但也意味着你要自己处理一些文华里完全不需要操心的事情,比如数组越界、数据不足时的空值判断、K线收盘后信号是否还继续更新等。
1.3 语法与数据模型的差异对照
为了直观说明,我把文华和富途在指标开发中的对应关系列了个表。
| 功能/场景 | 文华财经WH6写法 | 富途牛牛脚本写法 |
|---|---|---|
| 定义指标 | 直接写变量并输出 | study("指标名") |
| 局部计算 | A:=CLOSE*2; | var a = close * 2; |
| 画线输出 | MA5:MA(CLOSE,5); | plotLine("MA5", ma(close, 5)); |
| 求前N周期值 | REF(CLOSE,1) | close[barIndex - 1]或ref(close, 1) |
| 求N周期最低值 | LLV(LOW,N) | lowest(low, n) |
| 金叉判断 | CROSS(K,D) | cross(k, d) |
| 画买卖点图标 | DRAWICON(COND,LOW,1) | plotMarker("Buy", low, {marker: "arrowUp"}) |
| 判断最后一根K线 | ISLASTBAR | 遍历中判断barIndex === barCount - 1 |
| 自定义警示/标记 | DRAWTEXT(COND,PRICE,'TEXT') | plotText("Label", price, "TEXT") |
表格只是表面差异,真正影响指标行为的是底层数据模型。文华的公式引擎默认把整个K线序列拉到内存里自动循环,你用REF(CLOSE,1)时不需要担心第一根K线之前有没有数据;而富途脚本需要你自己判断当前索引,如果索引小于0还去取ref(close, 1),轻则返回异常值,重则直接报错。这就是为什么很多把文华公式“逐行直译”成富途脚本的人,第一版总会遇到各种数据错位和边界问题。
2. 迁移前必须先想清楚的设计思路
2.1 先把指标逻辑拆成“平台无关”的模块
不管在什么平台,一个交易指标本质上就三件事:计算核心、条件判断、信号输出。计算核心是纯粹的数据处理,比如计算KDJ的K、D、J值,计算均线、MACD柱,这些逻辑与平台无关,只需要找到对应函数。条件判断是基于计算结果的买卖点规则,比如“K上穿D买入”“价格跌破MA20卖出”,这层要特别注意CROSS这种边界条件在不同平台的实现差异。信号输出则是把结果画到图上、发出声音或文字提醒,各平台API差异最大,也是迁移工作量最集中的地方。
我自己习惯先把逻辑写在纸上,用伪代码表达清楚,再去分别翻译成语法。比如“KDJ金叉买入”:
- 计算RSV = (收盘价 - 9日最低价) / (9日最高价 - 9日最低价) * 100
- K = RSV的3日平滑,D = K的3日平滑,J = 3K - 2D
- 当上一根K线的K <= D 且当前K线的K > D,触发买入信号
- 在K线低点下方画买入箭头
这套伪代码落在文华和富途上都能落地,差异只在函数写法。先想清楚逻辑,再动手写代码,能省掉后面大量的返工。
2.2 平台差异必然带来信号偏差
我见过有人指望把同一套指标从文华搬到富途后,历史信号一个不差地完全一致。但这基本不现实,至少有三个客观原因。第一是复权方式不同。文华财经的期货合约默认不复权或按比例复权,富途牛牛对港股美股默认前复权,复权价格会直接影响均线、高低点、RSV这些计算,信号自然会有偏差。第二是K线时区不同。期货的日K按国内交易日切分,港美股日K按交易所本地时区切分,一天的“开盘价”“收盘价”对应的是完全不同的时间窗口。第三是停牌和交易时段差异,港美股有盘前盘后数据,普通日K未必把它纳入,文华期货则没有这个问题。
不是说两套平台不能共用一套逻辑,而是迁移后你要重新审视参数,不能指望原封不动的数字在不同市场也有同样表现。把平台差异当作“需要重新适配”,而不是“代码写错了”,心态上会舒服很多,排查问题也更高效。
2.3 输出设计:主图副图、买卖点、文字提示怎么分配
很多初学者把指标写得特别“满”,主图上又画均线又画通道又画买卖箭头,副图再堆一堆彩柱,看起来热闹,其实信号重叠严重,根本没法用。我建议迁移时强制做一次分层:主图只放价格相关的叠加内容,比如均线、布林带、买卖点箭头;副图放超买超卖类指标,比如KDJ、RSI的曲线;文字提示仅保留在关键信号位置,不要每个条件都弹文字。
富途牛牛脚本里,plotMarker用来画箭头和图钉,plotText用来写文字,plotLine画趋势线,plotBar画柱状图。把这些能力按主图、副图分开,代码结构也更清晰。文华那边则靠DRAWICON、DRAWTEXT、STICKLINE完成类似效果,迁移时按“一层一层拆开再合上”的思路处理,比直接改语法要稳健得多。
3. 实操:把文华KDJ+均线交叉逻辑搬进富途牛牛
3.1 文华WH6源码与逻辑拆解
我以一个非常经典的组合为例:KDJ金叉死叉 + 双均线交叉。文华WH6源码长这样:
N1:=9; N2:=3; N3:=3; RSV:=(CLOSE-LLV(LOW,N1))/(HHV(HIGH,N1)-LLV(LOW,N1))*100; K:=SMA(RSV,N2,1); D:=SMA(K,N3,1); J:=3*K-2*D; MA5:=MA(CLOSE,5); MA10:=MA(CLOSE,10); 金叉:=CROSS(K,D); 死叉:=CROSS(D,K); 均线金叉:=CROSS(MA5,MA10); 均线死叉:=CROSS(MA10,MA5); 买入:=金叉 AND 均线金叉; 卖出:=死叉 AND 均线死叉; DRAWICON(买入,LOW*0.98,1); DRAWICON(卖出,HIGH*1.02,2);这段源码的逻辑很清晰:先算KDJ,再算双均线,金叉和死叉分别用CROSS判断,最后把KDJ金叉与均线金叉同时成立作为买入信号,死叉同理作为卖出信号。LOW*0.98和HIGH*1.02的作用是让图标稍微偏离价格极值,避免和K线实体重叠。这里有个计算细节值得注意:SMA(RSV,N2,1)里的第三个参数1是权重,文华的SMA公式是Y = (X * M + Y' * (N - M)) / N,M=1时等价于对最近值给权重1,对前值给权重N-1,跟简单平均MA完全不同,改写时不能把sma简单替换成ma。
3.2 富途牛牛JavaScript源码与逐行说明
同样的逻辑,在富途牛牛脚本体系里我建议这样写:
study("KDJ + MA Cross"); // 参数 var n1 = 9; var n2 = 3; var n3 = 3; var maShort = 5; var maLong = 10; // 计算RSV与KDJ var llv = lowest(low, n1); var hhv = highest(high, n1); var rsv = (close - llv) / (hhv - llv) * 100; var k = sma(rsv, n2, 1); var d = sma(k, n3, 1); var j = 3 * k - 2 * d; // 均线 var maS = ma(close, maShort); var maL = ma(close, maLong); // 交叉判断 var kdjGolden = cross(k, d); var kdjDeath = cross(d, k); var maGolden = cross(maS, maL); var maDeath = cross(maL, maS); // 买卖点 var buySignal = kdjGolden && maGolden; var sellSignal = kdjDeath && maDeath; // 输出 plotLine("K", k, { color: "#FFD700", lineWidth: 1 }); plotLine("D", d, { color: "#00BFFF", lineWidth: 1 }); plotLine("J", j, { color: "#FF69B4", lineWidth: 1 }); plotLine("MA5", maS, { color: "#FF8C00", lineWidth: 1 }); plotLine("MA10", maL, { color: "#00CED1", lineWidth: 1 }); plotMarker("Buy", buySignal ? low * 0.98 : null, { color: "#FF4444", marker: "arrowUp" }); plotMarker("Sell", sellSignal ? high * 1.02 : null, { color: "#00AA00", marker: "arrowDown" });逐行看的话,study声明指标名;lowest(low, n1)和highest(high, n1)对应文华的LLV和HHV,直接算出了9周期的最低最高;sma(rsv, n2, 1)对应文华SMA(RSV,N2,1),函数名完全一致;cross也保留同名,用起来很顺手。关键点在plotMarker的写法,第三项传的是buySignal ? low * 0.98 : null,意思是当前K线满足买入条件时输出一个在低点下沿的箭头,不满足时输出null占位,这是富途API的典型写法,文华里DRAWICON没有这种三元表达式的习惯,迁移时需要改过来。
3.3 参数、信号与显示效果的调优
写完之后不要急着直接当交易依据,先在图表上加载,肉眼对比信号位置是否和预期一致。一般我会分三步验证。第一步,确认KDJ的K、D、J曲线和软件自带KDJ指标近似重合,如果明显不一样,大概率是sma与ma搞混了,或者参数N2/N3传反。第二步,确认买卖箭头出现在金叉/死叉当根K线,而不是提前或延后一根,如果偏移,要检查复权和数据对齐问题。第三步,调颜色和线宽,富途的plotLine支持color、lineWidth、lineStyle,把主图均线和副图KDJ线用不同颜色区分开,避免盯着看半小时还分不清哪条是哪条。
关于参数选择,KDJ的9、3、3是广泛使用的短周期默认值,适合日线级别的波动节奏;如果用在30分钟、60分钟这类更短周期,噪声更大,可以适当把N1放大到14或21,让曲线更平滑。但参数不是越大越好,过大的N1会让KDJ反应迟钝,买卖点明显滞后。双均线从5、10改为10、20,信号数量会显著减少,趋势行情里过滤效果更好,震荡行情里更容易被甩下车。没有完美的参数,只有适合你交易周期的参数。
4. 踩坑实录:迁移过程中最常见的5个问题
4.1 复权差异导致信号对不上
第一个坑就是前面提到的复权问题。富途默认前复权,文华期货端的合约价格通常不带复权因子,拿同一段历史行情去对比,前复权价格和原始价格的走势形态相似,但具体数值可能差距不小。KDJ里的RSV计算依赖近期最高价和最低价,复权方式一变,RSV就变,K、D、J全部跟着变,最终金叉死叉的位置就错开了。排查这类问题,最直接的办法是先把两个平台都设置成“不复权”对比,若信号重合,说明是复权差异;若还不重合,再继续查别的因素。富途脚本里的复权设置通常在K线图的右键菜单里,文华则在合约设置里调整。
4.2 信号闪烁与未来函数问题
文华里的部分函数,比如ZIG、PEAK、TROUGH这类“未来函数”,在最新K线上会随着后续K线变化而改变历史值,如果你把含有这类函数的指标迁移到富途,但富途的脚本引擎并不保证同样的“未来修复”机制,那么盘中信号就会出现闪烁——几分钟前显示买入,几分钟后箭头消失了。这不是代码写错,而是你用了带未来性质的算法。迁移时我的经验是主动规避此类函数,换成纯粹由已收盘K线数据推导的指标逻辑。我们的KDJ+均线组合里,cross在当前K线收盘后就能确定,不会历史漂移,属于稳健做法。
4.3 数据不足时的数组越界
富途脚本在K线数据不足时特别容易出问题。比如一只刚上市不久的港股,总共只有7根日K,你在代码里写lowest(low, 9),引擎可能返回空值甚至抛异常。文华那边多半会忽略这种问题,但富途的JavaScript环境对数组访问更严格。解决方法是在关键计算前判断当前K线索引是否满足周期数要求,不满足就返回空。比如可以这样写:
var barCount = close.length; if (barIndex < n1 || barIndex < maLong) return;这种防御式写法虽然增加了几行代码,但能避免图面上出现断层或报错,尤其适合同时加载多只股票、多周期模板的场景。
4.4 函数名相同但语义不同的隐蔽差异
最容易迷惑人的是那些“同名但不同义”的函数。文华和富途都有SMA,但如果你直接按文华的三参数写法往富途里搬,结果可能大相径庭。文华的SMA(X,N,1)和富途的sma(x, n, 1)虽然都是加权平滑,但平滑系数、边界处理的细节未必完全一致。更典型的是REF,文华写REF(CLOSE,1)取前一根收盘价,富途有的版本支持ref(close, 1),有的则建议直接用数组索引close[barIndex - 1]。我在迁移时不会偷懒照抄同名函数,而是会先做一次输出对比:把同一只标的同时加载文华原指标和富途新指标,手动核对最近20根K线的数值,数值对齐了才继续后面的活。
4.5 主图副图混用导致的性能与阅读负担
最后一个不是代码bug,而是使用习惯问题。有人迁移完后把KDJ曲线、均线、买卖箭头、文字提示全部堆在主图,副图又画一遍KDJ,导致主图密密麻麻,信号一处都看不清。富途的脚本API其实很灵活,study("指标名")默认把输出画在副图;如果你想让K线、均线、买卖点全部出现在主图,需要额外设置study("指标名", "main"),其中“main”表示主图上下文。但我不建议把太多内容塞进主图,合理的做法是主图只放均线和买卖点箭头,KDJ曲线保留在副图,这样视觉负担最小,信号也最直观。
5. 迁移完成后的验证清单
代码写完、指标能加载只是第一步,真正让人放心的是系统性验证。我给自己定了一套固定的验证清单,每次迁移完都会逐项过一遍。
- 历史信号抽检:随机选5只不同板块的股票/合约,比对文华与富途的历史买卖点,重合率低于90%就说明有问题。
- 极端行情压力测试:找一段2020年原油期货暴跌或2022年美股熊市的历史区间,确认指标在高波动环境下不会画出离谱的信号。
- 参数敏感性测试:把N1从5逐步调到20,观察信号密度变化是否平滑,如果某些参数下信号突然密集或完全消失,说明逻辑里有脆弱的边界条件。
- 盘中活数据验证:实盘行情下挂机观察半小时,确认箭头不会反复闪烁、文字提示不会重复出现。
这套清单不复杂,但能筛掉绝大多数低级错误。尤其是“信号闪烁”这类问题,回看历史数据时根本发现不了,只有盘中观察才能暴露。
6. 一点个人经验
折腾跨平台指标久了,我最大的体会是:别追求“信号一模一样”,要追求“逻辑真正落地”。文华和富途的定位、市场、数据源都不一样,指望同一套参数在两个平台产生完全一致的历史信号,既不可能也没必要。迁移的价值在于你的交易逻辑,比如“KDJ金叉+均线金叉”这个规则,能在另一个平台稳定运行,让你不用每天手动翻图盯信号。至于参数是9、3、3还是14、3、3,那是另一个层面的优化问题了。
最后再分享一个小技巧。富途牛牛脚本支持在study里声明参数变量,把它暴露到指标设置面板。迁移时把N1、N2、N3、MA周期全部参数化,就能在界面上直接拖动调整,不用每次改代码然后重新编译。实际用下来,这样调参的效率比在文华里改源码再刷新高很多。指标这东西,永远是“先能跑,再跑好”,能在目标平台上快速迭代,比一开始就憋一个大而全的完美版本要实用得多。
本文还有配套的精品资源,点击获取