- 显示:
- 267
- 等级:
- 已发布:
-
需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务
CBitBuffer 类 - MQL5 中的位级数据序列化
CBitBuffer 类为 MQL5 中的位级数据序列化提供了强大的基础,可对数据存储和检索进行细粒度控制。该类支持各种数据类型,包括可变长度整数(使用 ZigZag 编码的 VLQ)以及字符串和结构的序列化,非常适合优化空间。该类采用了内部缓冲和指数数组增长等优化措施来提高性能,并提供了全面的错误处理系统。它对网络通信或文件存储特别有用,因为在网络通信或文件存储中,最小化数据大小至关重要(例如,压缩 tick 数据)。
主要功能
- 位级操作:允许逐位写入和读取数据,或以指定位长度写入和读取数据,最高可达 64 位。
- 数据类型支持:包括 bool、char、uchar、short、ushort、int、uint、long、ulong、datetime、float、double、string 和 struct 的方法。
- 变长整数 (VLQ): 为 int、uint、long 和 ulong 值执行 VLQ 编码,可大大节省经常使用的小整数值的空间。
- 错误处理 提供了一个 ENUM_BIT_BUFFER_ERROR 枚举和 GetLastError()/GetLastErrorString() 方法,以进行稳健的错误管理。
- 缓冲区管理:提供用于清除、最终确定、设置原始缓冲区内容、保存到文件和从文件加载的函数。
- 内部缓冲 使用内部 64 位缓冲区(m_writeBufferInternal、m_readBufferInternal),通过在向主 ulong[] 数组写入或读取之前累积位来优化位级操作。
//+------------------------------------------------------------------+ //| CBitBuffer 类| //| 向 ulong[] 缓冲区读/写单个位或位序列。| //| 支持高效位操作和混合读/写操作。 //+------------------------------------------------------------------+ class CBitBuffer { public: // 核心位操作 bool WriteBit(bool bit); // 写入一个比特 bool WriteBits(ulong value, int numberOfBits); // 从 ulong 中写入 N 位 bool ReadBit(); // 读取一个比特 ulong ReadBits(int numberOfBits); // 将 N 位读作 ulong ulong PeekBits(int numberOfBits); // 读取 N 位,不前进位置 public: // 位置和尺寸管理 bool SetReadPosition(long bitPosition); // 以位为单位设置读取位置 long GetReadPosition(); bool ResetReadPosition(); // 将读取位置重置为 0 bool SkipBits(long bitsToSkip); // 跳过当前读取位置的 N 位 long GetTotalWrittenBits(); // 写入的总位数 long GetTotalBytesWritten(); // 写入的总字节数 long GetTotalBytesAllocated(); // 分配的字节总数 long GetRemainingReadBits(); // 要读取的剩余位 public: // 数据类型特定的读/写操作 bool WriteBool(bool value); bool WriteChar(char value); bool WriteUChar(uchar value); bool WriteShort(short value); bool WriteUShort(ushort value); bool WriteInt(int value); bool WriteUInt(uint value); bool WriteLong(long value); bool WriteULong(ulong value); bool WriteDatetime(datetime value); bool WriteFloat(float value); // 写入 32 位浮点数 bool WriteDouble(double value); // 写入一个 64 位二进制数 bool WriteString(string value); // 写入带长度前缀的字符串 template<typename T> bool WriteStruct(T &struct_object); // 写入带有长度前缀的结构 bool ReadBool(); char ReadChar(); uchar ReadUChar(); short ReadShort(); ushort ReadUShort(); int ReadInt(); uint ReadUInt(); long ReadLong(); ulong ReadULong(); datetime ReadDatetime(); float ReadFloat(); // 读取 32 位浮点数 double ReadDouble(); // 读取 64 位二进制数 string ReadString(); // 读取带长度前缀的字符串 template<typename T> T ReadStruct(); // 读取带有长度前缀的结构 public: // 整数可变长度编码 (VLQ) bool WriteVarInt(int value); // 使用 ZigZag + VLQ 写入带符号的 int bool WriteVarUInt(uint value); // 使用 VLQ 写入无符号 int bool WriteVarLong(long value); // 使用 ZigZag + VLQ 写入带符号的长文本 bool WriteVarULong(ulong value); // 使用 VLQ 写入无符号 long int ReadVarInt(); // 使用 ZigZag + VLQ 读取带符号的 int uint ReadVarUInt(); // 使用 VLQ 读取无符号 int long ReadVarLong(); // 使用 ZigZag + VLQ 读取带符号的长文本 ulong ReadVarULong(); // 使用 VLQ 读取无符号 long public: // 缓冲区管理 void Clear(); // 清除缓冲区内容并重置状态 bool GetFinalizedBuffer(ulong &destinationArray[]); // 将缓冲区内容复制到数组 bool SetRawBuffer(const ulong &sourceBuffer[]); // 从数组中设置缓冲区内容 bool Save(string filename); // 将缓冲区保存到文件中 bool Load(string filename); // 从文件加载缓冲区 public: // 错误处理 ENUM_BIT_BUFFER_ERROR GetLastError(); // 返回最后一个错误代码 string GetLastErrorString(); // 返回错误描述字符串 void ClearLastError() ; // 清除最后一个错误 void PrintHex(); // 以十六进制打印主缓冲区(调试) };
上面提供的完整测试示例 " CBitBuffer_Test.mq5 " 是检测错误和验证该类功能的最佳方法。
更新:
2025.07.21 - v.1.01 :
- CBitBuffer 类主动防止在读取操作开始后非法尝试写入,这有助于维护数据完整性。
- 当用户尝试混合操作时,会收到一个特定错误 (BIT_BUFFER_MIXED_OPERATION_ERROR)。
2025.07.22 - v.1.02 :
- 修改了类的设计,通过正确处理部分 刷新/重新填充,允许混合读 /写操作 ,这有助于在读写模式之间切换时保持数据的完整性。
- 删除了变量 (m_operationMode) 和错误代码 (BIT_BUFFER_MIXED_OPERATION_ERROR)。
- 清理了代码注释,使意图更清晰。
- 更新了 "CBitBuffer_Test.mq5" 中的示例,以涵盖更多的测试用例。
由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/61728
Boom Index Spike Pattern
该 MetaTrader 5 (MT5) 自定义指标 boomSpikeBoxMitigationFinal.mq5 可检测图表上的特定看涨尖峰形态,并使用矩形和水平线标记进入区域。一旦价格返回("缓解")入口水平,入口线就会缩短至缓解点。
Moving Price Line Indicator MT5
这个简单的指标可以轻松找出价格何时到达任何蜡烛或时间框架上的特定时间。