所以我遇到的问题是,当我运行内置的 mql5 测试器时,我的指标值不会动态变化,它们保持恒定值,即使我编写了代码,以便在每个价格变动时不断读取指标值。这导致机器人没有进行一笔交易,我已经尝试了一切来解决这个问题,甚至阅读了 mql5 的文档,据我所知,我没有犯任何错误。欢迎任何反馈或解决方案。
//+------------------------------------------------------------------+
//| SwingTradeBot.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
CTrade trade; // Trade object for order operations
input int SMA_Fast_Period = 50; // Fast SMA period
input int SMA_Slow_Period = 200; // Slow SMA period
input int RSI_Period = 14; // RSI period
input double Risk_Percent = 2.0; // Risk percentage of account balance
input double StopLossFactor = 2.0; // Factor for setting stop loss
input double TakeProfitFactor = 3.0; // Factor for setting take profit
// Global variables for indicator values
double FastMA_Current, SlowMA_Current, RSI_Current;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
Print("Swing Trading Bot Initialized");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Calculate the lot size based on risk management rules |
//+------------------------------------------------------------------+
double CalculateLotSize() {
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Percent / 100;
double atr = iATR(_Symbol, PERIOD_D1, 14);
double stopLossPips = atr * StopLossFactor / _Point;
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
double calculatedLotSize = riskAmount / (stopLossPips * pipValue);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
calculatedLotSize = MathMax(minLot, MathMin(calculatedLotSize, maxLot));
calculatedLotSize = MathRound(calculatedLotSize / lotStep) * lotStep;
Print("Calculated Lot Size: ", calculatedLotSize); // Debugging print
return calculatedLotSize;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
UpdateIndicators();
double lot = CalculateLotSize();
if (ShouldOpenBuyOrder()) {
Print("Attempting to place buy order."); // Debugging print
PlaceBuyOrder(lot);
} else if (ShouldOpenSellOrder()) {
Print("Attempting to place sell order."); // Debugging print
PlaceSellOrder(lot);
}
}
//+------------------------------------------------------------------+
//| Update indicator values |
//+------------------------------------------------------------------+
void UpdateIndicators() {
FastMA_Current = iMA(_Symbol, PERIOD_D1, SMA_Fast_Period, 0, MODE_SMA, PRICE_CLOSE);
SlowMA_Current = iMA(_Symbol, PERIOD_D1, SMA_Slow_Period, 0, MODE_SMA, PRICE_CLOSE);
RSI_Current = iRSI(_Symbol, PERIOD_H4, RSI_Period, PRICE_CLOSE);
datetime currentBarTime = iTime(_Symbol, PERIOD_D1, 0);
Print("Current Bar Time: ", TimeToString(currentBarTime, TIME_DATE|TIME_MINUTES),
", FastMA: ", FastMA_Current,
", SlowMA: ", SlowMA_Current,
", RSI: ", RSI_Current);
}
//+------------------------------------------------------------------+
//| Check if a buy order should be opened |
//+------------------------------------------------------------------+
bool ShouldOpenBuyOrder() {
Print("Checking Buy Condition - FastMA: ", FastMA_Current, ", SlowMA: ", SlowMA_Current, ", RSI: ", RSI_Current); // Debugging print
return (FastMA_Current > SlowMA_Current && RSI_Current < 50);
}
//+------------------------------------------------------------------+
//| Check if a sell order should be opened |
//+------------------------------------------------------------------+
bool ShouldOpenSellOrder() {
Print("Checking Sell Condition - FastMA: ", FastMA_Current, ", SlowMA: ", SlowMA_Current, ", RSI: ", RSI_Current); // Debugging print
return (FastMA_Current < SlowMA_Current && RSI_Current > 50);
}
//+------------------------------------------------------------------+
//| Place a buy order |
//+------------------------------------------------------------------+
void PlaceBuyOrder(double lot) {
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double stopLoss = currentPrice - StopLossFactor * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double takeProfit = currentPrice + TakeProfitFactor * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
MqlTradeRequest request;
MqlTradeResult result;
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lot;
request.type = ORDER_TYPE_BUY;
request.price = currentPrice;
request.sl = stopLoss;
request.tp = takeProfit;
request.deviation = 3;
request.type_filling = ORDER_FILLING_RETURN;
request.comment = "Buy Order";
if (!trade.OrderSend(request, result)) {
Print("Error opening buy order: ", result.comment, ", Error Code: ", GetLastError()); // Debugging print
} else {
Print("Buy order placed successfully."); // Debugging print
}
}
//+------------------------------------------------------------------+
//| Place a sell order |
//+------------------------------------------------------------------+
void PlaceSellOrder(double lot) {
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double stopLoss = currentPrice + StopLossFactor * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double takeProfit = currentPrice - TakeProfitFactor * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
MqlTradeRequest request;
MqlTradeResult result;
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lot;
request.type = ORDER_TYPE_SELL;
request.price = currentPrice;
request.sl = stopLoss;
request.tp = takeProfit;
request.deviation = 3;
request.type_filling = ORDER_FILLING_RETURN;
request.comment = "Sell Order";
if (!trade.OrderSend(request, result)) {
Print("Error opening sell order: ", result.comment, ", Error Code: ", GetLastError()); // Debugging print
} else {
Print("Sell order placed successfully."); // Debugging print
}
}
在 MQL5 中使用指标与在 MQL4 中使用它们有很大不同。
在 MQL4 指标中,只需调用并返回它们的值。
在 MQL5 中,定义了指标(返回指标句柄),并且必须定义一个缓冲区(以数组的形式)并准备好存储它们的值。
调用定义的指标(通过使用其句柄)时,必须将返回值复制到数组中。
您还必须设置:
#property indicator_buffers 1 // or 2,3...
第一次使用时,这似乎令人生畏,但是当在多个时间范围(如 iMA 5、30、D1)上应用类似的指标时,它很容易工作。