使用人工智能AI来编写MT4/MT5指标-汇有钱途

使用人工智能AI来编写MT4/MT5指标

XM十周年100万美元奖励活动

因为要交易美股ETF以及美股差价合约CFD,从去年年底开始在MT5平台上交易。交易系统和交易策略不变,但原来已经习惯多年的MT4平台指标要替换为MT5平台指标。

很多MT5指标都可以在网上找到,大多数可以免费获得,有些指标是付费的。

之前介绍的一个DR/IDR定义区间指标,MT4是免费的,但MT5版本需要30美元。

突然想到,每天都看到各种报道,说什么人工智能的各种进步,在数学、编程领域等又有新的突破。。。

于是决定尝试用DeepSeek v3.2来编写DR/IDR的MT5版指标。

调出DeepSeek v3.2对话框,输入要求如下
“编写一个MQ5指标,要求如下:在北京时间7:30到8:30以两根直线标注出这一个小时的最高最低价,直线延伸至北京时间14:50,同样,标注出北京时间15:00到16:00的最高最低价,直线延伸至北京时间20:25、标注出北京时间21:30到22:30的最高最低价,直线延伸至第二天北京时间04:00。显示效果如同所示。MT5平台的服务器时间是GMT+3.”
AI编写MQ5指标
添加一个效果图,AI更能理解你的需求。

DeepSeek思考几秒钟就开始工作了,不到2分钟几百行代码出来了。
DeepSeek编写MQ5指标
得到这几百行的代码后,怎么编译为mq5文件?

打开MT5平台,按快捷键F4,打开MetaEditor编辑器,点击文件---新文件---创建自定义指标
MQ5文件编辑器
下一步,给指标命名
编写MQ5指标
接下来两步默认,无需理会
MT5平台编辑器
MT5平台编辑器
下一步,把deepseek生成的代码复制到编辑器里,按F7编译
MT5指标编译
这次DeepSeek一步到位,编写指标成功,没有任何错误,效果如下。
MT5指标编译
如果AI编写的指标出现错误,MT5编辑器会在下方出现提示错误的原因,代码哪行哪列都会标注出来。你无需理会,截图给AI,提示语是“代码编译后出现如图中的错误”,AI会给出处理方案,也就是新的代码。继续编译。继续出现错误就继续截图给AI,直到指标编译成功。
MT5平台编辑器错误提示"
指标编译成功后保存在indicators文件夹里,可能是单独的文件或者在一个子文件夹里,MT5平台指标路径详见:MT5平台添加指标文件步骤

这个DR/IDR定义区间指标的最终效果和设置如下
人工智能AI来编写MT4指标

指标源代码如下,现成指标一般保存在百度网盘,但现在百度网盘,哪怕下载几K大小的文件都需要注册账户,下载客户端后才能下载文件,太麻烦了。需要的直接复制,按照上述方法编译。
//+------------------------------------------------------------------+
//| TimeRangeHighLow.mq5 |
//| Copyright © 2026, YourName |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2026, fxful"
#property link "https://fxful.com"
#property version "2.0"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

//--- 输入参数
input color LineColor_High1 = clrGreen; // 时间段1最高价线颜色
input color LineColor_Low1 = clrRed; // 时间段1最低价线颜色
input color LineColor_Mid1 = clrYellow; // 时间段1中点价线颜色
input color LineColor_High2 = clrDodgerBlue; // 时间段2最高价线颜色
input color LineColor_Low2 = clrOrange; // 时间段2最低价线颜色
input color LineColor_Mid2 = clrCyan; // 时间段2中点价线颜色
input color LineColor_High3 = clrLime; // 时间段3最高价线颜色
input color LineColor_Low3 = clrMagenta; // 时间段3最低价线颜色
input color LineColor_Mid3 = clrWhite; // 时间段3中点价线颜色
input int LineWidth = 1; // 线宽
input ENUM_LINE_STYLE LineStyle = STYLE_SOLID; // 线型
input bool ShowMidPrice = true; // 显示中点价格
input bool KeepPreviousDay = true; // 保留前一日标注
input int KeepDays = 1; // 保留天数
input bool ShowTimeRangeBackground = true; // 显示时间段背景
input color BackgroundColor1 = C'30,100,30,50'; // 早盘背景颜色
input color BackgroundColor2 = C'30,30,100,50'; // 午盘背景颜色
input color BackgroundColor3 = C'100,30,100,50'; // 晚盘背景颜色

