在 MQL5 中实现电子表格:CTable 二维数据类
一、为什么需要表格类
Excel 太重,而指标与 EA 内部经常需要“异质二维数据”:一行里既有字符串标签、又有数值、还有时间。原生二维数组只能存单一类型,CTable 用 Variant 思路弥补这一缺口。
二、CTable 的接口
CTable 采用“先列后行”的两步构造:FirstResize 用类型数组定列结构,SecondResize 用整数定行数。这借鉴了 C++ 中 Variant 单列特例的思想。
class CTable
{
public:
void FirstResize(const ENUM_DATATYPE &TYPE[]); // 设列类型
void SecondResize(int j); // 设行数
int FirstSize(void); // 列数
int SecondSize(void); // 行数
void CopyTable(const CTable &src); // 深拷贝
bool Change(...);
bool Insert(...);
};
三、FirstResize / SecondResize 语义
FirstResize 接收 ENUM_DATATYPE 数组,长度即列数,每个元素声明该列单元格类型;行数此时无需指定,由 SecondResize 后续给出。这种分离让对象可作为函数参数传递后再划分。
四、单元格类型与 Variant
五、CopyTable 与性能
CopyTable 做深拷贝,避免两个 CTable 指向同一底层缓冲产生别名 bug。在性能敏感路径,仍建议退回单一类型原生二维数组。
void CTable::CopyTable(const CTable &src)
{
// 逐列按类型深拷贝,避免别名
for(int c=0; c<FirstSize(); c++)
CopyCol(c, src);
}
六、实战用途
- 回测结果汇总表(品种/周期/收益/回撤混合)。
- 多品种实时状态表(价格/信号/持仓混合)。
- 导出 HTML/CSV 前的格式化缓冲。
七、CTable 布局模型
CTable 是标准库里把数据画成「电子表格」的控件:行、列、单元格三层结构,先定义列数、列宽、行高,再把数据填进单元格。它把「表格展示」从手画矩形变成声明式布局,省掉大量坐标计算。
布局上支持自动列宽、单元格对齐、分隔线,足以做出现代感的面板。理解「行列模型」后,任何结构化数据(成交、持仓、统计)都能直接可视化。
八、单元格读写与样式
写入就是 table.SetValue(row, col, text) 之类,读数对应 GetValue。样式(颜色、字体、对齐)可逐单元格设,也能按行/列统一设,比如盈利行标绿、亏损行标红,信息密度高且一眼可读。
table.SetValue(0, 0, "品种"); table.SetValue(0, 1, "净盈亏"); table.SetCellColor(1, 1, profit>0 ? clrLime : clrRed); table.Update();
九、实战:把成交记录画成表格
最实用的场景:遍历 HistoryDealsTotal,把每笔成交的时间、品种、方向、净盈亏填进 CTable,实时刷新。比起在日志里翻,表格化让绩效一眼可见,也方便截图复盘或分享。
刷新节奏用定时器(每秒一次足够),别每 tick 重绘大表;数据多时只保留最近 N 笔,避免表格无限增长拖慢终端。
十、大数据量下的性能
表格行数很多时(如几千笔历史成交),每次全量重绘会拖慢终端。做法是分页或只保留最近 N 笔可见,滚动时再加载;样式也只在数据变化时重设,别每帧重画整表。
另一个技巧是把表格对象缓存、只更新变动的单元格而非重建整表。CTable 本身已做了不少优化,配合「增量更新」思路,万行数据也能流畅展示。
十一、CTable 与交互
进阶可让表格可点:监听 OnChartEvent,点到某行就高亮并在旁边画出该笔成交的入场出场箭头,做成一个可交互的绩效复盘面板,比静态表格有用得多。
交互要注意点击坐标到行号的反查,以及点击后只更新高亮而非重建整表。把 CTable 当「数据视图」而非一次性截图,它的价值才真正释放。 配合定时器增量刷新,它就是一个常驻的轻量绩效终端,比反复导 CSV 看省事得多。
十二、小结
CTable 不是要取代 Excel,而是给 MQL5 一个轻量的“表格思维”工具。理解它的两步构造与 Variant 本质,能少写很多胶水代码。