价格行为分析工具包开发(第二部分):分析注释脚本
概述
为简化价格行为分析、加速市场评估流程,我基于“图表投影仪”概念开发了一款高效工具。该工具通过单脚本运行即可为交易者提供核心市场数据的精简摘要,无需手动切换图表。并且有效地展示了关键指标,其中包括:前一日的开盘价和收盘价、重要的支撑位和阻力位、前一日的最高价和最低价以及交易量。此外,工具会在图表上直接显示纵向数据表,便于快速参考。
工具可自动绘制重要支撑阻力线,为分析提供直观的视觉指引。同时,还会生成市场条件及潜在走势的注释说明,为交易决策提供关键背景信息。
以下将展开说明各子模块:
为什么要关注该工具?
在研究某些市场信息如何影响市场方向预测之后,我创建了一个旨在快速提供最关键市场洞察的工具。这就意味着您无需筛选历史数据或进行复杂的计算。该工具的突出特点是它能够在几秒钟内提供信息。
它显示了前一日的开盘价和收盘价,并突出显示关键的阻力位和支撑位。也许最重要的是,它计算了当前成交量和前一日的成交量。理解成交量至关重要,因为它反映了市场的参与度。当今日成交量显著高于昨日时,表明市场参与度提升,交易者活跃度增加。这样往往伴随更剧烈的价格波动,并可能强化当前价格趋势——无论是向上(看涨)还是向下(看跌)。通过综合分析此类信息,可对价格未来走势方向形成有价值的判断依据。
下表概述了其中一些关键功能。
| 优势 | 说明 |
|---|---|
| 关键水平的识别 | 了解前一日的最高价和最低价,可帮助交易者识别关键的心理价位水平,由此可能会增加买入或卖出的压力。 |
| 成交量洞察 | 分析成交量有助于交易者衡量市场偏好。在特定价格水平上的高成交量,通常表明交易者对该价位的强烈共识,这会成为未来交易的一个重要参考。 |
| 趋势确认 | 开盘价和收盘价提供了对市场情绪的洞察。收盘价高于开盘价表明看涨情绪,反之则表明看跌情绪。 |
| 图表注释 | 该脚本会在图表上自动绘制支撑与阻力水平线,通过可视化标记辅助交易者提升分析效率。这种视觉化支撑体系使市场关键价位与价格行为动态更直观易懂,尤其适合快速识别交易机会。 |
| 清晰的注释 | 在图表上使用注释框有助于简洁地传达关键性分析,有助于快速决策。 |
| 学习工具 | 对于新手交易者来说,该脚本可以作为一种教学工具,帮助他们了解如何阅读和解读历史价格数据、成交量以及对未来价格走势的影响。 |
| 高效和节省时间 | 该工具自动化了关键指标的计算和检索,节省了时间。这让交易者可以专注于执行他们的交易计划,而不是收集数据。 |
脚本概述
我们将要查看的MQL5脚本可以帮助你自动收集前一个交易日的重要指标。这使得分析更加轻松,您可以将更多时间花在策略上,而不是收集数据上。以下是该脚本的工作方式。
1. 直接从交易平台上获取前一个交易日的数据,计算并显示关键技术水平。

图例1. 关键水平
图1展示了市场的重要信息,包括前一日的开盘价和收盘价、关键阻力位和支撑位,以及市场对这些水平的反应。
2. 对图表进行注释,以便作为即时参考。

