MQL5教程 06 EA开发实战

news2025/7/15 15:17:50

文章目录

  • 一、调用多指标多周期EA示例
  • 二、获取ZigZag顶点值
  • 三、逆势加仓EA

一、调用多指标多周期EA示例

shuju.mqh:

class shuju
  {
   public:
      shuju()
        {
        }     
      ~shuju()
        {
        }
      void MA(
         double &ma[],
         int count,
         string               symbol,            // 交易品种名称 
         ENUM_TIMEFRAMES      period,            // 周期 
         int                  ma_period,         // 平均周期 
         int                  ma_shift,          // 平移 
         ENUM_MA_METHOD       ma_method,         // 平滑类型 
         ENUM_APPLIED_PRICE   applied_price      // 价格或者处理程序类型 
        );
      void Bands( 
         double &Upper[],
         double &Lower[],
         double &Middle[],
         int count,
         string              symbol,            // 交易品种名称 
         ENUM_TIMEFRAMES     period,            // 周期 
         int                 bands_period,      // 平均线计算周期 
         int                 bands_shift,       // 指标平移 
         double              deviation,         // 标准差数 
         ENUM_APPLIED_PRICE  applied_price      // 价格或处理器类型 
        );
      void Stochastic( 
         double &data0[],
         double &data1[],
         int count,
         string           symbol,          // 交易品种名称 
         ENUM_TIMEFRAMES  period,          // 周期 
         int              Kperiod,         // K线周期 (用于计算的柱数) 
         int              Dperiod,         // D线周期 (开始平滑周期) 
         int              slowing,         // 最终平滑 
         ENUM_MA_METHOD   ma_method,       // 平滑类型 
         ENUM_STO_PRICE   price_field      // 随机计算法 
        );
      int getrates(MqlRates &rates[],int count,string symbol,ENUM_TIMEFRAMES tf);
  };

void shuju::MA(
   double               &ma[],
   int                  count,            // 复制总数
   string               symbol,           // 交易品种名称 
   ENUM_TIMEFRAMES      period,           // 周期 
   int                  ma_period,        // 平均周期 
   int                  ma_shift,         // 平移 
   ENUM_MA_METHOD       ma_method,        // 平滑类型 
   ENUM_APPLIED_PRICE   applied_price     // 价格或者处理程序类型 
  ){
  
   int ma_h = iMA(symbol,period,ma_period,ma_shift,ma_method,applied_price);
   ArraySetAsSeries(ma,true);
   CopyBuffer(ma_h,0,0,count,ma);
   IndicatorRelease(ma_h);
   
  }
  
void shuju::Bands( 
   double &Upper[],
   double &Lower[],
   double &Middle[],
   int count,
   string              symbol,            // 交易品种名称 
   ENUM_TIMEFRAMES     period,            // 周期 
   int                 bands_period,      // 平均线计算周期 
   int                 bands_shift,       // 指标平移 
   double              deviation,         // 标准差数 
   ENUM_APPLIED_PRICE  applied_price      // 价格或处理器类型 
  ){
  
   int h = iBands(symbol,period,bands_period,bands_shift,deviation,applied_price);
   ArraySetAsSeries(Upper, true);
   ArraySetAsSeries(Lower, true);
   ArraySetAsSeries(Middle, true);
   CopyBuffer(h,0,0,count,Middle);
   CopyBuffer(h,1,0,count,Upper);
   CopyBuffer(h,2,0,count,Lower);
   IndicatorRelease(h);
  }
  
void shuju::Stochastic( 
   double &data0[],
   double &data1[],
   int count,
   string           symbol,          // 交易品种名称 
   ENUM_TIMEFRAMES  period,          // 周期 
   int              Kperiod,         // K线周期 (用于计算的柱数) 
   int              Dperiod,         // D线周期 (开始平滑周期) 
   int              slowing,         // 最终平滑 
   ENUM_MA_METHOD   ma_method,       // 平滑类型 
   ENUM_STO_PRICE   price_field      // 随机计算法 
  ){
  
   int h = iStochastic(symbol,period,Kperiod,Dperiod,slowing,ma_method,price_field);
   ArraySetAsSeries(data0, true);
   ArraySetAsSeries(data1, true);
   CopyBuffer(h,0,0,count,data0);
   CopyBuffer(h,1,0,count,data1);
   IndicatorRelease(h);
  
  }
  
