机器人正在修改的EA,有空有闲的可当游戏玩玩。全部源码:
//+------------------------------------------------------------------+
//| 输入参数 |
//+------------------------------------------------------------------+
input group "==== 核心参数 ===="
input int FastMA_Period = 5; // 快速均线周期(5-8)
input int SlowMA_Period = 13; // 慢速均线周期(12-20)
input int MA_Method = MODE_SMA; // 均线计算方法
input int MA_Price = PRICE_CLOSE; // 均线应用价格
input group "==== 资金管理 ===="
input double BaseBalance = 1000.0; // 每1000美元开仓0.01手
input double MaxLotSize = 5.0; // 最大交易手数
input double MinLotSize = 0.01; // 最小交易手数
input int MaxTrades = 5; // 最大同时持仓数
input group "==== 止损与止盈 ===="
input double StopLossUSD = 1.5; // 止损金额(美元/0.01手)
input double TakeProfitUSD = 3.0; // 止盈金额(美元/0.01手)
input bool UseTrailingStop = true; // 启用追踪止损
input double TrailingStopUSD = 1.0; // 追踪止损距离(美元/0.01手)
input double TrailingStepUSD = 0.5; // 追踪止损步长(美元/0.01手)
input bool UseBreakEven = true; // 启用保本止损
input double BreakEvenAtUSD = 1.5; // 保本触发距离(美元/0.01手)
input double BreakEvenPlusUSD = 0.3; // 保本后止损调整(美元/0.01手)
input group "==== 趋势过滤 ===="
input int ADX_Period = 10; // ADX周期(10-14)
input double ADX_Threshold = 18; // ADX趋势强度阈值(15-22)
input int RSI_Period = 10; // RSI周期(10-14)
input double RSI_Overbought = 60; // RSI超买阈值(55-65)
input double RSI_Oversold = 40; // RSI超卖阈值(35-45)
input int MACD_Fast = 8; // MACD快线
input int MACD_Slow = 17; // MACD慢线
input int MACD_Signal = 9; // MACD信号线
input group "==== 其他设置 ===="
input int MagicNumber = 202312; // EA魔术码
input string TradeComment = "均线黄金转折EA"; // 订单注释
input bool EnableAlerts = true; // 启用警报
input bool PrintDebug = true; // 启用调试信息
//+------------------------------------------------------------------+
//| 全局变量 |
//+------------------------------------------------------------------+
double lastFastMA, lastSlowMA, lastADX, lastDiPlus, lastDiMinus, lastRSI;
double lastMACDMain, lastMACDSignal;
datetime lastTradeTime = 0;
int lastOrderType = -1;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(PrintDebug) Print("EA初始化开始...");
// 检查参数合理性
if(FastMA_Period >= SlowMA_Period)
{
Alert("错误: 快速均线周期必须小于慢速均线周期!");
return(INIT_PARAMETERS_INCORRECT);
}
if(StopLossUSD <= 0 || TakeProfitUSD <= 0)
{
Alert("错误: 止损和止盈必须大于0!");
return(INIT_PARAMETERS_INCORRECT);
}
if(PrintDebug) Print("EA初始化完成");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA终止函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(PrintDebug) Print("EA终止");
}
//+------------------------------------------------------------------+
//| 计算手数函数 |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
double lotSize = NormalizeDouble(AccountBalance() / BaseBalance * 0.01, 2);
lotSize = MathMax(lotSize, MinLotSize);
lotSize = MathMin(lotSize, MaxLotSize);
if(PrintDebug) PrintFormat("账户余额=%.2f, 计算手数=%.2f", AccountBalance(), lotSize);
return lotSize;
}
//+------------------------------------------------------------------+
//| 检查交易条件函数 |
//+------------------------------------------------------------------+
bool CheckTradingConditions()
{
// 检查是否有未平仓订单
int openTrades = CountOpenTrades();
if(openTrades >= MaxTrades)
{
if(PrintDebug) Print("已达到最大持仓数量限制: ", openTrades, "/", MaxTrades);
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| 获取指标数据函数 |
//+------------------------------------------------------------------+
bool RefreshIndicatorData()
{
lastFastMA = iMA(NULL, 0, FastMA_Period, 0, MA_Method, MA_Price, 1);
lastSlowMA = iMA(NULL, 0, SlowMA_Period, 0, MA_Method, MA_Price, 1);
lastADX = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 1);
lastDiPlus = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI, 1);
lastDiMinus = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 1);
lastRSI = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, 1);
lastMACDMain = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_MAIN, 1);
lastMACDSignal = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_SIGNAL, 1);
if(GetLastError() != 0)
{
if(PrintDebug) Print("获取指标数据错误: ", GetLastError());
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| 计算开仓信号函数 |
//+------------------------------------------------------------------+
int CalculateSignal()
{
if(!RefreshIndicatorData()) return 0;
// 获取前一根K线的指标值
double fastMAPrev = iMA(NULL, 0, FastMA_Period, 0, MA_Method, MA_Price, 2);
double slowMAPrev = iMA(NULL, 0, SlowMA_Period, 0, MA_Method, MA_Price, 2);
double macdMainPrev = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_MAIN, 2);
double macdSignalPrev = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_SIGNAL, 2);
// 检查趋势强度
bool strongTrend = lastADX > ADX_Threshold;
// 检查均线交叉
bool fastAboveSlowNow = lastFastMA > lastSlowMA;
bool fastAboveSlowPrev = fastMAPrev > slowMAPrev;
bool fastBelowSlowNow = lastFastMA < lastSlowMA;
bool fastBelowSlowPrev = fastMAPrev < slowMAPrev;
// 检查MACD信号
bool macdAboveSignalNow = lastMACDMain > lastMACDSignal;
bool macdAboveSignalPrev = macdMainPrev > macdSignalPrev;
bool macdBelowSignalNow = lastMACDMain < lastMACDSignal;
bool macdBelowSignalPrev = macdMainPrev < macdSignalPrev;
// 检查RSI条件
bool rsiNotOverbought = lastRSI < RSI_Overbought;
bool rsiNotOversold = lastRSI > RSI_Oversold;
// 检查DI+和DI-关系
bool diPlusAboveDiMinus = lastDiPlus > lastDiMinus;
bool diPlusBelowDiMinus = lastDiPlus < lastDiMinus;
// 买入信号
if(!fastAboveSlowPrev && fastAboveSlowNow &&
!macdAboveSignalPrev && macdAboveSignalNow &&
rsiNotOverbought && diPlusAboveDiMinus && strongTrend)
{
if(PrintDebug) Print("生成买入信号");
return 1; // 买入信号
}
// 卖出信号
if(!fastBelowSlowPrev && fastBelowSlowNow &&
!macdBelowSignalPrev && macdBelowSignalNow &&
rsiNotOversold && diPlusBelowDiMinus && strongTrend)
{
if(PrintDebug) Print("生成卖出信号");
return -1; // 卖出信号
}
return 0; // 无信号
}
//+------------------------------------------------------------------+
//| 计算止损止盈点数 |
//+------------------------------------------------------------------+
void CalculateStopLevels(double lotSize, double &stopLossPoints, double &takeProfitPoints)
{
// 计算0.01手的止损止盈点数
double baseLot = 0.01;
double ratio = lotSize / baseLot;
// 转换为点数 (假设1点=0.00001对于5位小数货币对)
stopLossPoints = StopLossUSD / ratio / MarketInfo(Symbol(), MODE_TICKVALUE) * MarketInfo(Symbol(), MODE_TICKSIZE) / Point;
takeProfitPoints = TakeProfitUSD / ratio / MarketInfo(Symbol(), MODE_TICKVALUE) * MarketInfo(Symbol(), MODE_TICKSIZE) / Point;
// 确保最小点数
stopLossPoints = MathMax(stopLossPoints, 10);
takeProfitPoints = MathMax(takeProfitPoints, 10);
if(PrintDebug) PrintFormat("手数=%.2f, 止损点数=%.1f, 止盈点数=%.1f", lotSize, stopLossPoints, takeProfitPoints);
}
//+------------------------------------------------------------------+
//| 执行交易函数 |
//+------------------------------------------------------------------+
void ExecuteTrade(int signal)
{
if(!CheckTradingConditions()) return;
double lotSize = CalculateLotSize();
double stopLossPoints, takeProfitPoints;
CalculateStopLevels(lotSize, stopLossPoints, takeProfitPoints);
double entryPrice = 0;
double slPrice = 0;
double tpPrice = 0;
int ticket = -1;
string signalType = (signal == 1) ? "买入" : "卖出";
if(signal == 1) // 买入
{
entryPrice = Ask;
slPrice = entryPrice - stopLossPoints * Point;
tpPrice = entryPrice + takeProfitPoints * Point;
ticket = OrderSend(Symbol(), OP_BUY, lotSize, entryPrice, 3, slPrice, tpPrice,
TradeComment, MagicNumber, 0, Blue);
lastOrderType = OP_BUY;
}
else if(signal == -1) // 卖出
{
entryPrice = Bid;
slPrice = entryPrice + stopLossPoints * Point;
tpPrice = entryPrice - takeProfitPoints * Point;
ticket = OrderSend(Symbol(), OP_SELL, lotSize, entryPrice, 3, slPrice, tpPrice,
TradeComment, MagicNumber, 0, Red);
lastOrderType = OP_SELL;
}
if(signal != 0)
{
if(ticket > 0)
{
if(PrintDebug) Print("订单执行成功, 订单号: ", ticket);
lastTradeTime = TimeCurrent();
if(EnableAlerts)
{
string alertMsg = StringFormat("%s: %s %s 手数 %.2f @ %.5f",
TradeComment, Symbol(), signalType, lotSize, entryPrice);
Alert(alertMsg);
}
}
else
{
if(PrintDebug) Print("订单发送失败, 错误代码: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| 追踪止损函数 |
//+------------------------------------------------------------------+
void TrailingStopManagement()
{
if(!UseTrailingStop && !UseBreakEven) return;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol()) continue;
double lotSize = OrderLots();
double baseLot = 0.01;
double ratio = lotSize / baseLot;
double newSL = OrderStopLoss();
bool modified = false;
if(OrderType() == OP_BUY)
{
double profitInPips = (Bid - OrderOpenPrice()) / Point;
// 保本止损逻辑
if(UseBreakEven && profitInPips >= BreakEvenAtUSD / ratio &&
OrderStopLoss() < OrderOpenPrice())
{
newSL = OrderOpenPrice() + BreakEvenPlusUSD / ratio / MarketInfo(Symbol(), MODE_TICKVALUE) * MarketInfo(Symbol(), MODE_TICKSIZE);
modified = true;
}
// 追踪止损逻辑
if(UseTrailingStop && profitInPips > TrailingStopUSD / ratio)
{
double trailStopPips = TrailingStopUSD / ratio;
double potentialSL = Bid - trailStopPips * Point;
if(potentialSL > newSL)
{
newSL = potentialSL;
modified = true;
}
}
}
else if(OrderType() == OP_SELL)
{
double profitInPips = (OrderOpenPrice() - Ask) / Point;
// 保本止损逻辑
if(UseBreakEven && profitInPips >= BreakEvenAtUSD / ratio &&
OrderStopLoss() > OrderOpenPrice())
{
newSL = OrderOpenPrice() - BreakEvenPlusUSD / ratio / MarketInfo(Symbol(), MODE_TICKVALUE) * MarketInfo(Symbol(), MODE_TICKSIZE);
modified = true;
}
// 追踪止损逻辑
if(UseTrailingStop && profitInPips > TrailingStopUSD / ratio)
{
double trailStopPips = TrailingStopUSD / ratio;
double potentialSL = Ask + trailStopPips * Point;
if(potentialSL < newSL)
{
newSL = potentialSL;
modified = true;
}
}
}
// 如果止损需要调整
if(modified && newSL != OrderStopLoss())
{
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
{
if(PrintDebug) Print("订单修改成功, 新止损: ", newSL);
}
else
{
if(PrintDebug) Print("订单修改失败, 错误代码: ", GetLastError());
}
}
}
}
}
//+------------------------------------------------------------------+
//| 统计开仓订单数量函数 |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| EA主函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 检查是否是新柱
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(NULL, 0, 0);
if(lastBarTime == currentBarTime) return;
lastBarTime = currentBarTime;
// 更新指标数据
int signal = CalculateSignal();
// 执行交易
if(signal != 0 && (lastOrderType == -1 || lastOrderType != signal))
{
ExecuteTrade(signal);
}
// 管理追踪止损
TrailingStopManagement();
}
|