好文章!
您推荐哪些货币对适用于该算法?
哪些时间框架?M5、M30 等。
哪个时段?
谢谢,并致以诚挚的问候
在 ExecutionAlgorithm.mqh 文件中,在下单时添加了 request.type_filling = ORDER_FILLING_IOC;一行,以解决下单问题。 在 H1 上进行了测试,它从未应用 SL 或 TP,所有交易都以亏损收盘。 在编译时还会产生警告
建议如何测试算法、
时间框架以及任何其他建议。
从 "长 "到 "双 "的类型转换可能导致数据丢失 VWAP.mqh 272 22
从 "long "到 "double "的类型转换可能导致数据丢失 VWAP.mqh 449 17
从 "long "到 "double "的类型转换可能导致数据丢失 PerformanceAnalyzer.mqh 222 17
从 "long "到 "double "的类型转换可能导致数据丢失 ExecutionManager.mqh 418 17
建议如何测试算法、
时间框架以及任何其他建议。
修复警告
在编译时也会产生警告
我更改了代码行
m_volumeProfile[intervalIndex] += rates[i].tick_volu
至
它修复了警告
现在需要您就我的其他疑问提供指导,如
时间框架
还有
为什么在回溯测试期间所有交易都导致亏损
如何测试您的这项伟大工作。
在编译时也会产生警告
从 "long "到 "double "的类型转换可能导致数据丢失 VWAP .mqh 272 22
从 "长 "到 "双 "的类型转换可能导致数据丢失 VWAP .mqh 449 17
从 "long "到 "double "的类型转换可能导致数据丢失 PerformanceAnalyzer .mqh 222 17
从 "long "到 "double "的类型转换可能导致数据丢失 ExecutionManager .mqh 418 17
我更改了代码行
m_volumeProfile[intervalIndex] += rates[i].tick_volu
至
m_volumeProfile[intervalIndex] += (double)rates[i].tick_volume;
它修复了警告
现在需要您就我的其他疑问提供指导,如
时间框架
还有
为什么在回溯测试期间所有交易都导致亏损
如何测试您的这项伟大工作。
i_vergo 可能会丢失数据 VWAP.mqh 271 41
从 "长 "到 "双 "的类型转换可能导致数据丢失 VWAP.mqh 272 22
从 "long "到 "double "的类型转换可能导致数据丢失 VWAP.mqh 449 17
从 "long "到 "double "的类型转换可能导致数据丢失 PerformanceAnalyzer.mqh 222 17
从 "long "到 "double "的类型转换可能导致数据丢失 ExecutionManager.mqh 418 17
建议如何测试算法、
时间框架以及任何其他建议。
警告不是问题所在,但可以很快解决。不过,如果作者能逐步说明他在回溯测试中使用了哪些设置和输入,那就再好不过了。
//+------------------------------------------------------------------+ //| 所有执行算法的基类| //+------------------------------------------------------------------+ class CExecutionAlgorithm { protected: string m_symbol; // 交易符号 double m_totalVolume; // 执行总量 double m_executedVolume; // 卷已执行 double m_remainingVolume; // 剩余执行量 datetime m_startTime; // 开始执行时间 datetime m_endTime; // 执行结束时间 int m_slippage; // 允许的滑移点数 bool m_isActive; // 算法当前是否处于活动状态 // 统计数据 double m_avgExecutionPrice; // 平均执行价格 int m_totalOrders; // 订单总数 int m_filledOrders; // 已成交订单的数量 public: // 构造函数 CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage); // 销毁器 virtual ~CExecutionAlgorithm(); // 由派生类实现的虚拟方法 virtual bool Initialize(); virtual bool Execute() = 0; virtual bool Update() = 0; virtual bool Terminate() = 0; // 常用方法 bool IsActive() { return m_isActive; } double GetExecutedVolume() { return m_executedVolume; } double GetRemainingVolume() { return m_remainingVolume; } double GetAverageExecutionPrice() { return m_avgExecutionPrice; } // 辅助方法 bool PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0); bool ModifyOrder(ulong ticket, double price, double sl, double tp); bool CancelOrder(ulong ticket); void UpdateAverageExecutionPrice(double price, double volume); // 获取适当填充模式的辅助方法 ENUM_ORDER_TYPE_FILLING GetFillingMode(); }; //+------------------------------------------------------------------+ //| 构造函数| //+------------------------------------------------------------------+ CExecutionAlgorithm::CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage) { m_symbol = symbol; m_totalVolume = volume; m_executedVolume = 0.0; m_remainingVolume = volume; m_startTime = startTime; m_endTime = endTime; m_slippage = slippage; m_isActive = false; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; } //+------------------------------------------------------------------+ //| 销毁器| //+------------------------------------------------------------------+ CExecutionAlgorithm::~CExecutionAlgorithm() { // 必要时清理资源 } //+------------------------------------------------------------------+ // | 初始化算法| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::Initialize() { // 验证输入 if(m_symbol == "" || m_totalVolume <= 0.0) { Print("Invalid inputs for execution algorithm"); return false; } // 检查符号是否存在 if(!SymbolSelect(m_symbol, true)) { Print("Symbol not found: ", m_symbol); return false; } // 重置统计数据 m_executedVolume = 0.0; m_remainingVolume = m_totalVolume; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; return true; } //+------------------------------------------------------------------+ //| 为符号获取合适的填充模式 //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CExecutionAlgorithm::GetFillingMode() { // 获取符号填充模式 int filling_modes = (int)SymbolInfoInteger(m_symbol, SYMBOL_FILLING_MODE); // 按偏好顺序检查可用的加注模式 if((filling_modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) return ORDER_FILLING_FOK; else if((filling_modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) return ORDER_FILLING_IOC; else return ORDER_FILLING_RETURN; } //+------------------------------------------------------------------+ //| 下订单| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0) { // 验证输入 if(volume <= 0.0) { Print("Invalid order volume"); return false; } // 准备请求 MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.symbol = m_symbol; request.volume = volume; request.type = orderType; request.deviation = m_slippage; request.magic = 123456; // 用于识别的神奇数字 // 根据订单类型设置适当的操作和价格 if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { // 市场订单 request.action = TRADE_ACTION_DEAL; request.type_filling = GetFillingMode(); if(orderType == ORDER_TYPE_BUY) request.price = SymbolInfoDouble(m_symbol, SYMBOL_ASK); else request.price = SymbolInfoDouble(m_symbol, SYMBOL_BID); } else { // 挂单 request.action = TRADE_ACTION_PENDING; if(price <= 0.0) { Print("Price must be specified for pending orders"); return false; } request.price = price; } // 发送订单 if(!OrderSend(request, result)) { Print("OrderSend error: ", GetLastError()); return false; } // 检查结果 if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderSend failed with code: ", result.retcode, " - ", result.comment); return false; } // 更新统计数据 m_totalOrders++; // 对于市场订单,立即更新执行统计数据 if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { m_filledOrders++; UpdateAverageExecutionPrice(request.price, volume); m_executedVolume += volume; m_remainingVolume -= volume; } Print("Order placed successfully. Ticket: ", result.order, " Volume: ", volume, " Price: ", request.price); return true; } //+------------------------------------------------------------------+ //| 修改现有订单| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::ModifyOrder(ulong ticket, double price, double sl, double tp) { // 准备请求 MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = price; request.sl = sl; request.tp = tp; // 发送修改请求 if(!OrderSend(request, result)) { Print("OrderModify error: ", GetLastError()); return false; } // 检查结果 if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderModify failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order modified successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| 取消现有订单| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::CancelOrder(ulong ticket) { // 准备请求 MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_REMOVE; request.order = ticket; // 发送取消请求 if(!OrderSend(request, result)) { Print("OrderCancel error: ", GetLastError()); return false; } // 检查结果 if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderCancel failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order cancelled successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| 更新平均执行价格| //+------------------------------------------------------------------+ void CExecutionAlgorithm::UpdateAverageExecutionPrice(double price, double volume) { // 计算新的平均执行价格 if(m_executedVolume > 0.0) { // 新旧价格的加权平均数 m_avgExecutionPrice = (m_avgExecutionPrice * m_executedVolume + price * volume) / (m_executedVolume + volume); } else { // 首次执行 m_avgExecutionPrice = price; } } //+------------------------------------------------------------------+
新文章 MQL5 中的高级订单执行算法:TWAP、VWAP 和冰山订单已发布:
“当然,”你可能会耸耸肩,“但我经手的又不是机构资金。”关键是:你完全不必这么做。无论你投入半手还是少量迷你手,波动性仍然会影响你的执行。这些工具可以帮助您:
低调行事:特别是冰山订单,可以隐藏您的真实订单规模,让窥探的算法难以猜测。
如今的民主化环境意味着,曾经需要数百万美元预算的执行技术现在可以在你的个人交易站上运行。通过将完善的 MQL5 代码(用于 TWAP、VWAP 和 Iceberg 策略)添加到您的平台中,您将拥有机构级的强大火力 —— 而无需离开散户领域。
作者:N Soumik