int shuju::getrates(MqlRates &rates[],int count,string symbol,ENUM_TIMEFRAMES tf)
  {
   ArraySetAsSeries(rates, true);
   return(CopyRates(symbol,tf,0,count,rates));
  }

jiaoyi.mqh:

class jiaoyi
  {
   public:
      ulong buy(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      ulong buyplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      ulong sell(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      ulong sellplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      void  closeallbuy(string symbol);
      void  closeallsell(string symbol);
  };
  
ulong jiaoyi::buy(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   MqlTradeRequest request = {};
   MqlTradeResult  result  = {};
   request.action = TRADE_ACTION_DEAL;
   request.symbol = symbol;
   request.type   = ORDER_TYPE_BUY;
   request.volume = lots;
   request.deviation    = 100;
   request.type_filling = ORDER_FILLING_IOC;
   request.price        = SymbolInfoDouble(symbol,SYMBOL_ASK);
   // SYMBOL_TRADE_STOPS_LEVEL 设置止损/止盈时,与当前价格的最小距离限制(以点为单位)
   if(slpoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl = SymbolInfoDouble(symbol,SYMBOL_ASK) - slpoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   if(tppoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp = SymbolInfoDouble(symbol,SYMBOL_ASK) + tppoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   request.comment = com;
   request.magic   = magic;
   // --- 发送请求
   if(!OrderSend(request, result))
      PrintFormat("OrderSend error %d", GetLastError()); // 如果不能发送请求,输出错误代码
   // --- 显示操作信息
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   
   return(result.order);
  }
  
ulong jiaoyi::buyplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   ulong ticket = 0;
   int total = PositionsTotal();
   
   for(int i=total-1; i>=0; i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==com)
            return(0);
        }
     }
     
   ticket = buy(symbol,lots,slpoint,tppoint,com,magic);
   return(ticket);
  }
  
ulong jiaoyi::sell(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   MqlTradeRequest request = {};
   MqlTradeResult  result  = {};
   request.action = TRADE_ACTION_DEAL;
   request.symbol = symbol;
   request.type   = ORDER_TYPE_SELL;
   request.volume = lots;
   request.deviation    = 100;
   request.type_filling = ORDER_FILLING_IOC;
   request.price        = SymbolInfoDouble(symbol,SYMBOL_BID);

   if(slpoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl = SymbolInfoDouble(symbol,SYMBOL_BID) + slpoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   if(tppoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp = SymbolInfoDouble(symbol,SYMBOL_BID) - tppoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   request.comment = com;
   request.magic   = magic;
   // --- 发送请求
   if(!OrderSend(request, result))
      PrintFormat("OrderSend error %d", GetLastError());
   // --- 显示操作信息
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   
   return(result.order);
  }
  
ulong jiaoyi::sellplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   ulong ticket = 0;
   int total = PositionsTotal();
   
   for(int i=total-1; i>=0; i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==com)
            return(0);
        }
     }
     
   ticket = sell(symbol,lots,slpoint,tppoint,com,magic);
   return(ticket);
  }
  
void jiaoyi::closeallbuy(string symbol)
  {
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            MqlTradeRequest request = {};
            MqlTradeResult  result  = {};
            request.action   = TRADE_ACTION_DEAL;                    // 交易操作类型
            request.symbol   = symbol;                               // 交易品种
            request.volume   = PositionGetDouble(POSITION_VOLUME);   // 交易量 
            request.type     = ORDER_TYPE_SELL;                      // 订单类型
            request.price    = SymbolInfoDouble(symbol,SYMBOL_BID);  // 持仓价格
            request.deviation= 100;                                  // 允许价格偏差
            request.type_filling=ORDER_FILLING_IOC;
            request.position = ticket;
            
            if(!OrderSend(request,result))
               PrintFormat("OrderSend error %d",GetLastError()); 
           }
        }
     }
  }
  
