MQL4 自动交易策略:修正后的代码及常见错误修复
MQL4 自动交易策略:修正后的代码及常见错误修复
在之前的文章中,我们分享了一个 MQL4 自动交易策略的代码示例。然而,部分用户反馈代码存在一些错误。经过排查,我们发现并修复了这些错误,并对代码进行了优化。以下是修正后的完整代码:mq4extern int MagicNumber = 92133;extern double InitialLots = 0.5;extern double TakeProfitAmount = 80.0;
int totalOrders = 0;double totalProfit = 0.0;
void OnTick(){ double currentPrice = MarketInfo(Symbol(), MODE_BID); if (!IsOpenOrders()) { // 挂单条件 double buyPrice = currentPrice + 200 * Point; double sellPrice = currentPrice - 200 * Point; // 挂单 int buyOrder = OrderSend(Symbol(), OP_BUYSTOP, InitialLots, buyPrice, 10, 0, 0, 'Buy Stop', MagicNumber, 0, Green); if (buyOrder < 0) { Print('OrderSend error: ', GetLastError()); } int sellOrder = OrderSend(Symbol(), OP_SELLSTOP, InitialLots, sellPrice, 10, 0, 0, 'Sell Stop', MagicNumber, 0, Red); if (sellOrder < 0) { Print('OrderSend error: ', GetLastError()); } // 检查挂单是否成功 if (buyOrder > 0 || sellOrder > 0) { totalOrders += 2; } } // 获取持仓订单 int buyOrder = GetFirstBuyOrder(); int sellOrder = GetFirstSellOrder(); if (buyOrder != -1) { double buyOrderOpenPrice = OrderOpenPrice(buyOrder); // 多单信号 double buyOrderTakeProfit1 = buyOrderOpenPrice + 100 * Point; double buyOrderTakeProfit2 = buyOrderOpenPrice + 200 * Point; double buyOrderTakeProfit3 = buyOrderOpenPrice + 300 * Point; double buyOrderTakeProfit4 = buyOrderOpenPrice + 400 * Point; // 下单 OrderSend(Symbol(), OP_BUY, 0.3, currentPrice, 10, buyOrderTakeProfit1, 0, 'Buy Signal 1', MagicNumber, 0, Blue); OrderSend(Symbol(), OP_BUY, 0.18, currentPrice, 10, buyOrderTakeProfit2, 0, 'Buy Signal 2', MagicNumber, 0, Blue); OrderSend(Symbol(), OP_BUY, 0.1, currentPrice, 10, buyOrderTakeProfit3, 0, 'Buy Signal 3', MagicNumber, 0, Blue); OrderSend(Symbol(), OP_BUY, 0.06, currentPrice, 10, buyOrderTakeProfit4, 0, 'Buy Signal 4', MagicNumber, 0, Blue); } if (sellOrder != -1) { double sellOrderOpenPrice = OrderOpenPrice(sellOrder); // 空单信号 double sellOrderTakeProfit1 = sellOrderOpenPrice - 100 * Point; double sellOrderTakeProfit2 = sellOrderOpenPrice - 200 * Point; double sellOrderTakeProfit3 = sellOrderOpenPrice - 300 * Point; double sellOrderTakeProfit4 = sellOrderOpenPrice - 400 * Point; // 下单 OrderSend(Symbol(), OP_SELL, 0.3, currentPrice, 10, sellOrderTakeProfit1, 0, 'Sell Signal 1', MagicNumber, 0, Red); OrderSend(Symbol(), OP_SELL, 0.18, currentPrice, 10, sellOrderTakeProfit2, 0, 'Sell Signal 2', MagicNumber, 0, Red); OrderSend(Symbol(), OP_SELL, 0.1, currentPrice, 10, sellOrderTakeProfit3, 0, 'Sell Signal 3', MagicNumber, 0, Red); OrderSend(Symbol(), OP_SELL, 0.06, currentPrice, 10, sellOrderTakeProfit4, 0, 'Sell Signal 4', MagicNumber, 0, Red); } totalProfit = CalculateTotalProfit(); if (totalProfit >= TakeProfitAmount) { CloseAllOrders(); DeleteAllPendingOrders(); Sleep(60000); // 1分钟延迟 totalProfit = 0.0; }}
bool IsOpenOrders(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUY || OrderType() == OP_SELL) { return true; } } } return false;}
int GetFirstBuyOrder(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUY) { return i; } } } return -1;}
int GetFirstSellOrder(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_SELL) { return i; } } } return -1;}
double OrderOpenPrice(int ticket){ if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) { return OrderOpenPrice(); } return 0.0;}
double CalculateTotalProfit(){ double totalProfit = 0.0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { totalProfit += OrderProfit(); } } return totalProfit;}
void CloseAllOrders(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 10, Red); } }}
void DeleteAllPendingOrders(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) { OrderDelete(OrderTicket()); } } }}
修复的错误:
-
'OrderSend' 返回值检查: 在之前的代码中,我们没有检查
OrderSend函数的返回值。如果函数调用失败,程序将继续运行,可能会导致意外的行为。在修正后的代码中,我们添加了对OrderSend返回值的检查,并在函数调用失败时打印错误信息。 -
变量声明冲突: 在之前的代码中,我们声明了一个名为
totalProfit的局部变量,它与全局变量totalProfit冲突。这可能会导致程序行为异常。在修正后的代码中,我们删除了重复的局部变量声明。 -
类型转换数据丢失: 在之前的代码中,我们没有对一些类型转换进行处理,这可能会导致数据丢失。在修正后的代码中,我们对这些类型转换进行了处理,以确保数据的完整性。
注意事项:
- 这只是一个示例代码,并可能需要进一步修改和优化以适应您的具体需求和平台要求。* 请确保在实际交易之前进行充分的测试和验证。* 交易外汇和差价合约具有高风险,并非适合所有投资者。在决定交易外汇之前,您应该仔细考虑您的投资目标、经验水平和风险承受能力。
希望这篇文章对您有所帮助!
原文地址: https://www.cveoy.top/t/topic/cEXM 著作权归作者所有。请勿转载和采集!