指标名称:供需趋势[color=rgba(0, 0, 0, 0.9)]
版本:MT4 ver. 2.01 一、指标简介供需趋势,它可在同一个图表上叠加多条来自不同时间周期(Timeframe)的 ZigZag,并自动绘制相应的趋势线、水平线、以及可选的支撑阻力矩形区域。
主要功能: - 多周期叠加:最多可同时计算并显示 9 个 ZigZag,覆盖不同时间周期,从而帮助交易者在同一张图表上快速观察多周期结构。
- 自动趋势线绘制:根据 ZigZag 的最近几个拐点自动画出趋势线(可配置不同的绘制方法)。
- 自动支撑阻力区域:当参数中启用 sup_res 等功能后,会自动在关键 Swing 高低之间绘制矩形,起到标注支撑阻力带的作用。
- Fibo 与水平扩展:可自动对拐点进行斐波那契扩展、或绘制水平线、斐波那契价格标签等辅助工具。
- 可视化开关按钮:在图表上方有一个可点击的按钮(默认文字是“QCSR”),一键开启/关闭指标可视化,以免图表过于拥挤。
二、主要参数讲解本指标的参数很多,下表仅罗列最常用、最关键的几个,帮助大家快速上手。其余参数可以根据源码注释自行探索。 ED
- 用于快速切换 ExtDepth 的值。源码里内置了 2,3,5,8,13,21,34,55,89 等常见数值。
- 例如当 ED="21" 时,会将所有 ZigZag 的 ExtDepth 设置为 21。
ExtDepth、ExtBackstep、ExtMaxBar
- ExtDepth:寻找 Swing 高低点时,ZigZag 向前后比较的“深度”/阈值。
- ExtBackstep:在确认拐点后,再回退多少个柱子以防过度重复。
- ExtMaxBar:可设置当前 ZigZag 只在多少个历史 Bar 上进行计算(0 表示全历史)。
GrossPeriod
- 指定各条 ZigZag 所使用的时间周期(单位:分钟)。例如 1,5,15,30,60,240,1440 分别代表 1 分钟、5 分钟、15 分钟、30 分钟、1 小时、4 小时、1 天等。
- 若填写 0,则表示使用当前图表所在的时间周期。
zzVisible
- 用于控制对应 ZigZag 是否在图表上显示,1=显示,0=不计算不显示。
showZigZag
- 0:ZigZag 以折线形式连接各拐点;
- 1:在拐点处使用菱形(或箭头)标注;
- 2:在拐点到拐点的区间绘制点阵线(类似 DT-ZigZag 的风格)。
TrendLineType
- 0:按上级周期的拐点坐标映射到当前图表,不再细分到当前周期 Bar;
- 1:直接按当前周期的实际 Bar 数据来绘制趋势线;
- 2:在原有更大周期的坐标基础上绘线,不和当前周期 Bar 进行对齐。
- 决定趋势线的绘制方法:
- 建议初学者先使用默认的 1,较为直观。
LevelVisible / hLevelVisible / FiboLevelVisible
- 这几组参数决定是否绘制水平线和斐波那契回调/扩展线。
- LevelVisible=1 时,会在两个最近的关键点之间画水平交汇线;
- hLevelVisible=1 时,会在最近关键点之间画斐波那契通道;
- FiboLevelVisible=1 时,结合垂直线可以绘制相应的斐波那契扩展坐标。
sup_res、sup_res1
- 当 sup_res=true 时,指标会在相邻拐点之间自动绘制矩形,用于标识支撑或阻力带。
- sup_res1=true 时,会绘制更多矩形带,做进一步细分。
按钮相关参数(btn_text, btn_Width, btn_Height, 等)
- 用于控制图表左上角按钮的外观和文字。
- 点击按钮可以快速隐藏/显示所有 ZigZag 线、趋势线、支撑阻力带等,便于保持图表整洁。
四、使用方法与步骤将指标放入 MT4
- 复制指标文件到 ...\MQL4\Indicators\ 文件夹。
- 重启 MT4 或在导航器刷新指标列表。
加载指标到图表
- 在“导航器→自定义指标”中找到“多周期ZigZag趋势/支撑阻力指标”,双击或拖拽到所需图表。
- 在弹出的参数对话框中,按照需求修改 GrossPeriod(需要叠加的周期)、ExtDepth、ED 等。
- 若不想显示某个周期,可以将对应的 zzVisible 数值改为 0;也可以在 GrossPeriod 中把不需要的周期改成 0。
调整可视化样式
- 通过 showZigZag, zzColor, zzStyle, zzWidth 等参数,来改变 ZigZag 的颜色、线型和宽度。
- TrendLineType 切换趋势线绘制逻辑,sup_res 打开/关闭自动支撑阻力矩形,FiboLevelVisible 打开/关闭斐波扩展等。
观察图表
- 指标会自动在图表上呈现多条 ZigZag。相互交叠可快速查看不同时间框架的大趋势或潜在支撑阻力。
- 若打开 sup_res,在关键拐点之间会自动出现矩形区域,通常视为阻力/支撑带。
- 若觉得图表过于拥挤,可点击左上角(默认文字“QCSR”)的按钮,一键隐藏/显示所有线条和矩形。
实盘或回测中注意事项
- ZigZag 指标具有重绘特性,随着行情更新,拐点位置会发生变化,需结合其他分析方法。
- 支撑阻力带与趋势线仅作为参考,并非交易绝对信号。
- 对于较大周期(如日线、周线)叠加到小周期图表时,可能会出现大量水平或趋势线交织,要及时利用按钮或参数进行筛减。
五、常见问题与建议 六、结语指标整合了多周期 ZigZag 和自动趋势线绘制功能,对于想要在同一个图表中快速观察更上级或更下级周期结构的交易者非常有帮助。它不仅能在短时间内展现多周期的高低点,而且通过趋势线、支撑阻力矩形与斐波扩展,让交易者更直观地识别潜在关键价位。
参数:
部分代码展示:
- //+------------------------------------------------------------------+//| 供需趋势.mq4 |//| Copyright © 2009-2024, www.QChaos.com |//| https://www.qchaos.com/ |//+------------------------------------------------------------------+#property indicator_chart_window#property indicator_buffers 8extern string ED = "21"; // ZigZag 计算参数extern string ExtDepth = "21,21,21,21,21,21,21,21,21"; // ZigZag 深度extern string ExtBackstep = "0,0,0,0,0,0,0,0,0"; // ZigZag 回溯步长extern string ExtMaxBar = "1000,1000,1000,1000,1000,1000,1000,1000,1000,1000"; // 计算的最大K线数extern string GrossPeriod = "1,5,15,30,60,240,1440,10080,43200"; // 计算 ZigZag 的时间周期extern string zzVisible = "1,1,1,1,1,1,1,1,1"; // 是否显示 ZigZagextern string zzColor = "Sienna,Purple,RoyalBlue,DarkTurquoise,Tan,Teal,Olive,ForestGreen,DarkGoldenrod,Sienna,Purple,RoyalBlue,DarkTurquoise,Tan,Teal,Olive,ForestGreen,DarkGoldenrod"; // ZigZag 颜色extern string extColor = "Indigo,Olive,Teal"; // 额外线的颜色extern string zzStyle = "0,0,0,0,0,0,0,0,0"; // ZigZag 线型extern string extStyle = "0,0,0"; // 额外线的线型extern string zzWidth = "0,0,0,0,0,0,0,0,0"; // ZigZag 线宽extern string extWidth = "0,0,0"; // 额外线的线宽
- extern bool ExtProcedureOfPayments = true; // 可能涉及支付计算extern int showZigZag = 1; // 是否显示 ZigZagextern bool ExtFirstPoint = true; // 是否计算第一个高低点extern int TrendLineType = 1; // 趋势线类型extern string LevelVisible = "0,0,0,0,0,0,0,0,0"; // 支撑阻力线可见性extern string vLineVisible = "0,0,0,0,0,0,0,0,0"; // 垂直线可见性extern int numbervLine = 1; // 显示的垂直线数量//extern string vLineVisible = "0,0,0,0,0,0,0,0,0"; // 可能是重复定义extern string LineStyle = "2,2,2,2,2,2,2,2,2"; // 线条样式extern string LineWidth = "0,0,0,0,0,0,0,0,0"; // 线条宽度
- // 水平线和标签的可见性控制//extern string hLevelVisible = "1,1,1,1,1,1,1,1,1"; // 之前的水平线可见性(已注释)extern string hLevelVisible = "0,0,0,0,0,0,0,0,0"; // 当前水平线可见性(0-隐藏, 1-显示)extern string hLabelVisible = "0,0,0,0,0,0,0,0,0"; // 水平线标签可见性(0-隐藏, 1-显示)extern string hLevelFree = "-1.0,0.0,0.618,1.0,1.618,2.0,2.618,3.0,4.0"; // 预设水平线比例(可能与斐波那契相关)extern string hLineStyle = "1,1,1,1,1,1,1,1,1"; // 水平线的线型(1-虚线, 0-实线等)extern string hLineWidth = "0,0,0,0,0,0,0,0,0"; // 水平线的线宽
- // 斐波那契线相关设置extern string FiboLevelVisible = "0,0,0,0,0,0,0,0,0"; // 斐波那契水平线可见性(0-隐藏, 1-显示)extern string FiboLevel = "0.0,0.146,0.236,0.382,0.618,1.0,1.618,2.618,4.236,6.853"; // 斐波那契回撤和扩展比例extern bool VisibleCenaFibo = true; // 是否显示斐波那契价格水平
- // ZigZag 计算和趋势线设置extern int ExtReCalculate = 3; // 重新计算的 ZigZag 极值数量(高级别时间框架)extern bool TrendLine1 = true; // 是否显示主趋势线extern bool sup_res = true; // 是否显示支撑/阻力线extern bool sup_res1 = false; // 备用支撑/阻力线的开关extern int ExtComplect = 21; // 计算参数,可能用于 ZigZag 或趋势线计算extern bool Comments = false; // 是否在图表上显示评论信息
- // 按钮界面设置extern string button_note1 = "------------------------------"; // 按钮分隔符extern ENUM_BASE_CORNER btn_corner = CORNER_LEFT_UPPER; // 按钮锚点(左上角)extern string btn_text = "QCSR"; // 按钮文本extern string btn_Font = "Arial"; // 按钮字体extern int btn_FontSize = 10; // 按钮字体大小extern color btn_text_ON_color = clrWhite; // 按钮开启时的字体颜色extern color btn_text_OFF_color = clrRed; // 按钮关闭时的字体颜色extern color btn_background_color = clrDimGray; // 按钮背景色extern color btn_border_color = clrBlack; // 按钮边框颜色extern int button_x = 20; // 按钮 X 坐标extern int button_y = 13; // 按钮 Y 坐标extern int btn_Width = 60; // 按钮宽度extern int btn_Height = 20; // 按钮高度extern string button_note2 = "------------------------------"; // 按钮分隔符
- // 数据显示选项bool show_data = true; // 是否显示数据// 指标名称、对象前缀、按钮IDstring IndicatorName, IndicatorObjPrefix, buttonId;
- // ZigZag 计算参数数组int ExtDepth_[]= {0,0,0,0,0,0,0,0,0}; // 深度参数int ExtBackstep_[]= {0,0,0,0,0,0,0,0,0}; // 回溯步长int ExtMaxBar_[]= {0,0,0,0,0,0,0,0,0}; // 计算的最大K线数量int GrossPeriod_[]= {0,0,0,0,0,0,0,0,0}; // 计算 ZigZag 的时间周期int zzVisible_[]= {0,0,0,0,0,0,0,0,0}; // ZigZag 可见性
- // 颜色和样式设置int zzColor_[]= {0,0,0,0,0,0,0,0,0,0}; // ZigZag 颜色int extColor_[]= {0,0,0}; // 额外线颜色int currentBars_[]= {0,0,0,0,0,0,0,0,0}; // 记录当前K线数int LineStyle_[]= {0,0,0,0,0,0,0,0,0}; // 线条样式int LineWidth_[]= {0,0,0,0,0,0,0,0,0}; // 线条宽度
- // ZigZag 线条样式int zzStyle_[]= {0,0,0,0,0,0,0,0,0}; // ZigZag 线型int extStyle_[]= {0,0,0}; // 额外线线型int zzWidth_[]= {0,0,0,0,0,0,0,0,0}; // ZigZag 线宽int extWidth_[]= {0,0,0}; // 额外线宽度
- // 其他可见性设置int LevelVisible_[]= {0,0,0,0,0,0,0,0,0}; // 支撑阻力线可见性int vLineVisible_[]= {0,0,0,0,0,0,0,0,0}; // 垂直线可见性int hLevelVisible_[]= {0,0,0,0,0,0,0,0,0}; // 水平线可见性int hLabelVisible_[]= {0,0,0,0,0,0,0,0,0}; // 水平线标签可见性int hLineStyle_[]= {0,0,0,0,0,0,0,0,0}; // 水平线线型int hLineWidth_[]= {0,0,0,0,0,0,0,0,0}; // 水平线宽度int FiboLevelVisible_[]= {0,0,0,0,0,0,0,0,0}; // 斐波那契线可见性
- // 指标数据缓冲区(存储 ZigZag 高低点)double LowestBuffer1[], HighestBuffer1[], LowestBuffer2[], HighestBuffer2[];double LowestBuffer3[], HighestBuffer3[], LowestBuffer4[], HighestBuffer4[];
- // 辅助缓冲区(存储高级别 ZigZag 数据)double LowestBufferGross1[], HighestBufferGross1[], LowestBufferGross2[], HighestBufferGross2[];double LowestBufferGross3[], HighestBufferGross3[], LowestBufferGross4[], HighestBufferGross4[];double LowestBufferGross5[], HighestBufferGross5[], LowestBufferGross6[], HighestBufferGross6[];double LowestBufferGross7[], HighestBufferGross7[], LowestBufferGross8[], HighestBufferGross8[];double LowestBufferGross9[], HighestBufferGross9[];
- // 标记是否已计算高级别 ZigZagbool Grosstf_DT[]= {false, false, false, false, false, false, false, false, false};
- // 标记 ZigZag 是否已绘制bool ZZ_tf[] = {false, false, false, false, false, false, false, false, false};
- // 记录第三个趋势点的起始和结束时间datetime L2LTime[]= {0,0,0,0,0,0,0,0,0}, L2HTime[]= {0,0,0,0,0,0,0,0,0};
- // 计算 ZigZag 条件:仅当超出已计算的K线范围时才重新计算,避免每个 tick 计算double lBar[]= {0,0,0,0,0,0,0,0,0}, hBar[]= {0,0,0,0,0,0,0,0,0};datetime tiZZ[]= {0,0,0,0,0,0,0,0,0}, tiP2ZZ[]= {0,0,0,0,0,0,0,0,0};
- // 记录 ZigZag 三个关键点和垂直线位置int nbar[9][3], vLine[9];datetime t3[9][3], tvLine[9];double h3[9][3], l3[9][3], vFibo[9];
- // 控制趋势线重新计算int recount[9]; // 0 - 不计算, 1 - 计算第一条趋势线, 2 - 计算两条趋势线
- // 记录 Bars 数量int saveBars[]= {0,0,0,0,0,0,0,0,0};int currentBars;
- // 记录 ZigZag 计算顺序int ProcedureOfPayments[9][3];
- // 计算 ZigZag 的最大 K 线数int limit;
- // 斐波那契水平相关变量double fi[], fif[];string fitxt[], fiftxt[];string fitxt100[], fiftxt100[];int Sizefi=0, Sizefif=0;
- // 计算参数int ed=2;//+------------------------------------------------------------------------------------------------------------------+// 生成唯一的指标名称,防止重复string GenerateIndicatorName(const string target) // 不要更改此函数 { string name = target; // 初始名称 int try = 2; while(WindowFind(name) != -1) // 如果该名称已存在,则添加编号 { name = target + " #" + IntegerToString(try ++); } return name; // 返回唯一的名称 }//+------------------------------------------------------------------------------------------------------------------+
- // 初始化函数int OnInit() // 不要忘记更改 buttonId 的名称 { IndicatorName = GenerateIndicatorName(btn_text); // 生成唯一的指标名称 IndicatorObjPrefix = "__" + IndicatorName + "__"; // 指标对象前缀 IndicatorShortName(IndicatorName); // 设置指标的短名称 IndicatorDigits(Digits); // 设置指标的小数位数
- double val; if(GlobalVariableGet(IndicatorName + "_visibility", val)) // 获取全局变量控制的可见性状态 show_data = val != 0; // 如果全局变量值非零,则显示数据
- ChartSetInteger(ChartID(), CHART_EVENT_MOUSE_MOVE, 1); // 允许鼠标移动事件
- buttonId = IndicatorObjPrefix + "QCSRTrendLineSR"; // 生成按钮ID(此处名称需要更改) createButton(buttonId, btn_text, btn_Width, btn_Height, btn_Font, btn_FontSize, btn_background_color, btn_border_color, btn_text_ON_color); // 创建按钮
- ObjectSetInteger(ChartID(), buttonId, OBJPROP_YDISTANCE, button_y); // 设置按钮的 Y 轴位置 ObjectSetInteger(ChartID(), buttonId, OBJPROP_XDISTANCE, button_x); // 设置按钮的 X 轴位置
- // 调用自定义初始化函数 init2();
- return(INIT_SUCCEEDED); // 返回初始化成功标志 }
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int init2() { if(ED=="2") { ExtDepth="2,2,2,2,2,2,2,2,2"; ed=2; } if(ED=="3") { ExtDepth="3,3,3,3,3,3,3,3,3"; ed=2; } if(ED=="5") { ExtDepth="5,5,5,5,5,5,5,5,5"; ed=4; } if(ED=="8") { ExtDepth="8,8,8,8,8,8,8,8,8"; ed=7; } if(ED=="13") { ExtDepth="13,13,13,13,13,13,13,13,13"; ed=12; } if(ED=="21") { ExtDepth="21,21,21,21,21,21,21,21,21"; ed=20; } if(ED=="34") { ExtDepth="34,34,34,34,34,34,34,34,34"; ed=33; } if(ED=="55") { ExtDepth="55,55,55,55,55,55,55,55,55"; ed=54; } if(ED=="89") { ExtDepth="89,89,89,89,89,89,89,89,89"; ed=88; } string aa1,str=""; int aa2; int i,j,k,m,n,q;
- SetIndexBuffer(0,LowestBuffer1); SetIndexBuffer(1,HighestBuffer1); SetIndexBuffer(2,LowestBuffer2); SetIndexBuffer(3,HighestBuffer2); SetIndexBuffer(4,LowestBuffer3); SetIndexBuffer(5,HighestBuffer3); SetIndexBuffer(6,LowestBuffer4); SetIndexBuffer(7,HighestBuffer4);
-
- SetIndexEmptyValue(0,0.0); SetIndexEmptyValue(1,0.0); SetIndexEmptyValue(2,0.0); SetIndexEmptyValue(3,0.0); SetIndexEmptyValue(4,0.0); SetIndexEmptyValue(5,0.0); SetIndexEmptyValue(6,0.0); SetIndexEmptyValue(7,0.0);
- _stringtointarray(ExtDepth, ExtDepth_, 9); _stringtointarray(ExtBackstep, ExtBackstep_, 9); _stringtointarray(ExtMaxBar, ExtMaxBar_, 9); _stringtointarray(GrossPeriod, GrossPeriod_, 9); _stringtointarray(zzVisible, zzVisible_, 9); _stringtointarray(LineStyle, LineStyle_, 9); _stringtointarray(LineWidth, LineWidth_, 9); _stringtointarray(LevelVisible, LevelVisible_, 9); _stringtointarray(vLineVisible, vLineVisible_, 9); _stringtointarray(hLevelVisible,hLevelVisible_,9); _stringtointarray(hLabelVisible,hLabelVisible_,9); _stringtointarray(hLineStyle, hLineStyle_, 9); _stringtointarray(hLineWidth, hLineWidth_, 9); _stringtointarray(FiboLevelVisible, FiboLevelVisible_, 9); _stringtointarray(zzStyle, zzStyle_, 9); _stringtointarray(extStyle, extStyle_, 3); _stringtointarray(zzWidth, zzWidth_, 9); _stringtointarray(extWidth, extWidth_, 3); _stringtocolorarray(zzColor, zzColor_, 10); _stringtocolorarray(extColor, extColor_, 3);
- ArrayInitialize(t3,0); ArrayInitialize(h3,0); ArrayInitialize(l3,0); ArrayInitialize(recount,2); ArrayInitialize(nbar,0); ArrayInitialize(vLine,0); ArrayInitialize(tvLine,0); ArrayInitialize(vFibo,0);
- if(TrendLineType<0) TrendLineType=0; if(TrendLineType>2) TrendLineType=2;
- if(numbervLine<0) numbervLine=0; if(numbervLine>1) numbervLine=1;
- i=-1; aa2=0; while(aa2>=0) { aa2=StringFind(hLevelFree, ",",i+1); if(aa2>=0) {i=aa2; Sizefi++;} else { if(StringLen(hLevelFree)-i>0) { if(StrToDouble(StringSubstr(hLevelFree,i+1))>0) Sizefi++; ArrayResize(fi,Sizefi); ArrayResize(fitxt,Sizefi); ArrayResize(fitxt100,Sizefi); aa1=hLevelFree; for(i=0; i<Sizefi; i++) { aa2=StringFind(aa1, ",", 0);
- fitxt=StringTrimLeft(StringTrimRight(StringSubstr(aa1,0,aa2))); fi=StrToDouble(fitxt); if(fi<1) fitxt=StringSubstr(fitxt,1); fitxt100=DoubleToStr(100*fi,1);
- if(aa2>=0) aa1=StringSubstr(aa1,aa2+1); } } } }
- i=-1; aa2=0; while(aa2>=0) { aa2=StringFind(FiboLevel, ",",i+1); if(aa2>=0) {i=aa2; Sizefif++;} else { if(StringLen(FiboLevel)-i>0) { if(StrToDouble(StringSubstr(FiboLevel,i+1))>0) Sizefif++; ArrayResize(fif,Sizefif); ArrayResize(fiftxt,Sizefif); ArrayResize(fiftxt100,Sizefif); aa1=FiboLevel; for(i=0; i<Sizefif; i++) { aa2=StringFind(aa1, ",", 0);
- fiftxt=StringTrimLeft(StringTrimRight(StringSubstr(aa1,0,aa2))); fif=StrToDouble(fiftxt); if(fif<1) fitxt=StringSubstr(fiftxt,1); fiftxt100=DoubleToStr(100*fif,1);
- if(aa2>=0) aa1=StringSubstr(aa1,aa2+1); } } } }
复制代码
|