//--- 全局变量
struct STimeRange
{
int start_hour;
int start_minute;
int end_hour;
int end_minute;
int extend_hour;
int extend_minute;
string name;
string label;
color bg_color;
};

STimeRange ranges[3];
string obj_prefix = "TRHL_";

//+------------------------------------------------------------------+
//| 自定义函数:将北京时间转换为服务器时间(GMT+3) |
//+------------------------------------------------------------------+
datetime BeijingToServerTime(int year, int month, int day, int hour, int minute)
{
datetime beijing_time = StringToTime(string(year) + "." + string(month) + "." + string(day) + " " +
string(hour) + ":" + string(minute));
datetime utc_time = beijing_time - 8 * 3600;
datetime server_time = utc_time + 3 * 3600;
return server_time;
}

//+------------------------------------------------------------------+
//| 自定义函数:获取当前K线对应的北京时间 |
//+------------------------------------------------------------------+
void GetBeijingTime(datetime server_time, int &year, int &month, int &day, int &hour, int &minute)
{
datetime utc_time = server_time - 3 * 3600;
datetime beijing_time = utc_time + 8 * 3600;
MqlDateTime dt;
TimeToStruct(beijing_time, dt);
year = dt.year;
month = dt.mon;
day = dt.day;
hour = dt.hour;
minute = dt.min;
}

//+------------------------------------------------------------------+
//| 自定义函数:获取日期部分(去除时间) |
//+------------------------------------------------------------------+
datetime GetDatePart(datetime time)
{
MqlDateTime dt;
TimeToStruct(time, dt);
dt.hour = 0;
dt.min = 0;
dt.sec = 0;
return StructToTime(dt);
}

//+------------------------------------------------------------------+
//| 自定义函数:获取时间段内的最高最低价 |
//+------------------------------------------------------------------+
bool GetRangeHighLow(datetime start_time, datetime end_time, double &high_price, double &low_price)
{
high_price = 0;
low_price = EMPTY_VALUE;
bool found = false;

int total_bars = Bars(_Symbol, _Period);
for(int i = 0; i < total_bars; i++) { datetime bar_time = iTime(_Symbol, _Period, i); if(bar_time >= start_time && bar_time <= end_time)
{
double bar_high = iHigh(_Symbol, _Period, i);
double bar_low = iLow(_Symbol, _Period, i);

if(high_price < bar_high) high_price = bar_high; if(low_price > bar_low || low_price == EMPTY_VALUE) low_price = bar_low;
found = true;
}
else if(bar_time < start_time)
{
break;
}
}

return found;
}

//+------------------------------------------------------------------+
//| 自定义函数:在图表上绘制水平线 |
//+------------------------------------------------------------------+
void DrawHorizontalLine(string name, double price, datetime start_time, datetime end_time,
color line_color, ENUM_LINE_STYLE style = STYLE_SOLID)
{
ObjectDelete(0, name);

if(!ObjectCreate(0, name, OBJ_TREND, 0, start_time, price, end_time, price))
return;

ObjectSetInteger(0, name, OBJPROP_COLOR, line_color);
ObjectSetInteger(0, name, OBJPROP_WIDTH, LineWidth);
ObjectSetInteger(0, name, OBJPROP_STYLE, style);
ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false);
ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
}

