当前位置:首页 > 量化|编程

【MT5】周期性 定时发送报告 函数

2个月前 (11-18)量化|编程风控哥

程序功能说明:

  1. 1.时间设置:通过输入参数DailyReportTime设置每日报告时间,格式为"HH:MM"

  2. 2.定时检查:使用定时器每分钟检查一次是否到达报告时间

  3. 3.每日重置:程序会在每天自动重置发送标志,确保每天只发送一次报告

  4. 4.报告内容:包含今日盈亏、交易次数等基本信息

  5. 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;
}


标签: 量化编程
分享给朋友:

“【MT5】周期性 定时发送报告 函数” 的相关文章

《MT5编程入门教程》课程大纲

《MT5编程入门教程》课程大纲

一份真正面向零基础小白的《MT5编程入门教程》课程大纲。这套大纲遵循从易到难、理论与实践结合的原则,旨在让完全没有编程经验的交易者也能轻松入门。…

【MT5】创建箭头标识函数 OBJ_ARROW

【MT5】创建箭头标识函数 OBJ_ARROW

调用函数方法:crearFlecha("Bear_Dominanat"+IntegerToString(i),time[i],high[i],clr,226,ANCHOR_BOTTOM,300); crearFlecha("Bull_Dominanat"+I…

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。