void jiaoyi::closeallsell(string symbol)
  {
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            MqlTradeRequest request = {};
            MqlTradeResult  result  = {};
            request.action   = TRADE_ACTION_DEAL;                    // 交易操作类型
            request.symbol   = symbol;                               // 交易品种
            request.volume   = PositionGetDouble(POSITION_VOLUME);   // 交易量 
            request.type     = ORDER_TYPE_BUY;                       // 订单类型
            request.price    = SymbolInfoDouble(symbol,SYMBOL_ASK);  // 持仓价格
            request.deviation= 100;                                  // 允许价格偏差
            request.type_filling=ORDER_FILLING_IOC;
            request.position = ticket;
            
            if(!OrderSend(request,result))
               PrintFormat("OrderSend error %d",GetLastError()); 
           }
        }
     }
  }

EA:

#include <myClass/jiaoyi.mqh>
#include <myClass/shuju.mqh>

jiaoyi jy;
shuju  sj;

input double LOTS  = 0.01;    // 开仓手数
input int sl_point = 700;    // 止损点数
input int tp_point = 700;    // 止盈点数
input int MAGIC    = 12345;   // 幻数
input int little_period = 5;  // 小均线周期
input int large_period  = 10; // 大均线周期
input int bollinger_period  = 20;   // 布林带周期
input double bollinger_deviation = 2; // 布林带偏差
input int InpKPeriod = 5; // K period
input int InpDPeriod = 3; // D period
input int InpSlowing = 3; // Slowing

int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   
  }

void OnTick()
  {
   double m30_ma_xiao[];   // 30分钟小周期MA
   sj.MA(m30_ma_xiao,4,Symbol(),PERIOD_M30,little_period,0,MODE_SMA,PRICE_CLOSE);
   double m30_ma_da[];     // 30分钟大周期MA
   sj.MA(m30_ma_da,4,Symbol(),PERIOD_M30,large_period,0,MODE_SMA,PRICE_CLOSE);
   
   double h4_ma_xiao[];    // H4小周期MA
   sj.MA(h4_ma_xiao,4,Symbol(),PERIOD_H4,little_period,0,MODE_SMA,PRICE_CLOSE);
   double h4_ma_da[];      // H4大周期MA
   sj.MA(h4_ma_da,4,Symbol(),PERIOD_H4,large_period,0,MODE_SMA,PRICE_CLOSE);
   
   double m30_bands_up[], m30_bands_low[], m30_bands_mid[];
   sj.Bands(m30_bands_up,m30_bands_low,m30_bands_mid,4,Symbol(),PERIOD_M30,bollinger_period,0,bollinger_deviation,PRICE_CLOSE);
   double h4_bands_up[], h4_bands_low[], h4_bands_mid[];
   sj.Bands(h4_bands_up,h4_bands_low,h4_bands_mid,4,Symbol(),PERIOD_H4,bollinger_period,0,bollinger_deviation,PRICE_CLOSE);
  
   double m30_k[], m30_d[];
   sj.Stochastic(m30_k,m30_d,4,Symbol(),PERIOD_M30,InpKPeriod,InpDPeriod,InpSlowing,MODE_SMA,STO_LOWHIGH);
   double h4_k[], h4_d[];
   sj.Stochastic(h4_k,h4_d,4,Symbol(),PERIOD_H4,InpKPeriod,InpDPeriod,InpSlowing,MODE_SMA,STO_LOWHIGH);
   
   MqlRates m30_rate[];
   sj.getrates(m30_rate,4,Symbol(),PERIOD_M30);
   MqlRates h4_rate[];
   sj.getrates(h4_rate,4,Symbol(),PERIOD_H4);
   
   // 开多单:H4K线下穿布林带下轨,且M30小周期均线在大周期均线之上,且M30指标KDJ金叉
   if(h4_rate[0].low<h4_bands_low[0] && m30_ma_xiao[0]>m30_ma_da[0] && m30_k[1]>m30_d[1] && m30_k[2]<m30_d[2])
      jy.buyplus(Symbol(),LOTS,sl_point,tp_point,"buy",MAGIC);
   // 平仓多单:在M30指标KDJ死叉
   if(m30_k[1]<m30_d[1] && m30_k[2]>m30_d[2])
      jy.closeallbuy(Symbol());
   
   // 开空单
   if(h4_rate[0].high>h4_bands_up[0] && m30_ma_xiao[0]<m30_ma_da[0] && m30_k[1]<m30_d[1] && m30_k[2]>m30_d[2])
      jy.sellplus(Symbol(),LOTS,sl_point,tp_point,"sell",MAGIC);   
   // 平仓空单
   if(m30_k[1]>m30_d[1] && m30_k[2]<m30_d[2])
      jy.closeallsell(Symbol());
   
  }