//+------------------------------------------------------------------+
//| 自定义函数:绘制价格标签 |
//+------------------------------------------------------------------+
void DrawPriceLabel(string name, datetime time, double price, color label_color, string text)
{
ObjectDelete(0, name);

if(!ObjectCreate(0, name, OBJ_TEXT, 0, time, price))
return;

ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_COLOR, label_color);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
ObjectSetInteger(0, name, OBJPROP_BACK, false);
}

//+------------------------------------------------------------------+
//| 自定义函数:绘制时间段背景矩形(改:用最高最低价限定范围) |
//+------------------------------------------------------------------+
void DrawTimeRangeBackground(string name, datetime start_time, datetime end_time,
color bg_color, double high_price, double low_price)
{
ObjectDelete(0, name);

if(!ObjectCreate(0, name, OBJ_RECTANGLE, 0, start_time, high_price, end_time, low_price))
return;

ObjectSetInteger(0, name, OBJPROP_COLOR, bg_color);
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg_color);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 0);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
}

//+------------------------------------------------------------------+
//| 自定义函数:处理单个时间段 |
//+------------------------------------------------------------------+
void ProcessTimeRange(STimeRange &range, int range_index, datetime current_date)
{
int year, month, day, hour, minute;
GetBeijingTime(current_date, year, month, day, hour, minute);

// 计算今天的开始和结束时间(服务器时间)
datetime range_start = BeijingToServerTime(year, month, day,
range.start_hour, range.start_minute);
datetime range_end = BeijingToServerTime(year, month, day,
range.end_hour, range.end_minute);
datetime extend_end = BeijingToServerTime(year, month, day,
range.extend_hour, range.extend_minute);

// 如果延伸结束时间小于开始时间,说明跨天了
if(range.extend_hour * 60 + range.extend_minute < range.start_hour * 60 + range.start_minute)
{
datetime next_day = current_date + 86400;
int next_year, next_month, next_day_num, next_hour, next_minute;
GetBeijingTime(next_day, next_year, next_month, next_day_num, next_hour, next_minute);
extend_end = BeijingToServerTime(next_year, next_month, next_day_num,
range.extend_hour, range.extend_minute);
}

// 获取时间段内的最高最低价
double range_high, range_low;
if(GetRangeHighLow(range_start, range_end, range_high, range_low))
{
double range_mid = (range_high + range_low) / 2.0;

// 绘制时间段背景矩形(改:传入最高最低价)
if(ShowTimeRangeBackground)
{
string bg_name = obj_prefix + "BG_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
DrawTimeRangeBackground(bg_name, range_start, range_end, range.bg_color, range_high, range_low);
}

// 绘制最高价线
string high_line_name = obj_prefix + "High_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
DrawHorizontalLine(high_line_name, range_high, range_start, extend_end,
(range_index == 0) ? LineColor_High1 :
(range_index == 1) ? LineColor_High2 : LineColor_High3);

// 绘制最低价线
string low_line_name = obj_prefix + "Low_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
DrawHorizontalLine(low_line_name, range_low, range_start, extend_end,
(range_index == 0) ? LineColor_Low1 :
(range_index == 1) ? LineColor_Low2 : LineColor_Low3);

// 绘制中点价线
if(ShowMidPrice)
{
string mid_line_name = obj_prefix + "Mid_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
DrawHorizontalLine(mid_line_name, range_mid, range_start, extend_end,
(range_index == 0) ? LineColor_Mid1 :
(range_index == 1) ? LineColor_Mid2 : LineColor_Mid3);
}

// 在图表上显示价格标签
string high_label = obj_prefix + "Label_High_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
string low_label = obj_prefix + "Label_Low_" + range.name + "_" + TimeToString(current_date, TIME_DATE);
string mid_label = obj_prefix + "Label_Mid_" + range.name + "_" + TimeToString(current_date, TIME_DATE);

DrawPriceLabel(high_label, extend_end, range_high,
(range_index == 0) ? LineColor_High1 :
(range_index == 1) ? LineColor_High2 : LineColor_High3,
DoubleToString(range_high, _Digits));

DrawPriceLabel(low_label, extend_end, range_low,
(range_index == 0) ? LineColor_Low1 :
(range_index == 1) ? LineColor_Low2 : LineColor_Low3,
DoubleToString(range_low, _Digits));

if(ShowMidPrice)
{
DrawPriceLabel(mid_label, extend_end, range_mid,
(range_index == 0) ? LineColor_Mid1 :
(range_index == 1) ? LineColor_Mid2 : LineColor_Mid3,
"中点 " + DoubleToString(range_mid, _Digits));
}
}
}