图例2. 快速图表参考
在图2中,我们可以看到MetaTrader 5图表上如何展示即时参考信息。
让我们更仔细地看一下脚本,以了解其功能。
MQL5脚本
该脚本旨在分析前一日的市场表现,并向交易者展示关键的分析内容。对于依赖近期价格行为与成交量趋势分析来制定交易决策的日内交易者和技术分析师而言,该工具具有显著的实用价值。以下是完整的脚本,可在您的MetaTrader 5平台上实现:
//+------------------------------------------------------------------+ //| ACS.mq5 | //| Copyright 2024, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2024, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/users/lynnchris" #property description "Script that displays previous day metrics on the current chart and predicts market direction." #property version "1.0" #include <Trade\Trade.mqh> //+------------------------------------------------------------------+ //| Input parameters | //+------------------------------------------------------------------+ input color TableTextColor = clrBlue; // Text color for the table input int TableXOffset = 10; // X offset for the table input int TableYOffset = 50; // Y offset for the table input color SupportColor = clrGreen; // Color for the support line input color ResistanceColor = clrRed; // Color for the resistance line //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ double prevDayHigh, prevDayLow, prevDayOpen, prevDayClose, prevDayVolume; double currentDayVolume; double keySupport, keyResistance; // Initialized but will be calculated //+------------------------------------------------------------------+ //| Main function | //+------------------------------------------------------------------+ void OnStart() { //--- Get previous day's data int prevDayIndex = iBarShift(NULL, PERIOD_D1, iTime(NULL, PERIOD_D1, 1)); if(prevDayIndex == -1) { Print("Error retrieving previous day's data."); return; } prevDayHigh = iHigh(NULL, PERIOD_D1, prevDayIndex); prevDayLow = iLow(NULL, PERIOD_D1, prevDayIndex); prevDayOpen = iOpen(NULL, PERIOD_D1, prevDayIndex); prevDayClose = iClose(NULL, PERIOD_D1, prevDayIndex); prevDayVolume = iVolume(NULL, PERIOD_D1, prevDayIndex); //--- Get today's volume currentDayVolume = iVolume(NULL, PERIOD_D1, 0); // Current day's volume //--- Calculate key support and resistance keySupport = prevDayLow; // Support level can be set to the previous day's low keyResistance = prevDayHigh; // Resistance level can be set to the previous day's high //--- Manage existing lines (if any) //ObjectDelete("SupportLine"); //ObjectDelete("ResistanceLine"); //--- Create support line if(!ObjectCreate(0, "SupportLine", OBJ_HLINE, 0, 0, keySupport)) { Print("Failed to create SupportLine"); } ObjectSetInteger(0, "SupportLine", OBJPROP_COLOR, SupportColor); ObjectSetInteger(0, "SupportLine", OBJPROP_WIDTH, 2); // Set the width of the line //--- Create resistance line if(!ObjectCreate(0, "ResistanceLine", OBJ_HLINE, 0, 0, keyResistance)) { Print("Failed to create ResistanceLine"); } ObjectSetInteger(0, "ResistanceLine", OBJPROP_COLOR, ResistanceColor); ObjectSetInteger(0, "ResistanceLine", OBJPROP_WIDTH, 2); // Set the width of the line //--- Determine the day's nature (Bullish or Bearish) string marketNature; if(prevDayClose > prevDayOpen) { marketNature = "Bullish"; } else if(prevDayClose < prevDayOpen) { marketNature = "Bearish"; } else { marketNature = "Neutral"; } //--- Compare volumes and determine market sentiment string volumeCommentary; if(currentDayVolume > prevDayVolume) { volumeCommentary = "Current day volume is higher than previous day volume. Bullish sentiment may continue."; } else if(currentDayVolume < prevDayVolume) { volumeCommentary = "Current day volume is lower than previous day volume. Bearish sentiment may follow."; } else { volumeCommentary = "Current day volume is equal to previous day volume. Market sentiment remains uncertain."; } //--- Generate market movement commentary string marketCommentary; if(marketNature == "Bullish") { marketCommentary = "The market closed higher yesterday, indicating bullish sentiment. Look for potential continuation patterns."; } else if(marketNature == "Bearish") { marketCommentary = "The market closed lower yesterday, indicating bearish sentiment. Consider taking positions that align with this trend."; } else { marketCommentary = "The market showed neutrality with little change. Watch for potential breakout opportunities."; } //--- Display the information in a table-like format on the chart string textOutput = "Previous Day Analytics:\n"; textOutput += "Open: " + DoubleToString(prevDayOpen, 5) + "\n"; textOutput += "Close: " + DoubleToString(prevDayClose, 5) + "\n"; textOutput += "High: " + DoubleToString(prevDayHigh, 5) + "\n"; textOutput += "Low: " + DoubleToString(prevDayLow, 5) + "\n"; textOutput += "Volume (Prev Day): " + DoubleToString(prevDayVolume, 0) + "\n"; textOutput += "Volume (Current Day): " + DoubleToString(currentDayVolume, 0) + "\n"; textOutput += "Support: " + DoubleToString(keySupport, 5) + "\n"; textOutput += "Resistance: " + DoubleToString(keyResistance, 5) + "\n"; textOutput += "\nMarket Nature: " + marketNature + "\n"; textOutput += volumeCommentary + "\n"; textOutput += marketCommentary; // Draw the text output on the chart Comment(textOutput); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
代码开发
我们使用MetaEditor来开发代码。在这种情况下,我们选择创建一个脚本。下面,我们将概述实现这一目标的步骤。
1. 属性
这些属性有助于为您的工作提供适当的归属,并分享有关作者或脚本来源的重要信息。还在脚本上明确标注了版本号,这一设计便于用户追踪更新记录,并确保及时获知所有功能变更信息。
#property copyright "2024, MetaQuotes Software Corp" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0"
2. 包含所需的库文件
此行代码用于引入Trade.mqh库文件,
Trade:该术语通常指用于管理交易操作的各种函数、类或对象集合。这些组件可简化交易执行、状态查询及相关任务处理流程,适用于交易算法开发。
.mqh:此文件扩展名为MetaQuotes头文件的专用格式。在 MetaTrader 平台中,.mqh文件用于存储可复用代码(如函数、类或库模块),这些代码可轻松嵌入其他MQL程序,提升开发效率与代码模块化程度。
#include <Trade\Trade.mqh> 3. 输入参数:
输入参数是MQL5程序中定义的变量,用户可通过策略测试器或EA参数设置界面直接调整,而无需修改底层代码。
该脚本支持用户自定义输入参数,赋予交易者灵活调整分析工具的权限。用户可针对支撑/阻力线选择特定交易品种或颜色方案,使工具更贴合个人需求且易于辨识。
input color TableTextColor = clrBlue; // Text color for the table input int TableXOffset = 10; // X offset for the table input int TableYOffset = 50; // Y offset for the table input color SupportColor = clrGreen; // Color for the support line input color ResistanceColor = clrRed; // Color for the resistance line
接下来,我们将探讨全局变量的应用。这些全局变量用于存储前一日价格行为数据及当日成交量信息。变量keySupport和keyResistance将在代码后续部分进行初始化。
double prevDayHigh, prevDayLow, prevDayOpen, prevDayClose, prevDayVolume; double currentDayVolume; double keySupport, keyResistance; // Initialized but will be calculated
4. 主函数:
此为脚本的主执行函数,程序从这里开始运行。该函数内的所有代码将在脚本启动时自动执行。在MetaTrader 5环境中,脚本属于单次执行程序,用于完成特定任务(如下单、修改订单或生成交易信号)。
void OnStart()
首先,脚本会获取前一交易日的行情数据(包括价格水平和成交量)。这一步骤通过定位最后一个完整日K线的索引来实现,该索引是分析近期市场行为和制定交易决策的关键依据。
int prevDayIndex = iBarShift(NULL, PERIOD_D1, iTime(NULL, PERIOD_D1, 1));
脚本会检查前日索引是否成功获取。若获取失败,将输出错误信息并终止函数执行。
if (prevDayIndex == -1) { Print("Error retrieving previous day's data."); return; }
接下来,它会检索前一天的数据:
prevDayHigh = iHigh(NULL, PERIOD_D1, prevDayIndex); prevDayLow = iLow(NULL, PERIOD_D1, prevDayIndex); prevDayOpen = iOpen(NULL, PERIOD_D1, prevDayIndex); prevDayClose = iClose(NULL, PERIOD_D1, prevDayIndex); prevDayVolume = iVolume(NULL, PERIOD_D1, prevDayIndex);
获取当日成交量
此代码用于获取当前交易日的成交量数据。
currentDayVolume = iVolume(NULL, PERIOD_D1, 0); // Current day's volume
计算支撑位与阻力位
支撑位设定为前一日的最低价,阻力位设定为前一日的最高价。
keySupport = prevDayLow; // Support level can be set to the previous day's low keyResistance = prevDayHigh; // Resistance level can be set to the previous day's high
绘制支撑阻力线
尝试创建一条水平线表示支撑位。若绘制失败,将输出错误信息。阻力线的绘制采用相同流程。
if (!ObjectCreate(0, "SupportLine", OBJ_HLINE, 0, 0, keySupport)) { Print("Failed to create SupportLine"); }
判断市场性质
以下代码根据前一日的开盘价和收盘价判断市场是处于向上(看涨)、向下(看跌)还是震荡(持平)行情:
if (prevDayClose > prevDayOpen) { marketNature = "Bullish"; } else if (prevDayClose < prevDayOpen) { marketNature = "Bearish"; } else { marketNature = "Neutral"; }
注释功能
Comment() 函数可在交易图表上直接显示描述性文字,可用于展示关键数据(如当前数值)、交易信号或系统状态等信息。
以下注释示例展示当前日与前一日成交量的对比:
if (currentDayVolume > prevDayVolume) { volumeCommentary = "Current day volume is higher..."; } else if (currentDayVolume < prevDayVolume) { volumeCommentary = "Current day volume is lower..."; } else { volumeCommentary = "Current day volume is equal..."; }
该脚本通过 Comment() 函数在图表上生成一条清晰、格式化的信息,显示前一日的开盘价、最高价、最低价、收盘价,以及前一日和当日的成交量数据。这一功能可为交易者提供即时的行情参考依据。
if (marketNature == "Bullish") { marketCommentary = "The market closed higher yesterday..."; } else if (marketNature == "Bearish") { marketCommentary = "The market closed lower yesterday..."; } else { marketCommentary = "The market showed neutrality..."; }
显示数据表
最后,脚本会将所有收集到的数据整合为文本信息,并将其显示在图表上:
string textOutput = "Previous Day Analytics:\n"; textOutput += "Open: " + DoubleToString(prevDayOpen, 5) + "\n"; ... textOutput += marketCommentary; // Draw the text output on the chart Comment(textOutput);
测试
以下是成功实现该脚本的完整步骤。
1. 打开MetaTrader 5交易平台,进入MetaEditor代码编辑器。
2. 在MetaEditor中,通过菜单栏选择 新建 > 脚本(New > Script)创建新脚本文件。
3. 将提供的脚本代码完整复制并粘贴到编辑器窗口中。
4. 点击编译按钮(Compile)生成可执行文件。并确保编译日志中无错误提示。
5. 返回MetaTrader主界面,在左侧导航面板的 "脚本"(Scripts)分类下找到刚编译的脚本,将其拖拽至目标交易图表上。