二、获取ZigZag顶点值

shuju.mqh:

class shuju
  {
   public:
      shuju()
        {
        }     
      ~shuju()
        {
        }
      void ZigZag(double &data0[],int count,ENUM_TIMEFRAMES period,int ExtDepth,int ExtDeviation,int ExtBackstep);
      void gettime(datetime &time[],int count);
      void getlow(double &Low[],int count);
  };

void shuju::ZigZag(double &data0[],int count,ENUM_TIMEFRAMES period,int ExtDepth,int ExtDeviation,int ExtBackstep)
  {
   int h = iCustom(Symbol(),period,"Examples/ZigZag",ExtDepth,ExtDeviation,ExtBackstep);
   ArraySetAsSeries(data0,true);
   CopyBuffer(h,0,0,count,data0);
   IndicatorRelease(h);
  }
  
void shuju::gettime(datetime &time[],int count)
  {
   ArraySetAsSeries(time,true);
   CopyTime(Symbol(),0,0,count,time);
  }
  
void shuju::getlow(double &Low[],int count)
  {
   ArraySetAsSeries(Low,true);
   CopyLow(Symbol(),0,0,count,Low);
  }

EA:

#include <myClass/shuju.mqh>

shuju  sj;

input int InpDepth    =12;  // Depth
input int InpDeviation=5;   // Deviation
input int InpBackstep =3;   // Back Step
input int geshu = 10;

double zigzag[][4];   // 只计入顶点值

int OnInit()
  {
   ArrayResize(zigzag, geshu);   // 设置新的第一维大小
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   
  }

void OnTick()
  {
   // ZigZag指标的顶点值为对应K线的最高/最低价,非顶点值为0
   double zigzagzhi[];
   int bars = Bars(Symbol(),0);  // 返回K嫌数量
   sj.ZigZag(zigzagzhi,bars,PERIOD_CURRENT,InpDepth,InpDeviation,InpBackstep);
   datetime time[];
   sj.gettime(time, bars);
   double low[];
   sj.getlow(low, bars);

   int counter = 0;
   for(int i=0; i<bars; i++)
     {
      if(counter>(geshu-1))
        {
         break;
        }
      if(zigzagzhi[i]>0)
        {
         zigzag[counter][0] = zigzagzhi[i];
         zigzag[counter][1] = i;
         zigzag[counter][2] = (double)time[i];
         if(zigzagzhi[i] <= low[i]) // 低点
           {
            zigzag[counter][3] = 1;
           }
         else  // 高点
           {
            zigzag[counter][3] = 2;
           }
         counter++;
        }
     }
  }

三、逆势加仓EA

jiaoyi.mqh:

class jiaoyi
  {
   public:
      int danshu(string symbol,ENUM_POSITION_TYPE type);
      ulong buy(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      ulong buyplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic);
      ulong zuijindan(string symbol,ENUM_POSITION_TYPE type,double &openprice,datetime &opentime,double &openlots,double &opensl,double &opentp,int magic);
      double formatlots(string symbol,double lots);
      void modifysltp(ENUM_POSITION_TYPE type,double sl,double tp);
  };
  
int jiaoyi::danshu(string symbol,ENUM_POSITION_TYPE type)
  {
   int count = 0;
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket > 0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
            count++;
        }
     }
     
   return(count);
  }
  
