| 
 | 
 
多单过滤条件: 
 
1,macd15分钟周期(需要可以选择)都在零轴上 
 
开单条件:rsi从下往上 上穿60 开多单 
 
空单过滤条件: 
 
1,macd15分钟周期(需要可以选择)都在零轴下 
 
开单条件:rsi从下往上 上穿40 开多单 
 
 
 
出场条件: 
 
亏损5000个点清仓 
盈利6000个点开始计算利润,开启移动止损,回撤利润的80%清仓, 
 
源码: 
 
//+------------------------------------------------------------------+ 
//|                                                    MACD_RSI_Pro.mq5 | 
//|                        Copyright 2024, MetaQuotes Software Corp. | 
//|                                             https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2024, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.06" 
 
#include <Trade\Trade.mqh> 
CTrade Trade; 
 
input group "MACD Settings" 
input ENUM_TIMEFRAMES MACDTimeframe = PERIOD_M15;  // MACD时间框架 
input int FastEMA = 12;                            // 快速EMA周期 
input int SlowEMA = 26;                            // 慢速EMA周期 
input int SignalSMA = 9;                           // 信号线周期 
 
input group "RSI Settings" 
input int RSIPeriod = 14;                          // RSI周期 
input ENUM_APPLIED_PRICE RSIPrice = PRICE_CLOSE;   // RSI应用价格 
 
input group "Trading Rules" 
input double Lots = 0.1;                           // 交易手数 
input int RSIOverbought = 60;                      // RSI超买水平 
input int RSIOversold = 40;                        // RSI超卖水平 
 
input group "Risk Management" 
input int StopLossPoints = 5000;                   // 止损点数 
input int TakeProfitPoints = 6000;                 // 移动止损启动点数 
input double TrailingPercent = 80;                 // 利润回撤百分比 
 
struct TrailingData { 
   ulong ticket; 
   double highest; 
   double lowest; 
}; 
TrailingData trailArray[]; 
 
//+------------------------------------------------------------------+ 
//| 初始化函数                                                       | 
//+------------------------------------------------------------------+ 
int OnInit() 
{ 
   if(StopLossPoints <= 0 || TakeProfitPoints <= 0 || TrailingPercent <= 0 || TrailingPercent >= 100) { 
      Alert("参数错误: 请检查止损/止盈/回撤参数!"); 
      return(INIT_PARAMETERS_INCORRECT); 
   } 
   Trade.SetExpertMagicNumber(12345); 
   Trade.SetDeviationInPoints(50); 
   ArraySetAsSeries(trailArray, true); 
   return(INIT_SUCCEEDED); 
} 
 
//+------------------------------------------------------------------+ 
//| 追踪止损管理函数                                                 | 
//+------------------------------------------------------------------+ 
void ManageTrailingStop() 
{ 
   for(int i=PositionsTotal()-1; i>=0; i--) 
   { 
      ulong ticket=PositionGetTicket(i); 
      if(ticket==0 || !PositionSelectByTicket(ticket)) continue; 
 
      double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); 
      double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT); 
      ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); 
 
      // 寻找或创建追踪记录 
      int idx = -1; 
      for(int j=0; j<ArraySize(trailArray); j++) { 
         if(trailArray[j].ticket == ticket) { 
            idx = j; 
            break; 
         } 
      } 
 
      // 初始化追踪数据:当价格差达到TakeProfitPoints时 
      if(idx == -1)  
      { 
         double priceDiff; 
         if(posType == POSITION_TYPE_BUY) { 
            priceDiff = currentPrice - openPrice; 
         } else { 
            priceDiff = openPrice - currentPrice; 
         } 
         if(priceDiff >= TakeProfitPoints * _Point)  
         { 
            ArrayResize(trailArray, ArraySize(trailArray)+1); 
            idx = ArraySize(trailArray)-1; 
            trailArray[idx].ticket = ticket; 
            trailArray[idx].highest = (posType == POSITION_TYPE_BUY) ? currentPrice : 0; 
            trailArray[idx].lowest = (posType == POSITION_TYPE_SELL) ? currentPrice : DBL_MAX; 
         } 
      } 
 
      // 更新价格轨迹并检查止损 
      if(idx != -1)  
      { 
         if(posType == POSITION_TYPE_BUY)  
         { 
            trailArray[idx].highest = MathMax(trailArray[idx].highest, currentPrice); 
            double stopLevel = trailArray[idx].highest - (trailArray[idx].highest - openPrice) * (TrailingPercent / 100.0); 
            stopLevel = NormalizeDouble(stopLevel, _Digits); 
            if(currentPrice <= stopLevel)  
            { 
               Trade.PositionClose(ticket); 
               ArrayRemove(trailArray, idx, 1); 
            } 
         }  
         else  
         { 
            trailArray[idx].lowest = MathMin(trailArray[idx].lowest, currentPrice); 
            double stopLevel = trailArray[idx].lowest + (openPrice - trailArray[idx].lowest) * (TrailingPercent / 100.0); 
            stopLevel = NormalizeDouble(stopLevel, _Digits); 
            if(currentPrice >= stopLevel)  
            { 
               Trade.PositionClose(ticket); 
               ArrayRemove(trailArray, idx, 1); 
            } 
         } 
      } 
   } 
} 
 