图例3. 工具测试结果1
6. 在弹出的对话框中设置自定义输入参数(如需调整)。以下GIF演示了我在MetaTrader 5中修改参数的操作过程。

图例4. 参数设置界面
运行脚本后,获得以下测试结果。我提供了三个不同交易对的测试GIF,分别展示脚本在不同品种上的运行效果。首个GIF演示的是货币对USD/SEK的测试结果,具体如下:

图例5. 工具测试结果2
如上图5所示,该工具清晰呈现了关键的市场信息,反映出市场预期的看涨情绪。市场初期呈现短暂下跌走势,但随日内交易的推进,逐步显现强劲的上涨态势。
之后,我们对Crash 900指数进行了同步分析。

图例6. 工具测试结果3
如图6所示的Crash 900指数分析中,呈现的市场信息同样清晰可见,反映出快速形成且无反弹逆转的看跌情绪。
最后,我们对美元对人民币(USDCNH)货币对进行了专项分析,具体结论如下。

图例7. 工具测试结果4
如上图7所示,该工具表现极为出色,成功地发出看涨市场信号。市场随即作出响应,严格遵循阻力位与支撑位的区间运行。
此外,在工具测试过程中,图3(Boom 300指数)呈现出部分显著的分析结果:该图表清晰标注了前一日的开盘价与收盘价,为市场行为研究提供了关键的数据支撑。同时,工具导航功能识别出明确的看跌趋势。
结论
通过成功开发与多轮测试,可以确信该分析注释工具具有高度的可靠性。其能够快速分析之前的市场走势,识别支撑位和阻力位,计算交易量,并根据收集到的信息提供对未来价格走势的洞察,令人印象深刻。
通过清晰的信息呈现,增强了该工具的可用性。我鼓励交易者将自己的交易策略与此工具结合起来,以改善交易结果和决策过程。此外,我还观察到,随着一天的推移,该工具的表现会达到最优,因为它会计算当前时间的成交量,这对于准确地分析可能是必要的。
| 日期 | 工具名 | 说明 | 版本 | 更新 | 备注 |
|---|---|---|---|---|---|
| 01/10/24 | Chart Projector | 以重影效果覆盖前一日价格走势的脚本 | 1.0 | 初始版本 | Lynnchris工具箱的第一个工具 |
| 18/11/24 | Analytical Comment | 它以表格形式提供前一日的信息,并预测市场的未来方向。 | 1.0 | 初始版本 | Lynnchris工具箱的第二个工具 |
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/15927
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
数据科学和机器学习(第 31 部分):利用 CatBoost AI 模型进行交易
DoEasy.服务函数(第 3 部分):外包线形态
开发回放系统(第 68 部分):取得正确的时间(一)