ulong jiaoyi::buy(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   MqlTradeRequest request = {};
   MqlTradeResult  result  = {};
   request.action = TRADE_ACTION_DEAL;
   request.symbol = symbol;
   request.type   = ORDER_TYPE_BUY;
   request.volume = lots;
   request.deviation    = 100;
   request.type_filling = ORDER_FILLING_IOC;
   request.price        = SymbolInfoDouble(symbol,SYMBOL_ASK);
   // SYMBOL_TRADE_STOPS_LEVEL 设置止损/止盈时,与当前价格的最小距离限制(以点为单位)
   if(slpoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl = SymbolInfoDouble(symbol,SYMBOL_ASK) - slpoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   if(tppoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp = SymbolInfoDouble(symbol,SYMBOL_ASK) + tppoint*SymbolInfoDouble(symbol,SYMBOL_POINT);
     }
   request.comment = com;
   request.magic   = magic;
   // --- 发送请求
   if(!OrderSend(request, result))
      PrintFormat("OrderSend error %d", GetLastError()); // 如果不能发送请求,输出错误代码
   // --- 显示操作信息
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   
   return(result.order);
  }
  
ulong jiaoyi::buyplus(string symbol,double lots,int slpoint,int tppoint,string com,int magic)
  {
   ulong ticket = 0;
   int total = PositionsTotal();
   
   for(int i=total-1; i>=0; i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==com)
            return(0);
        }
     }
     
   ticket = buy(symbol,lots,slpoint,tppoint,com,magic);
   return(ticket);
  }
  
ulong jiaoyi::zuijindan(string symbol,ENUM_POSITION_TYPE type,double &openprice,datetime &opentime,double &openlots,double &opensl,double &opentp,int magic=0)
  {
   openprice = 0;
   opentime  = 0;
   openlots  = 0;
   opensl    = 0;
   opentp    = 0;
   ulong ticket = 0;
   int   total  = PositionsTotal();
   for(int i=total; i>=0; i--)
     {
      if(PositionGetTicket(i) > 0)
         {
            if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type && PositionGetInteger(POSITION_MAGIC)==magic)
              {
                 openprice=PositionGetDouble(POSITION_PRICE_OPEN);
                 opentime=(datetime)PositionGetInteger(POSITION_TIME);
                 openlots=PositionGetDouble(POSITION_VOLUME);
                 opensl=PositionGetDouble(POSITION_SL);
                 opentp=PositionGetDouble(POSITION_TP);
                 ticket=PositionGetInteger(POSITION_TICKET);
                 break;
              }
         }
     }
     
   return(ticket);
  }
  
double jiaoyi::formatlots(string symbol,double lots)
  {
   double final_lots = 0;
   double minilots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
   double steplots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
   
   if(lots<minilots)
      return(0);
   else
     {
      double temp = MathFloor(lots/minilots)*minilots;
      final_lots  = temp + MathFloor((lots-temp)/steplots)*steplots;
     }
   
   return(final_lots);
  }
  
void jiaoyi::modifysltp(ENUM_POSITION_TYPE type,double sl,double tp)
  {
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(type==POSITION_TYPE_BUY)
           {
            // 止损止盈不等于原单子,才做修改。
            if((NormalizeDouble(sl,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))))
              {
               MqlTradeRequest request= {};
               MqlTradeResult  result = {};
               request.action   = TRADE_ACTION_SLTP;
               request.position = PositionGetTicket(i);
               request.symbol   = Symbol();
               request.sl       = NormalizeDouble(sl,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               request.tp       = NormalizeDouble(tp,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(sl<0)
                  request.sl = NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(tp<0)
                  request.tp = NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());
              }
           }
         if(type==POSITION_TYPE_SELL)
           {
            if((NormalizeDouble(sl,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))))
              {
               MqlTradeRequest request= {};
               MqlTradeResult  result = {};
               request.action   = TRADE_ACTION_SLTP;
               request.position = PositionGetTicket(i);
               request.symbol   = Symbol();
               request.sl       = NormalizeDouble(sl,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               request.tp       = NormalizeDouble(tp,(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(sl<0)
                  request.sl = NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(tp<0)
                  request.tp = NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS));
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());
                 }
           }
        }
     }
  }

shuju.mqh:

