保持敬畏之心
交易是一场持久战

MQL4(30):整合功能 - 使用函数构建更完善的EA

整合所有功能

现在,我们将展示最终使用本章创建的各种辅助函数重构后的 MA 交叉 EA 的完整代码结构。我们假设所有这些函数(如手数计算、验证、开仓、平仓、SL/TP 计算、调整、添加 SL/TP 等)都定义在 IncludeExample.mqh 文件中。

// --- 1. 预处理器指令 ---
#property copyright "tudao"
#include <IncludeExample.mqh> // 包含所有自定义辅助函数

// --- 2. 输入参数 ---
extern bool   UseDynamicLotSize = true;
extern double EquityPercent     = 2.0;
extern double FixedLotSize      = 0.1;
extern double StopLossPips      = 50;    // SL/TP 点数应命名清晰
extern double TakeProfitPips    = 100;
extern int    Slippage          = 5;     // 滑点 (pips)
extern int    MagicNumber       = 123;
extern int    FastMAPeriod      = 10;
extern int    SlowMAPeriod      = 20;

// --- 3. 全局变量 ---
int    g_BuyTicket       = 0;     // 当前买单号
int    g_SellTicket      = 0;     // 当前卖单号
double g_onePipValue     = 0.0;   // 1 pip 价值 
int    g_slippagePoints  = 0;   // 滑点 points 

// --- 4. 初始化函数 ---
int OnInit()
{
   g_onePipValue  = PipPoint(Symbol()); // 调用 IncludeExample.mqh 中的函数
   g_slippagePoints = GetSlippage(Symbol(), Slippage); // 调用 IncludeExample.mqh 中的函数
   return(INIT_SUCCEEDED);
}

// --- 5. 核心逻辑函数 ---
void OnTick() 
{
   // a. 计算指标
   double FastMA = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double SlowMA = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);

   // b. 计算并验证手数
   // 注意: 此处 StopLossPips 使用外部输入值,实际应根据信号动态决定
   double lotSize = CalcLotSize(UseDynamicLotSize, EquityPercent, StopLossPips, FixedLotSize);
   lotSize = VerifyLotSize(lotSize); // 验证并规范化手数
   if (lotSize <= 0) return(0); // 手数无效则不交易

   // c. 买入逻辑 (金叉且无买单)
   if (FastMA > SlowMA && g_BuyTicket == 0)
   {
      // i. 关闭反向卖单
      bool closedOK = CloseOppositeOrder(Symbol(), g_SellTicket, g_slippagePoints); // 调用平仓函数
      if (closedOK) g_SellTicket = 0; // 成功关闭或无需关闭才清零

      // ii. 开立新买单 (仅当反向单处理完毕)
      if (g_SellTicket == 0)
      {
         g_BuyTicket = OpenBuyOrder(Symbol(), lotSize, g_slippagePoints, MagicNumber); // 调用开买单函数

         // iii. 如果开单成功且需要 SL/TP,则添加
         if (g_BuyTicket > 0 && (StopLossPips > 0 || TakeProfitPips > 0))
         {
             // 封装好的添加 SL/TP 逻辑
             AddAndVerifySLTP(g_BuyTicket, StopLossPips, TakeProfitPips);
             /*
             // 或者展开逻辑:
             if (OrderSelect(g_BuyTicket, SELECT_BY_TICKET)) {
                 double openPrice = OrderOpenPrice();
                 double slPrice = CalcBuyStopLoss(Symbol(), StopLossPips, openPrice);
                 double tpPrice = CalcBuyTakeProfit(Symbol(), TakeProfitPips, openPrice);
                 slPrice = AdjustBelowStopLevel(Symbol(), slPrice, 5, openPrice); // 调整
                 tpPrice = AdjustAboveStopLevel(Symbol(), tpPrice, 5, openPrice); // 调整
                 AddStopProfit(g_BuyTicket, slPrice, tpPrice); // 添加
             }
             */
         }
      } // end if g_SellTicket == 0
   } // end if 买入条件

   // d. 卖出逻辑 (与买入逻辑对称)
   if (FastMA < SlowMA && g_SellTicket == 0) // 死叉且无卖单
   {
       // i. 关闭反向买单
       bool closedOK = CloseOppositeOrder(Symbol(), g_BuyTicket, g_slippagePoints); // 调用平仓函数
       if (closedOK) g_BuyTicket = 0; // 成功关闭或无需关闭才清零

       // ii. 开立新卖单 (仅当反向单处理完毕)
       if (g_BuyTicket == 0)
       {
           g_SellTicket = OpenSellOrder(Symbol(), lotSize, g_slippagePoints, MagicNumber); // 调用开卖单函数

           // iii. 如果开单成功且需要 SL/TP,则添加
           if (g_SellTicket > 0 && (StopLossPips > 0 || TakeProfitPips > 0))
           {
               // 封装好的添加 SL/TP 逻辑
               AddAndVerifySLTP(g_SellTicket, StopLossPips, TakeProfitPips);
               /*
               // 或者展开逻辑:
               if (OrderSelect(g_SellTicket, SELECT_BY_TICKET)) {
                   double openPrice = OrderOpenPrice();
                   double slPrice = CalcSellStopLoss(Symbol(), StopLossPips, openPrice);
                   double tpPrice = CalcSellTakeProfit(Symbol(), TakeProfitPips, openPrice);
                   slPrice = AdjustAboveStopLevel(Symbol(), slPrice, 5, openPrice); // 调整
                   tpPrice = AdjustBelowStopLevel(Symbol(), tpPrice, 5, openPrice); // 调整
                   AddStopProfit(g_SellTicket, slPrice, tpPrice); // 添加
               }
               */
           }
       } // end if g_BuyTicket == 0
   } // end if 卖出条件

   return;
}

