首先感谢各位大佬的分享,受益良多,特别鸣谢大树“My05613828” 大佬,从大佬那找了不少的参考资源
我写了一个MT5的EA代码,源码附上,请各位前辈指正(帮忙看看逻辑是否有问题,回测就爆仓):
一、输入参数
交易手数
止盈差值
止损差值
二、交易逻辑
获取当前品种当前周期的布林上中下轨的价格信息
开仓条件=0
如果价格低于了下轨,开仓条件=1
如果价格超过了上轨,开仓条件=2
获取当前订单数
如果订单数为0,开仓条件=1,买入价格大于等于下轨价格,做多单,按输入差值设置止盈、止损
如果订单数为0,开仓条件=2,卖出价格小于等于上轨价格,做空单,按输入差值设置止盈、止损
如果订单数为1,手中持有多单,买入价格触及中轨,平仓
如果订单数为1,手中持有空单,卖出价格触及中轨,平仓
源码附上:
//+------------------------------------------------------------------+
//| 布林穿透.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//输入参数
input double 交易手数=0.1;
input double 止盈差值=2.5;
input double 止损差值=2.5;
int 开仓条件=0;
MqlTradeRequest 订单保存 = {};
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
// 获取当前买入价格
double bidPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
// 获取当前卖出价格
double askPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
// 获取布林上中下轨价格
int handle = iBands(Symbol(), 0, 20, 0, 2, PRICE_CLOSE);
double bufferUpper[];
double bufferLower[];
double bufferMiddle[];
// 从指标缓冲区获取数据
CopyBuffer(handle, 1, 0, 1, bufferUpper);
CopyBuffer(handle, 2, 0, 1, bufferLower);
CopyBuffer(handle, 0, 0, 1, bufferMiddle);
double upperBand = bufferUpper[0];
double lowerBand = bufferLower[0];
double middleBand = bufferMiddle[0];
//开仓条件判断,如果价格出了布林轨道区间,准备回调下单
if (askPrice > upperBand)
{
开仓条件 = 2;
Print("价格刺穿上轨,准备回调做空,卖出价格:"+string(askPrice)+
"上轨:"+string(upperBand)+"中轨:"+string(middleBand)+"下轨:"+string(lowerBand));
}
if (bidPrice < lowerBand)
{
开仓条件 = 1;
Print("价格刺穿下轨,准备回调做多,买入价格:"+string(bidPrice)+
"上轨:"+string(upperBand)+"中轨:"+string(middleBand)+"下轨:"+string(lowerBand));
}
// 持仓数量
int positionsTotal = PositionsTotal();
//手中无单,价格穿透下轨回调时下多单
if (positionsTotal == 0 && 开仓条件 == 1 && bidPrice >= lowerBand)
{
MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = Symbol();
request.volume = 交易手数;
request.type = ORDER_TYPE_BUY;
request.price = bidPrice;
request.sl = bidPrice - 止损差值;
request.tp = bidPrice + 止盈差值;
MqlTradeResult result = {};
if (!OrderSend(request, result))
{
PrintFormat("下多单异常,错误码 %d",ENUM_ACCOUNT_INFO_INTEGER(GetLastError()));
}
else
{
Print("多单下单成功");
订单保存 = request;
开仓条件 = 0;
}
}
//手中无单,价格穿透上轨回调时下空单
if (positionsTotal == 0 && 开仓条件 == 2 && askPrice <= upperBand)
{
MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = Symbol();
request.volume = 交易手数;
request.type = ORDER_TYPE_SELL;
request.price = askPrice;
request.sl = askPrice + 止损差值;
request.tp = askPrice - 止盈差值;
MqlTradeResult result = {};
if (!OrderSend(request, result))
{
PrintFormat("下空单异常,错误码 %d",ENUM_ACCOUNT_INFO_INTEGER(GetLastError()));
}
else
{
Print("空单下单成功");
订单保存 = request;
开仓条件 = 0;
}
}
// 手中有多单,价格触及中轨主动平仓
if (positionsTotal == 1 && 订单保存.type == ORDER_TYPE_BUY && bidPrice > middleBand)
{
MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.magic=订单保存.magic;
request.position=订单保存.position;
request.symbol = 订单保存.symbol;
request.volume = 订单保存.volume;
request.type = ORDER_TYPE_SELL;
MqlTradeResult result = {};
if (!OrderSend(request, result))
{
PrintFormat("多单平仓异常,错误码 %d",ENUM_ACCOUNT_INFO_INTEGER(GetLastError()));
}
else
{
Print("多单平仓成功");
}
}
// 手中有空单,价格触及中轨主动平仓
if (positionsTotal == 1 && 订单保存.type == ORDER_TYPE_SELL && askPrice < middleBand)
{
MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.magic=订单保存.magic;
request.position=订单保存.position;
request.symbol = 订单保存.symbol;
request.volume = 订单保存.volume;
request.type = ORDER_TYPE_BUY;
MqlTradeResult result = {};
if (!OrderSend(request, result))
{
PrintFormat("空单平仓异常,错误码 %d",ENUM_ACCOUNT_INFO_INTEGER(GetLastError()));
}
else
{
Print("空单平仓成功");
}
}
}
//+------------------------------------------------------------------+ |