文章 "使用MQL5实现布林带交易策略:逐步指南"

 

新文章 使用MQL5实现布林带交易策略:逐步指南已发布:

使用MQL5实现基于布林带交易策略的自动化交易算法的逐步指南。这是一个基于创建EA的详细教程,对交易者非常有帮助。

通过遵循这个逐步教程,交易者可以构建一个使用布林带来执行买卖订单的专家顾问(Expert Advisor,EA),基于特定的市场条件。本教程将涵盖重要的主题,包括配置布林带指标、控制交易头寸,以及处理订单执行和错误管理。无论您是开发经验丰富的专业人士,还是对算法交易不太熟悉的新手,本教程都将为交易者提供一个坚实的基础,以设计和改进他们的交易方法。 

本教程将涵盖以下主题:

  1. 布林带策略的定义
  2. 布林带策略描述
  3. 使用MQL5的逐步实现
  4. 结论

From 2016 to 2019, the strategy executed 1425 trades, 857 closed with trades which is 20.28% more than the loss trades.

从2016年到2019年,该策略执行了1425笔交易,其中857笔交易获利,比亏损交易多出20.28%。

作者:Kikkih25

 

我们现在是 2024 年,而您的回溯测试 却在 2019 年停止。

是因为它在 2019 年之后不起作用吗?

 
EA 有许多 编译错误。
 

以下是至少能在 MT5 中编译的代码:)

附加的文件:
 

该代码错误太多。我已经修正了错误,现将更新后的代码发布在这里。不客气!

//+------------------------------------------------------------------+
//|布林线mq5
//|版权所有 2024 年,MetaQuotes 有限公司。|
//|https://www.mql5.com ||
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh> // 加入贸易库
CTrade trade; // 创建 CTrade 类的实例 

// 布林线策略的输入参数
input int BandPeriod = 30;
input double BandDeviation = 2.0;
input double LotSize = 0.2;
input int Slippage = 3;
input double StopLoss = 70;
input double TakeProfit = 140;

int Bb_Handle; // 布林线指标的手柄 

//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
int OnInit()
{
   // 创建布林线指标句柄
   Bb_Handle = iBands(_Symbol, PERIOD_CURRENT, BandPeriod, 0, BandDeviation, PRICE_CLOSE);
   
   if(Bb_Handle == INVALID_HANDLE)
   {
      Print("Error creating Bollinger Bands indicator"); 
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 专家去初始化函数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 释放布林线指标句柄
   IndicatorRelease(Bb_Handle);
}

//+------------------------------------------------------------------+
//| 专家勾选功能|
//+------------------------------------------------------------------+
void OnTick()
{
   double upperBand[], lowerBand[], middleBand[];
   
   // 将布林线数值复制到数组中
   if(CopyBuffer(Bb_Handle, 0, 0, 1, upperBand) <= 0 ||
      CopyBuffer(Bb_Handle, 1, 0, 1, middleBand) <= 0 ||
      CopyBuffer(Bb_Handle, 2, 0, 1, lowerBand) <= 0)
   {
      Print("Error copying band values");
      return;
   }
   
   double upper = upperBand[0];
   double lower = lowerBand[0];
   double middle = middleBand[0];
   double price = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
   double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   
   // 买入信号:价格低于下限且无未平仓合约 
   if(price < lower && !IsPositionOpen(_Symbol))
   {
      double sl, tp;
      CalculateSLTP(sl, tp, Ask, true);
      if(trade.Buy(LotSize, _Symbol, Ask, sl, tp, "Buy Order"))
         Print("Buy order opened at price: ", Ask);
      else
         Print("Error opening BUY order:", trade.ResultRetcode());
   }
   // 卖出信号:价格高于上限值,且无未平仓合约
   else if(price > upper && !IsPositionOpen(_Symbol))
   {
      double sl, tp;
      CalculateSLTP(sl, tp, Bid, false);
      if(trade.Sell(LotSize, _Symbol, Bid, sl, tp, "Sell Order"))
         Print("Sell order opened at price:", Bid);
      else
         Print("Error opening SELL order:", trade.ResultRetcode());
   }
}

//+------------------------------------------------------------------+
//| 检查某个符号是否有未结头寸
//+------------------------------------------------------------------+
bool IsPositionOpen(string symbol)
{
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(PositionGetSymbol(i) == symbol)
         return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 关闭一个符号的所有位置|
//+------------------------------------------------------------------+
void CloseAllPositions(string symbol)
{
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if(PositionGetSymbol(i) == symbol)
      {
         ulong ticket = PositionGetTicket(i);
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
            trade.PositionClose(ticket, Slippage);
         else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
            trade.PositionClose(ticket, Slippage);
         // 等待订单处理完毕后再继续
         Sleep(1000);
      }
   }
}

//+------------------------------------------------------------------+
//| 计算止损和获利水平
//+------------------------------------------------------------------+
void CalculateSLTP(double &sl, double &tp, double price, bool isBuy)
{
   if(isBuy)
   {
      sl = price - StopLoss * _Point;
      tp = price + TakeProfit * _Point;
   }
   else 
   {
      sl = price + StopLoss * _Point;
      tp = price - TakeProfit * _Point;
   }
}
 
上段和中段的复制缓冲区索引 不正确;iBands 应使用 UPPER_BAND、BASE_LINE、LOWER_BAND。
 
这篇文章非常棒。感谢作者。我会在我的平价差交易中尝试一下。
 
这正是我所做的....
研究代码,并将其应用到您的特定策略中,以获得最佳效果。