系统交易 게시글

基于 Heikin Ashi 的 MT4 EA 自动交易 – 利用移动平均线交叉实现趋势交易

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

在本篇文章中,我们将介绍如何创建一个基于移动平均线交叉的自动交易系统(EA),并通过 Heikin Ashi 指标来优化交易策略。

定义输入参数

//--- 输入参数
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 message =StringFormat("手数小于允许的最小值 %.2f",min_volume);
      Alert(message);
      return(INIT_PARAMETERS_INCORRECT);
   }
  
   myPoint = GetPipPoint(Symbol());
   mySlippage = GetSlippage(Symbol(),Slippage);

   return(INIT_SUCCEEDED);
}


市场价格变化时的逻辑

当市场价格发生变化时,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 群组 t.me/codeMQL


如果您正在寻找支持您交易的应用程序,请在应用商店下载我们的 SignalForex 应用。

https://play.google.com/store/apps/details?id=com.autobotfx.signalforex





연관 포스트

댓글 (0)