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自动交易,并为您开发自己的交易策略提供参考。

MQL5自动交易策略:基于固定利润目标的双向挂单策略

原文地址: https://www.cveoy.top/t/topic/b18A 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录