模糊逻辑指标入门:用隶属函数判断趋势状态
一、模糊逻辑解决什么问题
传统指标用硬阈值判断“涨/跌”,非此即彼,容易被边界附近的噪声反复打脸。模糊逻辑引入“隶属函数”,把精确数值映射到 [0,1] 的“属于某集合的程度”——比如“70 度的咖啡多热”是 1,“20 度”是 0,中间温度得到 0~1 之间的渐变值。这样信号是平滑的、抗噪的,更适合表达“偏多/偏空”这种连续状态。
二、核心流程:模糊化→规则→去模糊化
- 模糊化(fuzzification):用隶属函数把输入(如 EMA 值)变成对“上升/平缓/下降”等模糊集合的隶属度。
- 规则评估(rule evaluation):IF 趋势=强多 AND 动量=高 THEN 信号=买入,类似专家系统的规则表。
- 去模糊化(defuzzification):把所有规则的输出聚合,用重心法(centroid)等合成一个清晰数值。
三、隶属函数实现
最常用三角形/梯形隶属函数。文章用“EMA(2) 相对轨道线上/下边界的位置”定义隶属度:在上下边界之间为平缓(0),突破上边界趋近 1(强多),跌破下边界趋近 -1(强空):
double Fuzzy(double x, double a, double c)
{
double F;
if(a<x) F=1; // 100% 上升趋势
else if(x<=a && x>=c) F=(1-2*(a-x)/(a-c)); // 平坦(线性过渡)
else if(x<c) F=-1; // 100% 下降趋势
return(F);
}
四、完整指标实现
文章建两个轨道线(快/慢 Envelopes)和一个 EMA 信号线,各自算隶属度 Rule1/Rule2,结果取算术平均 Result=(R1+R2)/2。用 DRAW_COLOR_HISTOGRAM 画柱,按 |Result| 落在哪个 0.2 区间给 5 种颜色之一;Result==±1 时用 DRAW_COLOR_HISTOGRAM2 画买卖信号矩形。
CopyBuffer(Envelopes_Fast, UPPER_LINE, 0, rates_total, Env_Fast_Up);
CopyBuffer(Envelopes_Fast, LOWER_LINE, 0, rates_total, Env_Fast_Dn);
// ... 慢轨道线、信号线同理
double x = Mov_Sign[i];
Rule1Buffer[i] = Fuzzy(x, Env_Fast_Up[i], Env_Fast_Dn[i]);
Rule2Buffer[i] = Fuzzy(x, Env_Slow_Up[i], Env_Slow_Dn[i]);
ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;
for(int ci=0; ci<=4; ci++)
if(MathAbs(ResultBuffer[i])>0.2*ci && MathAbs(ResultBuffer[i])<=0.2*(ci+1))
{ ResultColors[i]=ci; break; }
五、优缺点
六、模糊集合与隶属度
经典逻辑非黑即白,模糊逻辑允许「部分属于」:每个输入(如 RSI 高低)映射到一个 0 到 1 的隶属度,表示「有多强」。这样「超买」不再是阈值一跳,而是平滑过渡,更贴近人类对市场的判断。
常见隶属函数有三角形、梯形、高斯形。形状决定过渡的陡峭程度——越平缓对噪声越钝,越陡越敏感。选形状也是在选策略对信号的容忍度。
七、用模糊规则融合信号
把多个指标(如动量、波动率、趋势)各自模糊化后,用一组「如果…则…」规则融合:若动量高且波动低,则强看多。规则把定性经验变成可计算逻辑,比硬加权更直观可解释。
八、实现坑:隶属函数与去模糊化
两大坑:一是隶属函数范围没随品种归一,某品种 RSI 区间和另一品种完全不同,硬套同一函数会失真;二是去模糊化(把多条规则的输出合成一个值)方法要选对,重心法最常用但要对输出空间合理划分。
调试时打印每条规则的激活强度,看信号到底由哪条规则驱动,比直接看最终值更容易定位逻辑错误。 进阶还能给每条规则配「可信度权重」,强规则一票顶弱规则两票,比简单投票更细腻,也方便你发现哪条规则其实在拖后腿。
九、模糊系统的调参顺序
调模糊指标有固定顺序:先定输入隶属函数的论域(覆盖品种真实波动范围),再调规则权重,最后调去模糊化粒度。论域错了后面全歪,所以论域优先于规则。
验证时用「已知行情回放」:给一段明显趋势和一段明显震荡,看隶属度与规则输出是否符合直觉,而不是只看最终信号对不对。