|
mt5ea 抄底摸顶ea
多单过滤条件:均线60>84>120>144>200>300
多单开单条件:macd在0轴下,macd柱子越来越短(监测前面2根,如果第三根主子比前面两根短,开多单)
空单过滤条件:均线60<84<120<144<200<300
开单条件:macd在0轴上,macd柱子越来越短(监测前面2根,如果第三根主子比前面两根短,开多单)
//+------------------------------------------------------------------+
//| ReversalEA.mq5 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- 输入参数
input double LotSize = 0.1; // 交易手数
input int TakeProfit = 10000; // 止盈点数
input int StopLoss = 10000; // 止损点数
input int MagicNumber = 12345; // 魔术码
input bool TimeFilterEnable = true; // 启用时间过滤
input int StartHour = 5; // 开始交易小时(0-23)
input int EndHour = 19; // 结束交易小时(0-23)
input bool SundayOff = true; // 周日禁止交易
input int MA60_Period = 60; // 均线60周期
input int MA84_Period = 84; // 均线84周期
input int MA120_Period = 120; // 均线120周期
input int MA144_Period = 144; // 均线144周期
input int MA200_Period = 200; // 均线200周期
input int MA300_Period = 300; // 均线300周期
//--- 全局变量
int macdHandle; // MACD指标句柄
int maHandles[6]; // 均线指标句柄数组
datetime lastBarTime; // 最后K线时间
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 参数有效性检查
if(StartHour < 0 || StartHour > 23 || EndHour < 0 || EndHour > 23) {
Print("错误:交易时间参数无效(0-23)");
return(INIT_PARAMETERS_INCORRECT);
}
// 创建MACD指标句柄
macdHandle = iMACD(_Symbol, _Period, 12, 26, 9, PRICE_CLOSE);
// 创建均线指标句柄
maHandles[0] = iMA(_Symbol, _Period, MA60_Period, 0, MODE_SMA, PRICE_CLOSE);
maHandles[1] = iMA(_Symbol, _Period, MA84_Period, 0, MODE_SMA, PRICE_CLOSE);
maHandles[2] = iMA(_Symbol, _Period, MA120_Period, 0, MODE_SMA, PRICE_CLOSE);
maHandles[3] = iMA(_Symbol, _Period, MA144_Period, 0, MODE_SMA, PRICE_CLOSE);
maHandles[4] = iMA(_Symbol, _Period, MA200_Period, 0, MODE_SMA, PRICE_CLOSE);
maHandles[5] = iMA(_Symbol, _Period, MA300_Period, 0, MODE_SMA, PRICE_CLOSE);
// 检查句柄是否有效
if(macdHandle == INVALID_HANDLE) {
Print("MACD指标初始化失败!");
return(INIT_FAILED);
}
for(int i=0; i<6; i++) {
if(maHandles == INVALID_HANDLE) {
Print("均线指标",i,"初始化失败!");
return(INIT_FAILED);
}
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 释放指标句柄
IndicatorRelease(macdHandle);
for(int i=0; i<6; i++) {
IndicatorRelease(maHandles);
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!IsNewBar()) return;
CheckForLong();
CheckForShort();
}
//+------------------------------------------------------------------+
//| 时间过滤检查函数 |
//+------------------------------------------------------------------+
bool IsTradingTimeAllowed()
{
if(!TimeFilterEnable) return true;
MqlDateTime timeStruct;
datetime currentTime = TimeCurrent();
TimeToStruct(currentTime, timeStruct);
// 周日检查
if(SundayOff && timeStruct.day_of_week == 0) return false;
// 交易时段检查
if(timeStruct.hour >= StartHour && timeStruct.hour < EndHour) {
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 多单交易条件检查 |
//+------------------------------------------------------------------+
void CheckForLong()
{
if(!IsTradingTimeAllowed()) return;
// 获取均线数据
double maValues[];
ArrayResize(maValues, 6);
if(!GetMAsValues(maValues)) return;
// 验证均线排列:60 > 84 > 120 > 144 > 200 > 300
for(int i=0; i<5; i++) {
if(maValues <= maValues[i+1]) return;
}
// 获取MACD数据
double macdMain[], macdSignal[];
if(!GetMACDValues(macdMain, macdSignal)) return;
// MACD条件检查
if(macdMain[0] >= 0) return; // MACD主线在0轴下
if(!IsHistogramDecreasing(macdMain)) return; // 柱状线连续缩短
OpenOrder(ORDER_TYPE_BUY);
}
//+------------------------------------------------------------------+
//| 空单交易条件检查 |
//+------------------------------------------------------------------+
void CheckForShort()
{
if(!IsTradingTimeAllowed()) return;
// 获取均线数据
double maValues[];
ArrayResize(maValues, 6);
if(!GetMAsValues(maValues)) return;
// 验证均线排列:60 < 84 < 120 < 144 < 200 < 300
for(int i=0; i<5; i++) {
if(maValues >= maValues[i+1]) return;
}
// 获取MACD数据
double macdMain[], macdSignal[];
if(!GetMACDValues(macdMain, macdSignal)) return;
// MACD条件检查
if(macdMain[0] <= 0) return; // MACD主线在0轴上
if(!IsHistogramDecreasing(macdMain)) return; // 柱状线连续缩短
OpenOrder(ORDER_TYPE_SELL);
}
//+------------------------------------------------------------------+
//| 获取均线数值 |
//+------------------------------------------------------------------+
bool GetMAsValues(double &values[])
{
if(ArraySize(values) < 6) ArrayResize(values, 6);
for(int i=0; i<6; i++) {
double buf[1];
if(CopyBuffer(maHandles, 0, 0, 1, buf) != 1) return false;
values = buf[0];
}
return true;
}
//+------------------------------------------------------------------+
//| 获取MACD数值 |
//+------------------------------------------------------------------+
bool GetMACDValues(double &main[], double &signal[])
{
double mainBuf[3], signalBuf[3];
if(CopyBuffer(macdHandle, 0, 0, 3, mainBuf) < 3) return false;
if(CopyBuffer(macdHandle, 1, 0, 3, signalBuf) < 3) return false;
ArraySetAsSeries(mainBuf, true);
ArraySetAsSeries(signalBuf, true);
ArrayResize(main, 3);
ArrayResize(signal, 3);
ArrayCopy(main, mainBuf);
ArrayCopy(signal, signalBuf);
return true;
}
//+------------------------------------------------------------------+
//| 判断MACD柱状线是否递减 |
//+------------------------------------------------------------------+
bool IsHistogramDecreasing(double &macdMain[])
{
if(ArraySize(macdMain) < 3) return false;
// 计算最近三根柱子的绝对值长度
double hist[3];
for(int i=0; i<3; i++) {
hist = MathAbs(macdMain);
}
// 检查是否递减:hist[2] > hist[1] > hist[0]
return (hist[2] > hist[1] && hist[1] > hist[0]);
}
//+------------------------------------------------------------------+
//| 开单函数 |
//+------------------------------------------------------------------+
void OpenOrder(ENUM_ORDER_TYPE orderType)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
double price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
: SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point
: price + StopLoss * _Point;
double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point
: price - TakeProfit * _Point;
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = orderType;
request.price = price;
request.sl = sl;
request.tp = tp;
request.deviation = 5;
request.magic = MagicNumber;
if(!OrderSend(request, result)) {
Print("订单发送失败,错误代码:", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 判断是否新K线 |
//+------------------------------------------------------------------+
bool IsNewBar()
{
datetime currentTime[1];
if(CopyTime(_Symbol, _Period, 0, 1, currentTime) != 1) return false;
if(lastBarTime != currentTime[0]) {
lastBarTime = currentTime[0];
return true;
}
return false;
}
|
|