每日交易盈亏统计指标
副图显示柱状图,每根柱子代表一天的累计盈亏,绿色盈利、红色亏损
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#property copyright "XAUOF 指标工坊"
#property version "1.00"
#property description "统计账户历史订单,按平仓日期分组,显示每日累计盈亏"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrGreen
#property indicator_width1 2
#property indicator_label1 "每日盈亏"
// ===== 参数设置 =====
input int ShowDays = 30; // 显示最近多少天的数据(推荐:30)
// ===== 全局变量 =====
double pnlBuffer[]; // 绘图缓冲区:每天的盈亏
datetime dayArray[]; // 存储每个柱子对应的日期
//+------------------------------------------------------------------+
//| 初始化 |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, pnlBuffer, INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
IndicatorSetString(INDICATOR_SHORTNAME, "每日交易盈亏");
ArrayResize(dayArray, ShowDays);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| 主计算函数 |
//+------------------------------------------------------------------+
已显示前 35 行,共 175 行。完整源码仅对 xauusd.team VIP 开放查看与复制。
开通 VIP 查看完整源码作品说明
明白了。这是MT Commander的交易统计表格视图——显示每天的开平仓数据、盈亏统计。我来写一个指标,在副图用柱状图显示每天的累计盈亏,类似这个表格的"日盈亏"列。
思路:
- 遍历账户历史订单(OrderHistory),按平仓日期分组
- 同一天的所有平仓订单盈亏相加 = 该天的日盈亏
- 用柱状图显示(正数绿色、负数红色)
- 鼠标悬停时显示该天的详细数据
问题:上面的代码有个缺陷——PlotIndexSetInteger 的颜色设置在循环里重复调用会导致每根柱子都是同一个颜色。让我用更恰当的方式重写:
```cpp // filename: DailyPnLStatistic.mq5 // title: 每日交易盈亏统计指标 // summary: 副图显示柱状图,每根柱子代表一天的累计盈亏,绿色盈利、红色亏损
#property copyright "XAUOF 指标工坊" #property version "1.00" #property description "统计账户历史订单,按平仓日期分组,显示每日累计盈亏" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_HISTOGRAM #property indicator_color1 clrGreen, clrRed #property indicator_width1 3 #property indicator_label1 "每日盈亏"
// ===== 参数设置 ===== input int ShowDays = 30; // 显示最近多少天的数据(推荐:30)
// ===== 全局变量 ===== double pnlBuffer[]; // 绘图缓冲区:每天的盈亏 double pnlColor[]; // 颜色索引缓冲区(0=绿色,1=红色)
//+------------------------------------------------------------------+ //| 初始化 | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, pnlBuffer, INDICATOR_DATA); SetIndexBuffer(1, pnlColor, INDICATOR_COLOR_INDEX);
IndicatorSetString(INDICATOR_SHORTNAME, "每日交易盈亏");
return INIT_SUCCEEDED; }
//+------------------------------------------------------------------+ //| 主计算函数 | //+------------------------------------------------------------------+ 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[]) { // 清空缓冲区 ArrayInitialize(pnlBuffer, EMPTY_VALUE); ArrayInitialize(pnlColor, 0);
// 获取当前时间 datetime now = TimeCurrent();
// ===== 第一步:从历史订单统计每天的盈亏 ===== int historyCount = HistoryDealsTotal();
if(historyCount == 0) { return rates_total; }
// 创建临时数组存储日期和盈亏 datetime tempDates[]; double tempPnL[]; int tempCount = 0;
ArrayResize(tempDates, 0); ArrayResize(tempPnL, 0);
// 遍历所有历史交易 for(int i = 0; i < historyCount; i++) { ulong dealTicket = HistoryDealGetTicket(i); if(dealTicket == 0) continue;
// 只统计平仓的交易 ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(dealTicket, DEAL_TYPE); if(dealType != DEAL_TYPE_BUY && dealType != DEAL_TYPE_SELL) continue;
// 获取平仓时间和盈亏 datetime closeTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME); double profit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);
// 获取交易日期(转换为该天00:00:00) MqlDateTime dt; TimeToStruct(closeTime, dt); dt.hour = 0; dt.min = 0; dt.sec = 0; datetime tradeDate = StructToTime(dt);
// 检查是否在统计范围内 if(now - tradeDate > ShowDays * 86400) continue;
// 找到该日期在临时数组中的位置 int dateIndex = -1; for(int j = 0; j < tempCount; j++) { if(tempDates[j] == tradeDate) { dateIndex = j; break; } }
if(dateIndex == -1) { // 新日期 ArrayResize(tempDates, tempCount + 1); ArrayResize(tempPnL, tempCount + 1); tempDates[tempCount] = tradeDate; tempPnL[tempCount] = profit; tempCount++; } else { // 已存在,累加盈亏 tempPnL[dateIndex] += profit; } }
// ===== 第二步:按日期从旧到新排序 ===== for(int i = 0; i < tempCount - 1; i++) { for(int j = i + 1; j < tempCount; j++) { if(tempDates[i] > tempDates[j]) { // 交换日期 datetime tempDate = tempDates[i]; tempDates[i] = tempDates[j]; tempDates[j] = tempDate;
// 交换盈亏 double tempProfit = tempPnL[i]; tempPnL[i] = tempPnL[j]; tempPnL[j] = tempProfit; } } }
// ===== 第三步:填充绘图缓冲区 ===== int plotCount = MathMin(tempCount, rates_total); for(int i = 0; i < plotCount; i++) { int barIndex = rates_total - plotCount + i; if(barIndex >= 0 && barIndex < rates_total) { pnlBuffer[barIndex] = tempPnL[i];
// 根据盈亏设置颜色(正数绿色=0,负数红色=1) if(tempPnL[i] >= 0) { pnlColor[barIndex] = 0; // 绿色 } else { pnlColor[barIndex] = 1; // 红色 } } }
ArrayFree(tempDates); ArrayFree(tempPnL);
return rates_total; }
//+------------------------------------------------------------------+ //| 反初始化 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ArrayFree(pnlBuffer); ArrayFree(pnlColor); } ```
使用说明
- 安装:将代码保存为
DailyPnLStatistic.mq5,放入MQL5\Indicators文件夹,重启 MT5 后在指标列表中找到该指标。
- 参数调整:
ShowDays参数控制显示最近多少天的数据,默认 30 天,可根据需要调整。
- 图表显示:指标在副图(独立窗口)显示柱状图,每根柱子代表一天的累计盈亏。绿色柱子表示该天盈利,红色柱子表示该天亏损。
- 数据来源:统计的是账户历史交易记录中已平仓的订单盈亏,按平仓时间所在的自然日分组。
- 计算规则:同一天内平仓的所有订单盈亏相加 = 该天的日盈亏值。
- 颜色说明:绿色柱=该天净盈利,红色柱=该天净亏损,空白处=该天无交易。
- 注意事项:指标只读取历史数据,不会自动更新持仓的浮动盈亏。若需实时看持仓浮亏,请在 MT5 的交易面板中查看。
- 性能:数据量较大时计算会耗时,建议
ShowDays不超过 90 天。
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个MT5副图指标,用来追踪你账户每天的收益情况。它从交易历史里自动找出每天平仓的所有订单,把盈亏加起来显示成柱状图——盈利的柱子是绿色,亏损的柱子是红色。相当于每天给你的账户做个体检,一眼看清哪些天赚钱、哪些天赔钱。
逻辑原理
指标的工作流程是这样的:
- 扫描历史订单:遍历账户的所有已平仓订单(买单和卖单),获取平仓时间和盈亏金额。
- 按日期分组:把同一天平仓的所有订单盈亏加起来,得到该天的累计盈亏。比如今天平仓了3笔单子,分别赚100、50、亏20,那今天的日盈亏就是 100 + 50 - 20 = 130。
- 着色显示:正数(盈利)画成绿色柱子,负数(亏损)画成红色柱子。
- 时间范围:只显示最近N天的数据,默认是30天。比你一个月的交易情况一目了然。
需要注意的是,指标统计的是已平仓订单的盈亏,不包括正在持仓中的订单。
参数说明
- ShowDays(默认值:30):显示最近多少天的数据。改成7就看周报,改成60就看两个月。建议不要超过100,数据太多图表会很拥挤。
怎么用
- 把代码保存为 .mq5 文件,放进 MT5 的 Indicators 文件夹。
- 打开任何品种的图表(XAUUSD、EURUSD 都行)。
- 在菜单栏选「插入 → 指标 → 自定义」,找到这个指标加载。
- 它会在图表下面的副图区显示出来,每根柱子代表一天。
- 绿柱子就是那天赚的,红柱子就是那天赔的,一目了然。
适用场景
- 日内交易者:想快速查看每天的收益波动。
- 波段交易者:梳理最近一两个月的交易成果。
- 任何交易品种:指标从账户历史里读数据,不限品种,什么都能用。
- 任何周期的图表:指标在副图,不影响K线显示,挂在任何周期都行。
不适合用在:
- 只想看未平仓订单:这个指标只统计已经平仓的单子,还在持仓的看不到。
风险提示
- 历史数据有限制:MT5 只保存有限的交易历史(通常是最近几个月),超出范围的订单看不到。如果你想查看更早的数据,需要手动导出历史或确保MT5的历史记录设置足够长。
- 不计手续费和隔夜费:
DEAL_PROFIT这个字段已经包含手续费和交换(隔夜费),但如果你的账户配置特殊,可能有其他费用不会算进去。
- 兑换货币问题:如果你的账户基础货币不是美元,显示的盈亏是以交易的字货币计,不是账户基础货币。比如账户是欧元,交易XAUUSD,显示的是美元盈亏。
- 时间同步:副图显示的是按K线排列的,如果你切换时间框架,柱子的位置可能会变。这是正常的。
- 重绘:指标不会重绘历史数据,每根柱子一旦确定就不会改变,因为它统计的是已平仓的历史订单。
常见问题
- 这个指标会重绘吗?
- 不会。指标统计的是已平仓订单,这些数据不会变,所以柱子不会重绘。
- 可以用在XAUUSD以外的品种吗?
- 可以。指标从账户历史里读数据,不限特定品种。挂在任何图表上都能显示整个账户的日盈亏。
- MT4能用吗?
- 不能。这个指标是MQL5写的,只能在MT5上用。MT4需要另外改写。
- 参数默认的30天适合什么周期?
- 30天是日历天数,和图表周期无关。你可以挂在1分钟图或日图上,显示的都是最近30天的每日盈亏。
- 历史数据不完整怎么办?
- MT5只保存有限的历史订单(通常是最近几个月)。如果看不到更早的数据,需要在MT5设置里增加历史记录的保存长度,或导出交易报告。
Daily P&L Statistic Indicator for MT5
A sub-window indicator that displays daily cumulative profit and loss as histogram bars. Green bars represent daily profits, red bars represent daily losses. The indicator automatically aggregates closed trades by date from account history and supports customizable day range.
A short source preview is shown above for visitors; full source, copy and compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。