【MT5】周期性 定时发送报告 函数
程序功能说明:
1.时间设置:通过输入参数
DailyReportTime设置每日报告时间,格式为"HH:MM"2.定时检查:使用定时器每分钟检查一次是否到达报告时间
3.每日重置:程序会在每天自动重置发送标志,确保每天只发送一次报告
4.报告内容:包含今日盈亏、交易次数等基本信息
5.错误处理:包含时间格式验证和错误处理机制
//+------------------------------------------------------------------+
//| DailyReporter.mq5 |
//| Copyright 2025, OneTrader.Club |
//| https://www.OneTrader.Club |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, OneTrader.Club"
#property link "https://www.OneTrader.Club"
#property version "1.00"
#property description "每日报告发送程序,在指定时间发送交易总结报告"
//--- 输入参数
input string DailyReportTime = "23:55"; // 每日报告时间 (HH:MM格式)
//--- 全局变量
int dailyReportHour = 23; // 报告小时
int dailyReportMinute = 55; // 报告分钟
bool dailyReportSentToday = false; // 今日是否已发送报告
datetime lastResetDate = 0; // 上次重置日期
//+------------------------------------------------------------------+
//| 专家初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 解析每日报告时间
if(!ParseDailyReportTime(DailyReportTime, dailyReportHour, dailyReportMinute))
{
Print("警告: 每日报告时间格式错误,使用默认时间23:55");
dailyReportHour = 23;
dailyReportMinute = 55;
}
Print("每日报告时间设置为: ", dailyReportHour, ":", dailyReportMinute);
// 设置定时器,每分钟检查一次
if(!EventSetTimer(60))
{
Print("错误: 无法设置定时器!");
return INIT_FAILED;
}
// 初始化重置日期
MqlDateTime today;
TimeToStruct(TimeCurrent(), today);
today.hour = 0;
today.min = 0;
today.sec = 0;
lastResetDate = StructToTime(today);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| 专家反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 移除定时器
EventKillTimer();
Print("每日报告程序已停止");
}
//+------------------------------------------------------------------+
//| 定时器事件处理函数 |
//+------------------------------------------------------------------+
void OnTimer()
{
CheckAndSendDailyReport();
}
//+------------------------------------------------------------------+
//| 解析每日报告时间函数 |
//+------------------------------------------------------------------+
bool ParseDailyReportTime(string timeStr, int &hour, int &minute)
{
string parts[];
int count = StringSplit(timeStr, ':', parts);
if(count != 2)
{
Print("错误: 时间格式不正确,应为 HH:MM");
return false;
}
hour = (int)StringToInteger(parts[0]);
minute = (int)StringToInteger(parts[1]);
if(hour < 0 || hour > 23 || minute < 0 || minute > 59)
{
Print("错误: 时间值超出范围,小时应在0-23,分钟应在0-59");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| 检查并发送每日报告函数 |
//+------------------------------------------------------------------+
void CheckAndSendDailyReport()
{
MqlDateTime currentTime;
TimeToStruct(TimeCurrent(), currentTime);
// 获取今天的日期(去除时间部分)
MqlDateTime today = currentTime;
today.hour = 0;
today.min = 0;
today.sec = 0;
datetime todayDate = StructToTime(today);
// 检查是否是新的一天
if(todayDate != lastResetDate)
{
dailyReportSentToday = false;
lastResetDate = todayDate;
Print("新的一天开始,重置报告发送标志");
}
// 检查是否到达报告时间
if(currentTime.hour == dailyReportHour &&
currentTime.min == dailyReportMinute &&
!dailyReportSentToday)
{
Print("到达报告时间,准备发送每日报告...");
if(SendDailySummaryReport())
{
dailyReportSentToday = true;
Print("每日报告已成功发送");
}
else
{
Print("错误: 发送每日报告失败");
}
}
}
//+------------------------------------------------------------------+
//| 发送每日总结报告函数 |
//+------------------------------------------------------------------+
bool SendDailySummaryReport()
{
// 这里实现具体的报告生成和发送逻辑
// 例如:收集交易数据、生成报告、通过邮件或通知发送
string reportContent = GenerateDailyReportContent();
// 示例:发送邮件通知
if(SendNotification("每日交易报告", reportContent))
{
Print("报告内容: ", reportContent);
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 生成每日报告内容函数 |
//+------------------------------------------------------------------+
string GenerateDailyReportContent()
{
string report = "";
// 获取今日日期
MqlDateTime today;
TimeToStruct(TimeCurrent(), today);
string dateStr = StringFormat("%04d-%02d-%02d", today.year, today.mon, today.day);
// 计算今日盈亏
double todayProfit = CalculateTodayProfit();
// 统计交易次数
int tradeCount = CalculateTodayTradeCount();
// 生成报告内容
report += "=== 每日交易报告 ===\n";
report += "日期: " + dateStr + "\n";
report += "今日盈亏: " + DoubleToString(todayProfit, 2) + " USD\n";
report += "交易次数: " + IntegerToString(tradeCount) + "\n";
report += "报告时间: " + TimeToString(TimeCurrent()) + "\n";
return report;
}
//+------------------------------------------------------------------+
//| 计算今日盈亏函数 |
//+------------------------------------------------------------------+
double CalculateTodayProfit()
{
double profit = 0.0;
// 设置时间范围为今日
MqlDateTime todayStart;
TimeToStruct(TimeCurrent(), todayStart);
todayStart.hour = 0;
todayStart.min = 0;
todayStart.sec = 0;
datetime startTime = StructToTime(todayStart);
// 获取今日交易记录
HistorySelect(startTime, TimeCurrent());
int totalDeals = HistoryDealsTotal();
for(int i = 0; i < totalDeals; i++)
{
ulong ticket = HistoryDealGetTicket(i);
if(ticket > 0)
{
profit += HistoryDealGetDouble(ticket, DEAL_PROFIT);
profit += HistoryDealGetDouble(ticket, DEAL_SWAP);
profit += HistoryDealGetDouble(ticket, DEAL_COMMISSION);
}
}
return profit;
}
//+------------------------------------------------------------------+
//| 计算今日交易次数函数 |
//+------------------------------------------------------------------+
int CalculateTodayTradeCount()
{
int count = 0;
// 设置时间范围为今日
MqlDateTime todayStart;
TimeToStruct(TimeCurrent(), todayStart);
todayStart.hour = 0;
todayStart.min = 0;
todayStart.sec = 0;
datetime startTime = StructToTime(todayStart);
// 获取今日交易记录
HistorySelect(startTime, TimeCurrent());
int totalDeals = HistoryDealsTotal();
for(int i = 0; i < totalDeals; i++)
{
ulong ticket = HistoryDealGetTicket(i);
if(ticket > 0)
{
ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE);
if(dealType == DEAL_TYPE_BUY || dealType == DEAL_TYPE_SELL)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| 发送通知函数 |
//+------------------------------------------------------------------+
bool SendNotification(string subject, string message)
{
// 这里实现具体的通知发送逻辑
// 可以是邮件、手机推送、平台通知等
// 示例:发送平台通知
if(SendNotification(subject, message))
{
return true;
}
// 示例:打印到日志
Print("通知: ", subject, " - ", message);
return true;
}