//+------------------------------------------------------------------+
//| 自定义函数:处理历史数据 |
//+------------------------------------------------------------------+
void ProcessHistoricalData()
{
if(!KeepPreviousDay) return;

datetime current_date = GetDatePart(TimeCurrent());

for(int day_offset = 1; day_offset <= KeepDays; day_offset++)
{
datetime history_date = current_date - day_offset * 86400;

for(int i = 0; i < 3; i++) { ProcessTimeRange(ranges[i], i, history_date); // 将历史数据的线改为虚线 string high_name = obj_prefix + "High_" + ranges[i].name + "_" + TimeToString(history_date, TIME_DATE); string low_name = obj_prefix + "Low_" + ranges[i].name + "_" + TimeToString(history_date, TIME_DATE); string mid_name = obj_prefix + "Mid_" + ranges[i].name + "_" + TimeToString(history_date, TIME_DATE); if(ObjectFind(0, high_name) >= 0)
ObjectSetInteger(0, high_name, OBJPROP_STYLE, STYLE_DASH);
if(ObjectFind(0, low_name) >= 0)
ObjectSetInteger(0, low_name, OBJPROP_STYLE, STYLE_DASH);
if(ObjectFind(0, mid_name) >= 0)
ObjectSetInteger(0, mid_name, OBJPROP_STYLE, STYLE_DASH);
}
}
}

//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 设置时间段(北京时间)
// 时间段1: 07:30-08:25,延伸至14:50
ranges[0].start_hour = 7;
ranges[0].start_minute = 30;
ranges[0].end_hour = 8;
ranges[0].end_minute = 25;
ranges[0].extend_hour = 14;
ranges[0].extend_minute = 50;
ranges[0].name = "Morning";
ranges[0].label = "早盘";
ranges[0].bg_color = BackgroundColor1;

// 时间段2: 15:00-15:55,延伸至20:25
ranges[1].start_hour = 15;
ranges[1].start_minute = 0;
ranges[1].end_hour = 15;
ranges[1].end_minute = 55;
ranges[1].extend_hour = 20;
ranges[1].extend_minute = 25;
ranges[1].name = "Afternoon";
ranges[1].label = "午盘";
ranges[1].bg_color = BackgroundColor2;

// 时间段3: 21:30-22:25,延伸至次日04:00
ranges[2].start_hour = 21;
ranges[2].start_minute = 30;
ranges[2].end_hour = 22;
ranges[2].end_minute = 25;
ranges[2].extend_hour = 4;
ranges[2].extend_minute = 0;
ranges[2].name = "Evening";
ranges[2].label = "晚盘";
ranges[2].bg_color = BackgroundColor3;

Print("时间段指标已初始化");
Print("早盘: 07:30-08:25");
Print("午盘: 15:00-15:55");
Print("晚盘: 21:30-22:25");

return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, obj_prefix);
}

//+------------------------------------------------------------------+
//| 迭代函数 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// 处理当日数据
datetime current_time = TimeCurrent();
datetime current_date = GetDatePart(current_time);

for(int i = 0; i < 3; i++)
{
ProcessTimeRange(ranges[i], i, current_date);
}

// 处理历史数据
ProcessHistoricalData();

return(rates_total);
}
//+------------------------------------------------------------------+

本文由 汇有钱途 作者:admin 发表,其版权均为 汇有钱途 所有,文章内容系作者个人观点,不代表 汇有钱途 对观点赞同或支持。如需转载,请注明文章来源。

发表评论