//+------------------------------------------------------------------+ //| SampleEA_RSI.mq4 | //| Copyright 2021, binjie09 | //| https://www.mql5.com | //+------------------------------------------------------------------+

#property copyright 'Copyright 2021, binjie09' #property link 'https://www.mql5.com' #property version '1.03' #property strict

// 外部输入参数 extern double Lots = 0.05; // 每次交易手数 extern double MaxLots = 0.1; // 总持仓不超过手数 extern double TakeProfit = 10000; // 止盈点数 extern int RSI_Period = 20; // RSI指标周期 extern int MACD_FastEMA = 12; // MACD快速移动平均线周期 extern int MACD_SlowEMA = 26; // MACD慢速移动平均线周期 extern int MACD_SignalEMA = 9; // MACD信号线移动平均线周期

// 判断是否能够交易,true表示可以交易,false表示无法交易 bool CanTrade() { double accountLots = 0.0; int totalOrders = OrdersTotal(); for (int i = 0; i < totalOrders; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == 0) { accountLots += OrderLots(); } } } return (accountLots + Lots <= MaxLots); }

// 根据RSI指标进行交易 void TradeByIndicators(double RSI_M15, double RSI_M30, double RSI_H1, double RSI_H4, double MACD_main, double MACD_signal) { // MACD向上突破零轴,平仓所有空单并只做多单 if (MACD_main > 0 && MACD_signal > 0) { int totalOrders = OrdersTotal(); for (int i = 0; i < totalOrders; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == 0 && OrderType() == OP_SELL) { bool closeResult = OrderClose(OrderTicket(), OrderLots(), Bid, 3, Red); if (!closeResult) { Print('Failed to close sell order. Error code: ', GetLastError()); } } } }

    if ((RSI_M15 < 30 || (RSI_M30 < 30 && MACD_main > MACD_signal) || RSI_H1 < 30 || RSI_H4 < 30) && CanTrade()) {
        double openPrice = Ask;
        int ticket = OrderSend(Symbol(), OP_BUY, Lots, openPrice, 3, 0, openPrice + TakeProfit * Point, NULL, 0, 0, Blue);
        if (ticket > 0) {
            Comment('Opened 多单成功,交易手数为:', Lots, ',开仓价格为:', DoubleToString(openPrice));
        } else {
            Print('Failed to open buy order. Error code: ', GetLastError());
        }
    }
} 
// MACD向下突破零轴,平仓所有多单并只做空单
else if (MACD_main < 0 && MACD_signal < 0) {
    int totalOrders = OrdersTotal();
    for (int i = 0; i < totalOrders; i++) {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == 0 && OrderType() == OP_BUY) {
                bool closeResult = OrderClose(OrderTicket(), OrderLots(), Ask, 3, Blue);
                if (!closeResult) {
                    Print('Failed to close buy order. Error code: ', GetLastError());
                }
            }
        }
    }

    if ((RSI_M15 > 70 || (RSI_M30 > 70 && MACD_main < MACD_signal) || RSI_H1 > 70 || RSI_H4 > 70) && CanTrade()) {
        double openPrice = Bid;
        int ticket = OrderSend(Symbol(), OP_SELL, Lots, openPrice, 3, 0, openPrice - TakeProfit * Point, NULL, 0, 0, Red);
        if (ticket > 0) {
            Comment('Opened 空单成功,交易手数为:', Lots, ',开仓价格为:', DoubleToString(openPrice));
        } else {
            Print('Failed to open sell order. Error code: ', GetLastError());
        }
    }
}

}

// 根据不同时间周期观察指标信号进行交易 void TradeByTimeframe(ENUM_TIMEFRAMES timeframe) { double RSI = iRSI(Symbol(), timeframe, RSI_Period, PRICE_CLOSE, 0); double MACD_main = iMACD(Symbol(), timeframe, MACD_FastEMA, MACD_SlowEMA, MACD_SignalEMA, PRICE_CLOSE, MODE_MAIN, 1); double MACD_signal = iMACD(Symbol(), timeframe, MACD_FastEMA, MACD_SlowEMA, MACD_SignalEMA, PRICE_CLOSE, MODE_SIGNAL, 1);

switch (timeframe) {
    case PERIOD_M15:
        TradeByIndicators(RSI, 0, 0, 0, MACD_main, MACD_signal);
        break;
    case PERIOD_M30:
        TradeByIndicators(0, RSI, 0, 0, MACD_main, MACD_signal);
        break;
    case PERIOD_H1:
        TradeByIndicators(0, 0, RSI, 0, MACD_main, MACD_signal);
        break;
    case PERIOD_H4:
        TradeByIndicators(0, 0, 0, RSI, MACD_main, MACD_signal);
        break;
    default:
        break;
}

}

// 定义OnTick()函数,用于每次价格变动时执行代码 void OnTick() { // 观察15分钟周期 TradeByTimeframe(PERIOD_M15);

// 观察30分钟周期
TradeByTimeframe(PERIOD_M30);

// 观察1小时周期
TradeByTimeframe(PERIOD_H1);

// 观察4小时周期
TradeByTimeframe(PERIOD_H4);

}

// 定义OnInit()函数,用于初始化 int OnInit() { // 允许交易 if (TradingAllowed()) { // 设置止损和最大持仓手数,防止风险过大 double stopLoss = TakeProfit * 2; int totalOrders = OrdersTotal(); for (int i = 0; i < totalOrders; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == 0) { double openPrice = OrderOpenPrice(); bool modifyResult = OrderModify(OrderTicket(), openPrice, stopLoss, openPrice + TakeProfit * Point, 0, Blue); if (!modifyResult) { Print('Failed to modify order. Error code: ', GetLastError()); } } } } } else { Print('Trading is not allowed on this account.'); }

return 0;

}

// 定义OnDeinit()函数,用于销毁EA void OnDeinit(const int reason) { Comment(''); }

// 定义OnTimer()函数,用于每隔一段时间执行代码 void OnTimer() { // 每隔30秒重新检查是否允许交易 if (!TradingAllowed()) { Comment('Trading is not currently allowed on this account.'); } }

// 定义TradingAllowed()函数,用于判断当前是否允许交易 bool TradingAllowed() { return AccountInfoInteger(ACCOUNT_TRADE_EXPERT) == 1; }

// 平仓不生效问题分析 // 以上代码中,平仓不生效可能是因为在平仓时未考虑到订单的类型,导致使用了错误的价格。 // 在平多单时应该使用 Bid 价格,而在平空单时应该使用 Ask 价格。 // 因此,在代码中需要根据订单类型来决定使用哪个价格进行平仓。

MQL4 代码优化后的完整正确代码:平仓不生效问题分析

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

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