//+------------------------------------------------------------------+ //| 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.1; // 交易手数 input int FastMA = 6; // 快速均线周期 (6日) input int MidMA = 15; // 中间均线周期 (15日) input int SlowMA = 30; // 慢速均线周期 (30日) input ulong m_magic=42828093; // 魔术数字 ulong m_slippage=10; // 滑点 //--- int handle_fastMA; // 快速均线指标句柄 int handle_midMA; // 中间均线指标句柄 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_15, FastMA, 0, MODE_SMA, PRICE_CLOSE);
handle_midMA  = iMA(m_symbol.Name(), PERIOD_15, MidMA,  0, MODE_SMA, PRICE_CLOSE);
handle_slowMA = iMA(m_symbol.Name(), PERIOD_15, SlowMA, 0, MODE_SMA, PRICE_CLOSE);

//--- 检查指标句柄是否创建成功
if(handle_fastMA == INVALID_HANDLE || handle_midMA == 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_15, FastMA, 0, MODE_SMA, PRICE_CLOSE);
double midMA  = iMA(m_symbol.Name(), PERIOD_15, MidMA,  0, MODE_SMA, PRICE_CLOSE);
double slowMA = iMA(m_symbol.Name(), PERIOD_15, SlowMA, 0, MODE_SMA, PRICE_CLOSE);
double price  = Close[0];

//--- 检查当前是否有持仓
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)
            {
                if (price < fastMA) // 多单平仓条件:价格下穿6日均线
                {
                    //--- 平仓
                    m_trade.PositionClose(m_position.Ticket());
                    break;
                }
            }
            else if(m_position.PositionType()==POSITION_TYPE_SELL)
            {
                if (price > slowMA) // 空单平仓条件:价格上穿30日均线
                {
                    //--- 平仓
                    m_trade.PositionClose(m_position.Ticket());
                    break;
                }
            }
        }
    }
}

//--- 判断是否满足开仓条件
if (price > fastMA && price > midMA && price > slowMA)
{
    // 做多条件:价格上穿6日、15日和30日均线
    if (m_position.PositionType() != POSITION_TYPE_BUY) {
        m_trade.Buy(Lots, m_symbol.Name());
    }
}
else if (price < fastMA && price < midMA && price < slowMA)
{
    // 做空条件:价格下穿6日、15日和30日均线
    if (m_position.PositionType() != POSITION_TYPE_SELL) {
        m_trade.Sell(Lots, m_symbol.Name());
    }
}

} //+------------------------------------------------------------------+ //| 刷新交易品种行情数据 | //+------------------------------------------------------------------+ 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) { double MA[1]; if(CopyBuffer(handle_fastMA, buffer, index, 1, MA) < 0) { Print('Failed to copy data from the moving average indicator'); return(0.0); } return(MA[0]); } //+------------------------------------------------------------------+

MQL5 EA 双向交易策略:基于多周期均线的突破策略

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

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