class shuju
  {
   public:
      shuju()
        {
        }     
      ~shuju()
        {
        }
      void getrates(MqlRates &rates[],int count);
      void shuju::Bands( 
         double &Upper[],
         double &Lower[],
         double &Middle[],
         int count,
         string              symbol,            // 交易品种名称 
         ENUM_TIMEFRAMES     period,            // 周期 
         int                 bands_period,      // 平均线计算周期 
         int                 bands_shift,       // 指标平移 
         double              deviation,         // 标准差数 
         ENUM_APPLIED_PRICE  applied_price      // 价格或处理器类型 
        );
      double getask();
  };

void shuju::getrates(MqlRates &rates[],int count)
  {
   ArraySetAsSeries(rates, true);
   CopyRates(Symbol(),PERIOD_CURRENT,0,count,rates);
  }
  
void shuju::Bands( 
   double &Upper[],
   double &Lower[],
   double &Middle[],
   int count,
   string              symbol,            // 交易品种名称 
   ENUM_TIMEFRAMES     period,            // 周期 
   int                 bands_period,      // 平均线计算周期 
   int                 bands_shift,       // 指标平移 
   double              deviation,         // 标准差数 
   ENUM_APPLIED_PRICE  applied_price      // 价格或处理器类型 
  ){
  
   int h = iBands(symbol,period,bands_period,bands_shift,deviation,applied_price);
   ArraySetAsSeries(Upper, true);
   ArraySetAsSeries(Lower, true);
   ArraySetAsSeries(Middle, true);
   CopyBuffer(h,0,0,count,Middle);
   CopyBuffer(h,1,0,count,Upper);
   CopyBuffer(h,2,0,count,Lower);
   IndicatorRelease(h);
  }
  
double shuju::getask()
  {
   return(SymbolInfoDouble(Symbol(),SYMBOL_ASK));
  }

EA:

#include <myClass/jiaoyi.mqh>
#include <myClass/shuju.mqh>

jiaoyi jy;
shuju  sj;

input double init_lots = 0.1; // 初始下单量
input int    loss_add_interbal_point = 100;  // 亏损加仓间隔点数
input double loss_add_multiple = 2; // 亏损加仓下单倍数
input int    syn_add_max_times = 5; // 同向单最多加仓次数
input int    call_back_tp_point = 200; // 回调止盈点数
input int    bollinger_period = 20;
input double bollinger_deviation =2;
input int    MAGIC = 12345;

datetime buytime=0;
MqlRates rate[];

int OnInit()
  {
   sj.getrates(rate, 4);
   buytime = rate[0].time;
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   
  }