//+------------------------------------------------------------------+ 
//| 开单条件检查函数                                                 | 
//+------------------------------------------------------------------+ 
void CheckForOpen() 
{ 
   // 获取MACD指标 
   int macdHandle = iMACD(_Symbol, MACDTimeframe, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE); 
   double macdMain[2]; 
   CopyBuffer(macdHandle, MAIN_LINE, 0, 2, macdMain); 
 
   // 获取RSI指标 
   int rsiHandle = iRSI(_Symbol, MACDTimeframe, RSIPeriod, RSIPrice); 
   double rsi[2]; 
   CopyBuffer(rsiHandle, 0, 0, 2, rsi); 
 
   // 多单条件:MACD双线在零轴上方且RSI上穿60 
   if(macdMain[0] > 0 && macdMain[1] > 0 && rsi[0] > RSIOverbought && rsi[1] <= RSIOverbought) 
   { 
      if(!PositionExist()) { 
         double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); 
         double sl = NormalizeDouble(ask - StopLossPoints*_Point, _Digits); 
         Trade.Buy(Lots, _Symbol, ask, sl, 0, "MACD_RSI_Buy"); 
      } 
   } 
 
   // 空单条件:MACD双线在零轴下方且RSI下穿40 
   if(macdMain[0] < 0 && macdMain[1] < 0 && rsi[0] < RSIOversold && rsi[1] >= RSIOversold) 
   { 
      if(!PositionExist()) { 
         double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); 
         double sl = NormalizeDouble(bid + StopLossPoints*_Point, _Digits); 
         Trade.Sell(Lots, _Symbol, bid, sl, 0, "MACD_RSI_Sell"); 
      } 
   } 
} 
 
//+------------------------------------------------------------------+ 
//| 仓位存在检查函数                                                 | 
//+------------------------------------------------------------------+ 
bool PositionExist() 
{ 
   for(int i=0; i<PositionsTotal(); i++) { 
      ulong ticket=PositionGetTicket(i); 
      if(ticket>0 && PositionSelectByTicket(ticket)) { 
         if(PositionGetString(POSITION_SYMBOL) == _Symbol) { 
            return true; 
         } 
      } 
   } 
   return false; 
} 
 
//+------------------------------------------------------------------+ 
//| 主执行函数                                                       | 
//+------------------------------------------------------------------+ 
void OnTick() 
{ 
   // 环境检查 
   if(!TerminalInfoInteger(TERMINAL_CONNECTED)) return; 
   if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) return; 
   if(SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_FULL) return; 
 
   ManageTrailingStop(); 
   CheckForOpen(); 
} 
 
 |   
 
 
 
 |