Here is the optimized code for the bidirectional trading EA:

//+------------------------------------------------------------------+
//|                  MovingAverageCrossoverEA.mq5                     |
//|                            Created by ChatGPT                      |
//+------------------------------------------------------------------+
#property copyright "Created by ChatGPT"
#property link      "https://www.example.com"
#property version   "1.000"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
//--- input parameters
input double   Lots        = 0.05;              // 交易手数
input int      FastMA       = 10;             // 快速均线周期
input int      SlowMA     = 45;             // 慢速均线周期
input ulong    m_magic=42828093;             // 魔术数字
ulong          m_slippage=10;                // 滑点
//---
int         handle_fastMA;                   // 快速均线指标句柄
int         handle_slowMA;                   // 慢速均线指标句柄
//+------------------------------------------------------------------+
//|  Expert initialization function                                  |
//+------------------------------------------------------------------+
int OnInit()
{
    //---
    if(!m_symbol.Name(Symbol())) // 设置交易品种名称
        return(INIT_FAILED);
    RefreshRates();

    string err_text="";
    if(!CheckVolumeValue(Lots,err_text))
    {
        Print(err_text);
        return(INIT_PARAMETERS_INCORRECT);
    }

    //---
    m_trade.SetExpertMagicNumber(m_magic);

    if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))
        m_trade.SetTypeFilling(ORDER_FILLING_FOK);
    else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))
        m_trade.SetTypeFilling(ORDER_FILLING_IOC);
    else
        m_trade.SetTypeFilling(ORDER_FILLING_RETURN);

    m_trade.SetDeviationInPoints(m_slippage);

    //--- 创建快速均线指标句柄
    handle_fastMA = iMA(m_symbol.Name(), PERIOD_M15, FastMA, 0, MODE_SMA, PRICE_CLOSE);
    //--- 创建慢速均线指标句柄
    handle_slowMA = iMA(m_symbol.Name(), PERIOD_M15, SlowMA, 0, MODE_SMA, PRICE_CLOSE);

    //--- 检查指标句柄是否创建成功
    if(handle_fastMA == INVALID_HANDLE || handle_slowMA == INVALID_HANDLE)
    {
        Print("Failed to create moving average indicators for the symbol ", m_symbol.Name());
        return(INIT_FAILED);
    }

    return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|  Expert deinitialization function                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    //---
}
//+------------------------------------------------------------------+
//|  Expert tick function                                            |
//+------------------------------------------------------------------+
void OnTick()
{
    //--- 仅在新K线生成时进行交易
    static datetime PrevBars=0;
    datetime time_0=iTime(0);
    if(time_0==PrevBars)
        return;
    PrevBars=time_0;

    //--- 获取均线值
    double fastMA = iMA(m_symbol.Name(), PERIOD_M15, FastMA, 0, MODE_SMA, PRICE_CLOSE);
    double slowMA = iMA(m_symbol.Name(), PERIOD_M15, SlowMA, 0, MODE_SMA, PRICE_CLOSE);  

    //--- 检查当前是否有持仓
    for(int i=PositionsTotal()-1;i>=0;i--)
    {
        if(m_position.SelectByIndex(i))
        {
            if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
            {
                if(m_position.PositionType()==POSITION_TYPE_BUY && fastMA < slowMA)
                {
                    //--- 卖出持仓
                    m_trade.PositionClose(m_position.Ticket());
                    break;
                }
                else if(m_position.PositionType()==POSITION_TYPE_SELL && fastMA > slowMA)
                {
                    //--- 买入持仓
                    m_trade.PositionClose(m_position.Ticket());
                    break;
                }
            }
        }
    }

    //--- 如果快速均线上穿慢速均线,进行买入交易
    if(fastMA > slowMA)
    {
        if (m_position.PositionType() != POSITION_TYPE_BUY) {
            m_trade.Buy(Lots, m_symbol.Name());
        }
    }
    //--- 如果快速均线下穿慢速均线,进行卖出交易
    else if(fastMA < slowMA)
    {
        if (m_position.PositionType() != POSITION_TYPE_SELL) {
            m_trade.Sell(Lots, m_symbol.Name());
        }
    }

    //--- 如果快速均线下穿慢速均线,进行做空交易
    if(fastMA < slowMA)
    {
        if (m_position.PositionType() != POSITION_TYPE_SELL) {
            m_trade.Sell(Lots, m_symbol.Name());
        }
    }
    //--- 如果快速均线上穿慢速均线,进行平仓交易
    else if(fastMA > slowMA)
    {
        if (m_position.PositionType() != POSITION_TYPE_BUY) {
            m_trade.PositionClose(m_position.Ticket());
        }
    }
}
//+------------------------------------------------------------------+
//|  刷新交易品种行情数据                                           |
//+------------------------------------------------------------------+
bool RefreshRates(void)
{
    //--- 刷新行情数据
    if(!m_symbol.RefreshRates())
    {
        Print("RefreshRates error");
        return(false);
    }

    //--- 保护返回值不为"零"
    if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
        return(false);

    return(true);
}
//+------------------------------------------------------------------+
//|  检查交易手数的正确性                                           |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume, string &error_description)
{
    //--- 最小允许交易手数
    double min_volume = m_symbol.LotsMin();
    if(volume < min_volume)
    {
        error_description = StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f", min_volume);
        return(false);
    }

    //--- 最大允许交易手数
    double max_volume = m_symbol.LotsMax();
    if(volume > max_volume)
    {
        error_description = StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f", max_volume);
        return(false);
    }

    //--- 获取交易手数变动的最小步长
    double volume_step = m_symbol.LotsStep();
    int ratio = (int)MathRound(volume / volume_step);
    if(MathAbs(ratio * volume_step - volume) > 0.0000001)
    {
        error_description = StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                                     volume_step,ratio * volume_step);
        return(false);
    }
    error_description = "Correct volume value";
    return(true);
}
//+------------------------------------------------------------------+ 
//|  检查指定的成交模式是否允许                                     | 
//+------------------------------------------------------------------+ 
bool IsFillingTypeAllowed(int fill_type)
{
    int filling = m_symbol.TradeFillFlags();
    return((filling & fill_type) == fill_type);
}
//+------------------------------------------------------------------+ 
//|  获取指定柱子的时间                                              | 
//+------------------------------------------------------------------+ 
datetime iTime(const int index, string symbol=NULL, ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
{
    if(symbol == NULL)
        symbol = m_symbol.Name();
    if(timeframe == 0)
        timeframe = Period();
    datetime Time[1];
    datetime time = 0;
    int copied = CopyTime(symbol, timeframe, index, 1, Time);
    if(copied > 0)
        time = Time[0];
    return(time);
}
//+------------------------------------------------------------------+
//|  获取iMA指标缓冲区的值                                           |
//|  缓冲区编号如下:                                                |
//|   0 - MAIN_LINE, 1 - SIGNAL_LINE                                 |
//+------------------------------------------------------------------+
double iMAGet(const int buffer, const int index)
{
Optimize the following automated trading EA codes into bidirectional trading allowing for both sell short and buy long trading Only trade under two types of moving average conditions Firstly trade lon

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

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