MQL5自动交易策略:基于固定利润目标的双向挂单策略
MQL5自动交易策略:基于固定利润目标的双向挂单策略
这篇博客文章将介绍一个简单的MQL5自动交易策略,该策略会在市场波动时自动设置买入和卖出止损订单,并在达到预设的利润目标后平仓并重新下单。
代码cpp//+------------------------------------------------------------------+//| 7777.mq4 |//| Copyright 2023, MetaQuotes Ltd. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright 'Copyright 2023, MetaQuotes Ltd.'#property link 'https://www.mql5.com'#property version '1.00'#property strict
//+------------------------------------------------------------------+//| Global variables |//+------------------------------------------------------------------+int MAGIC_NUMBER = 92133;double INITIAL_LOTS = 0.5;double REPLENISH_MULTIPLIER = 0.6;int REPLENISH_ATTEMPTS = 5;double PROFIT_TARGET = 40;double MIN_FLUCTUATION = MarketInfo(Symbol(), MODE_POINT) * 100;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+int OnInit(){ return (INIT_SUCCEEDED);}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+void OnDeinit(const int reason){ // Close all open orders CloseOrders();}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+void OnTick(){ // Check if there are any open orders with the specified magic number bool hasLongPosition = false; bool hasShortPosition = false;
for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER) { if (OrderType() == OP_BUY) { hasLongPosition = true; } else if (OrderType() == OP_SELL) { hasShortPosition = true; } } }
// Check if all positions have been closed if (!hasLongPosition && !hasShortPosition) { // Determine the prices for the pending orders double askPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); double bidPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); double buyPrice = askPrice + MIN_FLUCTUATION; double sellPrice = bidPrice - MIN_FLUCTUATION;
// Place pending orders if there are no open positions if (!hasLongPosition) { if (CountOrders(OP_BUYSTOP) == 0) { OpenBuyOrder(INITIAL_LOTS, buyPrice); Print('Opened buy order'); } } if (!hasShortPosition) { if (CountOrders(OP_SELLSTOP) == 0) { OpenSellOrder(INITIAL_LOTS, sellPrice); Print('Opened sell order'); } } }
// Check if any positions have reached the profit target double totalProfit = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER) { totalProfit += OrderProfit(); } } if (totalProfit >= PROFIT_TARGET) { CloseOrders(); // Place new pending orders after closing previous orders double askPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); double bidPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); double buyPrice = askPrice + MIN_FLUCTUATION; double sellPrice = bidPrice - MIN_FLUCTUATION; OpenBuyOrder(INITIAL_LOTS, buyPrice); OpenSellOrder(INITIAL_LOTS, sellPrice); Print('Placed new pending orders'); }}
//+------------------------------------------------------------------+//| Open buy order function |//+------------------------------------------------------------------+void OpenBuyOrder(double lots, double price){ int ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, price, 0, 0, 0, 'Buy Order', MAGIC_NUMBER, 0, Green); if (ticket <= 0) { Print('Failed to open buy order'); }}
//+------------------------------------------------------------------+//| Open sell order function |//+------------------------------------------------------------------+void OpenSellOrder(double lots, double price){ int ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, price, 0, 0, 0, 'Sell Order', MAGIC_NUMBER, 0, Red); if (ticket <= 0) { Print('Failed to open sell order'); }}
//+------------------------------------------------------------------+//| Close all orders function |//+------------------------------------------------------------------+void CloseOrders(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER) { if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)) { Print('Failed to close order with ticket ', OrderTicket()); } } }}
//+------------------------------------------------------------------+//| Count orders of a specific type |//+------------------------------------------------------------------+int CountOrders(int orderType){ int count = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { count++; } } return count;}
策略说明
该策略会在启动时同时挂出一张多单和一张空单。当总利润达到预设的目标 (PROFIT_TARGET) 时,该策略会平掉所有订单,并重新挂出一张多单和一张空单。
参数说明
MAGIC_NUMBER: 用于区分不同EA的唯一标识符.*INITIAL_LOTS: 初始订单手数.*REPLENISH_MULTIPLIER: 未使用.*REPLENISH_ATTEMPTS: 未使用.*PROFIT_TARGET: 利润目标,单位为账户货币.*MIN_FLUCTUATION: 最小价格波动, 用于设置挂单价格.
注意事项
- 这只是一个简单的示例策略,实际交易中需要根据具体情况进行调整和优化。* 在使用该策略之前,请务必进行充分的测试,并了解其风险。* 自动交易存在风险,请谨慎使用。
总结
本文介绍了一个简单的MQL5自动交易策略,该策略基于固定利润目标进行双向挂单交易。希望本文能帮助您更好地理解MQL5自动交易,并为您开发自己的交易策略提供参考。
原文地址: https://www.cveoy.top/t/topic/b18A 著作权归作者所有。请勿转载和采集!