如何在MQL5中自动创建带不同标识符的一维数组列表?
在MQL5中创建带独立名称的一维数组列表
你需要的是管理多个独立的一维数组,每个数组拥有唯一的名称/标识符,CArray确实只能存储单一类型的元素并堆叠,无法满足你的需求。这里提供两种实用的实现方式:
方法一:使用结构体数组(简单直接)
通过定义包含名称和数组的结构体,再创建该结构体的数组来管理所有一维数组。这种方式无需依赖复杂的类,适合轻量场景:
// 定义存储带名称数组的结构体 struct NamedArray { string name; // 数组的唯一标识符 double array[]; // 一维数组(可根据需求修改类型,如int、string) }; NamedArray g_namedArrays[]; // 全局数组列表,也可定义为局部变量 // 添加新的带名称数组,返回是否成功 bool AddNamedArray(string arrayName, double initialData[] = NULL) { // 检查是否存在同名数组 for(int i = 0; i < ArraySize(g_namedArrays); i++) { if(g_namedArrays[i].name == arrayName) { Print("错误:数组 ", arrayName, " 已存在"); return false; } } // 扩展结构体数组 int newIdx = ArrayResize(g_namedArrays, ArraySize(g_namedArrays) + 1); if(newIdx == -1) { Print("错误:无法扩展数组列表"); return false; } // 设置数组名称 g_namedArrays[newIdx].name = arrayName; // 复制初始数据(如果提供) if(initialData != NULL && ArraySize(initialData) > 0) { ArrayCopy(g_namedArrays[newIdx].array, initialData); } return true; } // 根据名称查找数组的索引,未找到返回-1 int GetNamedArrayIndex(string arrayName) { for(int i = 0; i < ArraySize(g_namedArrays); i++) { if(g_namedArrays[i].name == arrayName) { return i; } } return -1; } // 示例用法 void OnStart() { double priceData[] = {1.2345, 1.2350, 1.2348}; double volData[] = {1000, 1500, 800, 1200}; // 添加两个带名称的数组 AddNamedArray("eurusd_prices", priceData); AddNamedArray("eurusd_volumes", volData); // 获取并操作eurusd_prices数组 int idx = GetNamedArrayIndex("eurusd_prices"); if(idx != -1) { Print("eurusd_prices数组元素:"); for(int i = 0; i < ArraySize(g_namedArrays[idx].array); i++) { Print(g_namedArrays[idx].array[i]); } } }
方法二:使用CArrayObj结合自定义类(灵活扩展)
如果需要更灵活的管理(比如动态添加/删除、排序、批量操作),可以用CArrayObj存储封装了数组和名称的自定义类对象:
// 自定义类,封装带名称的一维数组 class CNamedArray : public CObject { private: string m_name; double m_array[]; // 可修改为你需要的数组类型 public: // 构造函数:初始化数组名称 CNamedArray(string arrayName) : m_name(arrayName) {} // 获取数组名称 string GetName() const { return m_name; } // 获取数组引用,用于直接操作数组元素 double& GetArray() { return m_array[0]; } // 获取数组当前大小 int GetArraySize() const { return ::ArraySize(m_array); } // 复制外部数据到当前数组 bool CopyFrom(double source[]) { if(source == NULL) return false; return ArrayCopy(m_array, source) != -1; } }; CArrayObj g_arrayManager; // 全局数组对象管理器 // 添加新的带名称数组 bool AddNamedArray(string arrayName, double initialData[] = NULL) { // 检查同名数组是否存在 for(int i = 0; i < g_arrayManager.Total(); i++) { CNamedArray* arrObj = (CNamedArray*)g_arrayManager.At(i); if(arrObj != NULL && arrObj.GetName() == arrayName) { Print("错误:数组 ", arrayName, " 已存在"); return false; } } // 创建新的数组对象 CNamedArray* newArrObj = new CNamedArray(arrayName); if(newArrObj == NULL) { Print("错误:无法创建数组对象"); return false; } // 复制初始数据 if(initialData != NULL && ArraySize(initialData) > 0) { newArrObj.CopyFrom(initialData); } // 添加到管理器 if(!g_arrayManager.Add(newArrObj)) { delete newArrObj; Print("错误:无法添加数组到管理器"); return false; } return true; } // 根据名称查找数组对象,未找到返回NULL CNamedArray* FindNamedArray(string arrayName) { for(int i = 0; i < g_arrayManager.Total(); i++) { CNamedArray* arrObj = (CNamedArray*)g_arrayManager.At(i); if(arrObj != NULL && arrObj.GetName() == arrayName) { return arrObj; } } return NULL; } // 示例用法 void OnStart() { double retData[] = {0.01, -0.005, 0.008}; double volData[] = {2.3, 1.8, 2.5}; AddNamedArray("daily_returns", retData); AddNamedArray("volatility", volData); // 查找并操作daily_returns数组 CNamedArray* retArray = FindNamedArray("daily_returns"); if(retArray != NULL) { Print("daily_returns数组元素:"); for(int i = 0; i < retArray.GetArraySize(); i++) { Print(retArray.GetArray()[i]); } } // 程序结束时清理资源(避免内存泄漏) g_arrayManager.Clear(true); }
两种方法对比
- 结构体数组:实现简单,无需面向对象知识,适合小型、固定数量的数组管理。
- 类+CArrayObj:支持动态增删、批量操作,扩展性强,适合复杂场景,但需要掌握MQL5的类和CArrayObj用法。
内容的提问来源于stack exchange,提问作者Razor
相关产品推荐
相关产品推荐