代码解释:

  1. 包含文件: 代码开头通过 #include <IncludeExample.mqh> 引入了包含所有自定义辅助函数的文件。
  2. 手数处理: 在函数开始处,调用 CalcLotSize()VerifyLotSize() 函数来计算并验证最终要使用的手数 lotSize
  3. 买入/卖出逻辑块:
    1. 关闭反向订单: 使用封装好的 CloseBuyOrder()CloseSellOrder() 函数。注意修正后的逻辑: 只有在确认平仓成功(或订单本就不存在/已关闭)后,才将对应的全局票号变量(g_SellTicketg_BuyTicket)置零。
    2. 开立新订单: 使用封装好的 OpenBuyOrder()OpenSellOrder() 函数(这些函数内部已包含交易上下文检查和基本错误处理,且发送时不带 SL/TP)。
    3. 添加 SL/TP: 在新订单成功开立后 (g_BuyTicket > 0g_SellTicket > 0) 且用户设置了 SL/TP 点数 (StopLossPips > 0 || TakeProfitPips > 0) 的情况下,执行以下系列调用:
      1. OrderSelect() 选中新订单。
      2. OrderOpenPrice() 获取开仓价。
      3. 调用 CalcBuyStopLoss() / CalcSellStopLoss() 计算目标止损价。
      4. 调用 CalcBuyTakeProfit() / CalcSellTakeProfit() 计算目标止盈价。
      5. 调用 AdjustBelowStopLevel() / AdjustAboveStopLevel() 对计算出的 SL/TP 价格进行停止级别验证和自动调整(示例中使用了 5 pips 的缓冲)。
      6. 最后调用 AddStopProfit() 函数将最终验证和调整过的 SL/TP 价格应用到订单上。

关于函数使用的章节内容结束,给大家展示了如何通过函数将复杂的交易逻辑模块化,从而构建出结构清晰、功能健壮且易于维护的智能交易系统。

赞(0)
未经允许不得转载:图道交易 » MQL4(30):整合功能 - 使用函数构建更完善的EA
分享到