系统交易 게시글

使用移动平均线交叉策略的MetaTrader 4专家顾问

첨부파일
34176.zip (2.06 KB, 다운로드 0회)

在今天的文章中,我们将一起创建一个基于移动平均线交叉策略的EA(专家顾问)。首先,我们需要定义输入参数。

//--- 输入参数
input    int      period_ma_fast = 8;  //快速移动平均期数
input    int      period_ma_slow = 20;  //慢速移动平均期数

input    double   takeProfit  = 20.0;  //止盈(点数)
input    double   stopLoss    = 20.0;  //止损(点数)

input    double   lotSize     = 0.10;  //手数
input    double   minEquity   = 100.0;  //最低资金(美元)

input    int Slippage = 3;       //滑点
input    int MagicNumber = 889;  //魔术编号


接下来,我们定义全局变量。这些全局变量在整个程序中都可以被访问。

//全局变量
double   myPoint    = 0.0;
int      mySlippage = 0;
int      BuyTicket   = 0;
int      SellTicket  = 0;


当EA被执行时,首先调用的函数是 OnInit()。这个函数通常用于验证和初始化全局变量。

int OnInit()
{
   //验证输入,建议始终对输入数据进行验证
   if (period_ma_fast >= period_ma_slow || takeProfit < 0.0 || stopLoss < 0.0 || lotSize < 0.01 || minEquity < 10){
      Alert("警告 - 输入数据无效");
      return (INIT_PARAMETERS_INCORRECT);
   }
   
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(lotSize<min_volume)
   {
      string pesan =StringFormat("交易手数低于允许的最低值 %.2f",min_volume);
      Alert (pesan);
      return(INIT_PARAMETERS_INCORRECT);
   }
   
   myPoint = GetPipPoint(Symbol());
   mySlippage = GetSlippage(Symbol(),Slippage);

   return(INIT_SUCCEEDED);
}


当市场价格发生变动时(即tick),将调用 OnTick() 函数并执行其中的所有指令。

OnTick() 函数内部,将调用其他多个函数。

首先调用 checkMinEquity() 函数来检查交易资金是否充足。如果资金大于最低要求,将进行信号变量声明,并调用 NewCandle() 函数,通知新的蜡烛形成。

接下来的 getSignal() 函数将读取两个移动平均指标的值,返回上升或下降交叉的信号信息,这将作为买入/卖出的信号。

根据信号信息,传递给 transaction() 函数来设置买入或卖出头寸。

接着调用 setTPSL() 函数,用于设置止盈和止损价格。

如果资金不满足最低要求,将显示警告并终止EA。

void OnTick()
{
   if (cekMinEquity()){
      
      int signal = -1;
      bool isNewCandle = NewCandle(Period(), Symbol());
      
      signal = getSignal(isNewCandle);
      transaction(isNewCandle, signal);
      setTPSL();
      
      
   }else{
      //停止交易,因为资金不足
      Print("EA将因资金不足而终止");
   }
}


设置止盈止损的函数

void setTPSL(){
   int   tOrder = 0;
   string   strMN = "", pair = "";
   double sl = 0.0, tp = 0.0;
   
   pair = Symbol();
   
   tOrder = OrdersTotal();
   for (int i=tOrder-1; i>=0; i--){
      bool hrsSelect = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      strMN = IntegerToString(OrderMagicNumber());
      if (StringFind(strMN, IntegerToString(MagicNumber), 0) == 0 && StringFind(OrderSymbol(), pair, 0) == 0 ){
         if (OrderType() == OP_BUY && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
            if (takeProfit > 0) {
               tp = OrderOpenPrice() + (takeProfit * myPoint);
            }else{
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() - (stopLoss * myPoint);
            }else{
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
               if(OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrBlue)){
                  Print ("订单修改成功");
               }
            }
         }
         if (OrderType() == OP_SELL && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
            if (takeProfit > 0) {
               tp = OrderOpenPrice() - (takeProfit * myPoint);
            }else{
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() + (stopLoss * myPoint);
            }else{
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
               if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrRed)){
                  Print ("订单修改成功");
               }
            }
         }
         
      }//结束魔术编号和交易符号的判断
   }//结束循环
}


如果你希望获得更多的交易知识和分享,欢迎加入我们的Telegram群组。

点击这里加入Telegram群组


如果你在寻找可以支持你交易的应用程序,欢迎下载我们的SignalForex应用程序,支持安卓系统。

点击这里下载SignalForex应用程序


연관 포스트

댓글 (0)