|
//+------------------------------------------------------------------+
//| RSIFinalEA.mq5 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
// 输入参数
input int MA30_Period = 30; // 30周期MA
input double MA30_Slope_Threshold = 0.00005;// 30MA斜率阈值
input int MA60_Period = 60; // 60周期MA
input double MA60_Slope_Threshold = 0.00005;// 60MA斜率阈值
input int MA144_Period = 144; // 144周期MA
input double MA144_Slope_Threshold = 0.00005;// 144MA斜率阈值
input int RSI_Period = 14; // RSI周期
input double RSI_OverSold = 35; // 超卖水平
input double RSI_OverBought = 65; // 超买水平
input double LotSize = 0.1; // 交易手数
input int TakeProfitPips = 6000; // 止盈点数
input int StopLossPips = 5000; // 止损点数
input ulong MagicNumber = 888888; // 魔术码
// 全局变量
int ma30_handle, ma60_handle, ma144_handle, rsi_handle;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 初始化指标句柄
ma30_handle = iMA(_Symbol, _Period, MA30_Period, 0, MODE_SMA, PRICE_CLOSE);
ma60_handle = iMA(_Symbol, _Period, MA60_Period, 0, MODE_SMA, PRICE_CLOSE);
ma144_handle = iMA(_Symbol, _Period, MA144_Period, 0, MODE_SMA, PRICE_CLOSE);
rsi_handle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE);
if(ma30_handle==INVALID_HANDLE || ma60_handle==INVALID_HANDLE ||
ma144_handle==INVALID_HANDLE || rsi_handle==INVALID_HANDLE)
{
Print("指标初始化失败!");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!HasPosition())
{
CheckEntryConditions();
}
else
{
CheckExitConditions();
}
}
//+------------------------------------------------------------------+
//| 检查是否存在持仓 |
//+------------------------------------------------------------------+
bool HasPosition()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket>0)
{
if(PositionSelectByTicket(ticket) &&
PositionGetString(POSITION_SYMBOL)==_Symbol &&
PositionGetInteger(POSITION_MAGIC)==MagicNumber)
{
return true;
}
}
}
return false;
}
//+------------------------------------------------------------------+
//| 检查入场条件 |
//+------------------------------------------------------------------+
void CheckEntryConditions()
{
// 获取MA斜率
double ma30_slope = GetMAslope(ma30_handle);
double ma60_slope = GetMAslope(ma60_handle);
double ma144_slope = GetMAslope(ma144_handle);
// 使用独立阈值检查MA斜率条件
if(MathAbs(ma30_slope) > MA30_Slope_Threshold) return;
if(MathAbs(ma60_slope) > MA60_Slope_Threshold) return;
if(MathAbs(ma144_slope) > MA144_Slope_Threshold) return;
// 获取RSI值(索引1=前根K线,索引0=当前K线)
double rsi[2];
if(CopyBuffer(rsi_handle, 0, 0, 2, rsi) != 2) return;
// 精确交叉信号检测
bool buySignal = (rsi[1] < RSI_OverSold) && (rsi[0] >= RSI_OverSold);
bool sellSignal = (rsi[1] > RSI_OverBought) && (rsi[0] <= RSI_OverBought);
if(buySignal) OpenOrder(ORDER_TYPE_BUY);
if(sellSignal) OpenOrder(ORDER_TYPE_SELL);
}
//+------------------------------------------------------------------+
//| 获取MA斜率(当前K线与前一根K线的差值) |
//+------------------------------------------------------------------+
double GetMAslope(int ma_handle)
{
double ma[2];
if(CopyBuffer(ma_handle, 0, 0, 2, ma) != 2) return 0;
return ma[0] - ma[1];
}
//+------------------------------------------------------------------+
//| 执行交易操作 |
//+------------------------------------------------------------------+
void OpenOrder(ENUM_ORDER_TYPE orderType)
{
MqlTradeRequest request={};
MqlTradeResult result={};
double price = orderType==ORDER_TYPE_BUY ? SymbolInfoDouble(_Symbol,SYMBOL_ASK)
: SymbolInfoDouble(_Symbol,SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol,SYMBOL_POINT);
double sl = 0, tp = 0;
// 计算止盈止损(兼容4/5位报价)
if(orderType == ORDER_TYPE_BUY)
{
sl = price - StopLossPips * 10 * point;
tp = price + TakeProfitPips * 10 * point;
}
else
{
sl = price + StopLossPips * 10 * point;
tp = price - TakeProfitPips * 10 * point;
}
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = orderType;
request.price = price;
request.sl = NormalizeDouble(sl, _Digits);
request.tp = NormalizeDouble(tp, _Digits);
request.deviation = 5;
request.magic = MagicNumber;
if(!OrderSend(request, result))
{
Print("开仓失败 错误代码:", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 检查退出条件 |
//+------------------------------------------------------------------+
void CheckExitConditions()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket>0 && PositionSelectByTicket(ticket) &&
PositionGetString(POSITION_SYMBOL)==_Symbol &&
PositionGetInteger(POSITION_MAGIC)==MagicNumber)
{
double profit = PositionGetDouble(POSITION_PROFIT);
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
// 强制平仓检查(当EA重启时确保止损止盈有效)
if(profit >= TakeProfitPips*10*LotSize ||
profit <= -StopLossPips*10*LotSize)
{
ClosePosition(ticket);
}
}
}
}
//+------------------------------------------------------------------+
//| 平仓操作 |
//+------------------------------------------------------------------+
void ClosePosition(ulong ticket)
{
MqlTradeRequest request={};
MqlTradeResult result={};
if(PositionSelectByTicket(ticket))
{
request.action = TRADE_ACTION_DEAL;
request.position = ticket;
request.symbol = _Symbol;
request.volume = PositionGetDouble(POSITION_VOLUME);
request.type = (ENUM_ORDER_TYPE)(PositionGetInteger(POSITION_TYPE)^1);
request.price = PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY
? SymbolInfoDouble(_Symbol,SYMBOL_BID)
: SymbolInfoDouble(_Symbol,SYMBOL_ASK);
request.deviation = 5;
request.magic = MagicNumber;
if(!OrderSend(request, result))
{
Print("平仓失败 错误代码:", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(ma30_handle);
IndicatorRelease(ma60_handle);
IndicatorRelease(ma144_handle);
IndicatorRelease(rsi_handle);
}
|
|