void OnTick()
  {
   // 这里只展示开多单部分
   sj.getrates(rate, 4);
   double bandsup[], bandslow[], bandsmid[];
   sj.Bands(bandsup,bandslow,bandsmid,4,Symbol(),PERIOD_CURRENT,bollinger_period,0,bollinger_deviation,PRICE_CLOSE);
   int buydanshu = jy.danshu(Symbol(), POSITION_TYPE_BUY);
   // 条件 buytime!=rate[0].time 是为了一根K线只开一个单。
   if(buydanshu==0)
     {
      // 上一根K线的开盘价收盘价均脱离布林带下轨,且再上一根K线最低价触碰到布林带下轨,则开多单。
      if(buytime!=rate[0].time && rate[1].open>bandslow[1] && rate[1].close>bandslow[1] && rate[2].low<bandslow[2])
      {
         if(jy.buyplus(Symbol(),init_lots,0,call_back_tp_point,"buy",MAGIC) > 0)
            buytime = rate[0].time;
      }
     }
   else
     {
      double open_price, open_lots, open_sl, open_tp;
      datetime open_time;
      jy.zuijindan(Symbol(),POSITION_TYPE_BUY,open_price,open_time,open_lots,open_sl,open_tp,MAGIC);
      // 修改此前所有单的止盈价为最后一单的止盈价
      jy.modifysltp(POSITION_TYPE_BUY, -1, open_tp); // 止损设为负值,则表示不修改止损
      if(buydanshu<=syn_add_max_times && (open_price-sj.getask()) >= loss_add_interbal_point*Point())
        {
         // 逆势加仓
         jy.buyplus(Symbol(),jy.formatlots(Symbol(), open_lots*loss_add_multiple),0,call_back_tp_point,"buy"+IntegerToString(buydanshu),MAGIC);
        }
     }
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343865.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Burp靶场JWT学习笔记1

JWT(JSON Web Token) 从其名字就可以看出来&#xff0c;它具有表示身份的作用&#xff0c;其本质是将用户信息储存到一串json字符串中再将其编码得到一串token JWT由三部分组成&#xff0c;分别是 Header&#xff0c;Payload&#xff0c;Signatrue JWTBase64(Header).Base6…

C++?类和对象(下)!!!

一、前言 在之前我们已经讨论过了有关类和对象的前置知识以及类中的六大默认成员函数&#xff0c;在本期我们继续再讨论类和对象中剩余的友元、初始化列表等相关知识&#xff0c;如果需要再了解之前的知识的话&#xff0c;链接奉上&#xff1a;C&#xff1f;类和对象&#xff0…

FastAPI 零基础入门指南:10 分钟搭建高性能 API

一、为什么选择 FastAPI&#xff1f; 想象一下&#xff0c;用 Python 写 API 可以像搭积木一样简单&#xff0c;同时还能拥有媲美 Go 语言的性能&#xff0c;这个框架凭借三大核心优势迅速风靡全球&#xff1a; 开发效率提升 3 倍&#xff1a;类型注解 自动文档&#xff0c;…

机器人新革命:Pi 0.5如何让智能走进千家万户

在科技飞速发展的今天&#xff0c;机器人技术正在以一种令人惊喜的方式贴近我们的生活。最近&#xff0c;Physical Intelligence 公司推出了 Pi 0.5 版本&#xff0c;这一创新设计不仅颠覆了传统机器人的运作模式&#xff0c;更让我们看到了未来智能设备融入日常生活的无限可能…

从数据结构说起(一)

1 揭开数据结构神奇的面纱 1.1 初识数据结构 在C的标准库模板&#xff08;Standard Template Library,STL&#xff09;课程上&#xff0c;我初次结识了《数据结构》。C语言提供的标准库模板是面向对象程序设计与泛型程序设计思想相结合的典范。所谓的泛型编程就是编写不依赖于具…

Git基本使用(很详细)

一&#xff1a;Git 概述 1.1 定义&#xff1a;分布式版本控制系统 1.2 版本控制 &#xff08;1&#xff09;定义&#xff1a; 版本控制时一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统 &#xff08;2&#xff09;举例 多副本 优化&#xff1a; 不使用多…

仓颉编程语言最佳实例 “Hello, world!”

仓颉编程语言最佳实例 “Hello, world!” The Best Practice to Cangjie Programming Language - “Hello, world!” BY JACKSON 1. 仓颉集成开发工具&#xff08;IDE&#xff09;安装 打开Chrome浏览器&#xff0c;访问仓颉编程语言官网&#xff1a;https://cangjie-lang.…

[mysql]窗口函数

目录 窗口函数: 为何要学习窗口函数,与mysql5.7实现语句对比 现在我们介绍一下窗口函数: 函数规则 1序号函数 2分布函数 3前后函数 5其他函数 总结 窗口函数: 首先数据库的迁移是非常慢的,大家学习新特性的时候要考虑自己公司的数据库版本是不是和自己学习的吻合 为何…

内存四区(栈)

今天我再次学到了有趣的知识&#xff0c;内存四区&#xff01; 内存四区分为代码区&#xff0c;全局区&#xff0c;栈区&#xff0c;堆区&#xff0c;今天我们详细来讲讲栈区&#xff01; 内存四区和栈区都是用来存放数据的&#xff0c;而栈区存放的数据具体有两类 1.形参数…

新零售行业时代:如何用科技驱动传统零售的转型升级​​

新零售行业时代&#xff1a;如何用科技驱动传统零售的转型升级​​ ​​“在变化的世界中&#xff0c;唯一不变的是变化本身。”​​ ​​一、传统零售的困局&#xff1a;当“生存”成为一场鏖战​​ 街角的便利店老板老王&#xff0c;每天凌晨4点起床进货&#xff0c;却在月…

长途骑行装备攻略:VELO维乐 Angel Revo坐垫伴我畅享旅途

工作忙碌了很久&#xff0c;终于迎来了一个难得的假期。我决定和朋友一起踏上一场长途骑行之旅&#xff0c;远离城市的喧嚣&#xff0c;去寻找那份久违的宁静与自由。这次旅行&#xff0c;不仅是为了旅途风景的放松&#xff0c;更是为了体验一场身体与心灵的挑战。而朋友推荐的…

WebcamJS中文文档

文章目录 WebcamJS针对Chrome 47及以上版本的重要说明浏览器支持演示示例开源协议快速入门指南配置初始化拍摄照片自定义图像大小裁剪图像翻转图像(镜像模式)冻结/预览图像设置备用SWF文件位置重置(关闭)API 参考自定义事件向服务器提交图像跟踪上传进度包含在现有表单中自…

微软官网Win10镜像下载快速获取ISO文件

如何从微软官网轻松下载win10镜像&#xff1f;win10镜像的下载方式主要包括两种&#xff1a; 目录 一&#xff1a;借助官方工具 二&#xff1a;直接微软官网通过浏览器进行下载。 三&#xff1a;实现方法与步骤&#xff1a; 1&#xff1a;利用微软官方提供的MediaCreationT…

逆向|dy|a_bogus|1.0.1.19-fix.01

2025-04-26 请求地址:aHR0cHM6Ly93d3cuZG91eWluLmNvbS91c2VyL01TNHdMakFCQUFBQV96azV6NkoyMG1YeGt0eHBnNkkzRVRKejlyMEs3d2Y2dU9EWlhvd2ttblZWRnB0dlBPMmMwN2J0WFotcVU4V3M 个人主页的视频数据 我们需要逆向这个接口,所以现在需要分析这个请求, 分析这几个数据包可以发现: 只有…

高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!

目录 思路"情境 对象 问题"型 课题选题的类型有哪些呢&#xff1f;这要从课题题目的构成说起。通过对历年来国家社会科学基金立项项目进行分析&#xff0c;小编发现&#xff0c;课题选题类型非常丰富&#xff0c;但一般是围绕限定词、研究对象和研究问题进行不同的组…

springboot项目配置nacos,指定使用环境

遇到这样一个问题&#xff0c;在开发、测试、生成环境之间切换的问题。 大多数的操作是通过修改spring.profiles.active来确定指向使用的环境配置文件&#xff0c;对应项目中需要增加对应的配置文件。 但是现在几乎所有公司都会有代码管理不管是SVN、git&#xff0c;这样就会涉…

DIFY 浅尝 - DIFY + Ollama 添加模型

准备物料 Dify 本地部署 Ollama 下载 Open WebUI 好了现在&#xff0c;假设访问 http://localhost/apps 应该可以打开 Dify&#xff0c;设置用户登录后应该可以看到以下界面 打开 http://localhost:3000/, 你应该可以看到部署好的Open WebUI&#xff0c;并假设有下载好你感…

Java 异常处理全解析:从基础到自定义异常的实战指南

Java 异常处理全解析&#xff1a;从基础到自定义异常的实战指南 一、Java 异常体系&#xff1a;Error 与 Exception 的本质区别 1. 异常体系核心架构 Java把异常当作对象来处理&#xff0c;并定义一个基类java.lang.Throwable作为所有异常的超类。 在Java API中已经定义了许…

开源AI智能名片链动2+1模式S2B2C商城小程序源码赋能下的社交电商创业者技能跃迁与价值重构

摘要&#xff1a;在移动互联网深度重构商业生态的背景下&#xff0c;社交电商创业者面临流量成本攀升、用户粘性不足、供应链协同低效等核心痛点。本文以“开源AI智能名片链动21模式S2B2C商城小程序源码”技术体系为研究对象&#xff0c;通过分析其技术架构、商业逻辑及实战案例…

WSL 中 nvidia-smi: command not found的解决办法

前言 在使用基于 Linux 的 Windows 子系统&#xff08;WSL&#xff09;时&#xff0c;当我们执行某些操作后&#xff0c;可能会遇到输入 nvidia-smi 命令却无法被系统识别的情况。 例如&#xff0c;在终端中输入nvidia-smi 后&#xff0c;系统返回提示 -bash: nvidia-smi: co…