//+------------------------------------------------------------------+
//| 趋势加微马丁策略.mq5 |
//| Copyright 2026,廖先生 |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026,廖先生"
#property link "https://www.mql5.com"
#property version "1.00"
#property description "趋势策略"
#property description "极少数人能在交易中长期获利,请全面了解此策略再小资金尝试"
#property description "EA只是工具,使用EA获得的盈利和造成的损失均由您自行负责,与EA开发者无关"
#include <Trade/Trade.Mqh>
#include <Trade/PositionInfo.Mqh>
#include <Trade/OrderInfo.Mqh>
//+------------------------------------------------------------------+
//| 输入参数(用户可修改) |
//+------------------------------------------------------------------+
input string AllowedSymbols = "XAUUSD"; // 允许交易的品种(多个用逗号分隔)
input string Section1 = "=====基础设置=====";
input double InitialLotSize = 0.01; // 初始手数
input string GridLotsStr = "0.02,0.03"; // 加仓手数序列(第一加仓,第二加仓)
input int MagicNumber = 20260415; // EA魔术号(身份证)
input int Slippage = 3; // 滑点(点)
input int MaxSpread = 50; // 最大允许点差(点)
input string Section2 = "=====指标参数=====";
input int BBPPeriod = 20; // 布林带周期
input double BBDeviation = 2.0; // 布林带宽度
input int RSIPeriod = 14; // RSI周期
input int MAPeriod = 5; // MA周期
input int EMAPeriod = 5; // EMA周期
input string Section3 = "=====仓位管理=====";
input int GridInterval = 200; // 加仓间隔(点)
input int TakeProfitPoints = 350; // 固定止盈点数
input int SecondGridStopLoss = 200; // 第二加仓单固定止损(点)
input int TrailingStopPoints = 200; // 移动止损点数
input int TrailingActivation = 350; // 移动止损激活点数
input string Section4 = "=====风控设置=====";
input double MaxFloatingLoss1 = 15.0; // 第一级风控:浮动亏损达余额百分比(%),全平暂停5分钟
input double MaxFloatingLoss2 = 30.0; // 第二级风控:浮动亏损达余额百分比(%),永久暂停
input int PauseSeconds = 300; // 暂停时间(秒)
input string Section5 = "=====时间设置=====";
input int TimeStopSeconds = 3600; // 第二加仓单超时平仓时间(秒)
//+------------------------------------------------------------------+
//| 全局变量(代码内部使用) |
//+------------------------------------------------------------------+
// 交易对象
CTrade trade;
// 指标句柄
int EMA5Handle; // EMA5
int EMA10Handle; // EMA10
int EMA20Handle; // EMA20
int BBHandle;
int ADXHandle;
int RSIHandle;
// 指标数组
double EMA5[];
double EMA10[];
double EMA20[];
double BB_middle[];
double BB_upper[];
double BB_lower[];
double ADX[];
double RSI[];
double MA5[];
// 加仓手数数组(从输入字符串解析)
double gridLots[];
// 状态变量
datetime lastBarTime; // 上一根K线时间(用于避免同一K线重复开单)
int lastOrderTickets[3]; // 0-首单,1-第一加仓单,2-第二加仓单
datetime secondOrderOpenTime; // 第二加仓单开仓时间
datetime pauseUntil; // 暂停截止时间
bool isPaused = false; // 是否暂停状态
bool isPermanentlyStopped = false; // 是否永久停止(30%风控触发)
// 方向记录(避免反方向同时持仓)
int currentDirection = 0; // 0=无持仓, 1=做多, -1=做空
// 移动止损追踪
double secondGridHighestProfit = 0; // 第二加仓单最高盈利点数
// 辅助标志
bool isFirstTick = true; // 是否是第一个tick
datetime lastTradeTime = 0; // 上次开仓时间(避免同一信号重复开单)
//+------------------------------------------------------------------+
//| 状态机枚举 |
//+------------------------------------------------------------------+
enum EA_STATE
{
STATE_STOPPED, // 停止(30%风控触发)
STATE_RUNNING, // 运行中
STATE_PAUSED // 临时暂停(15%风控触发或时间风控)
};
EA_STATE g_eaState = STATE_RUNNING;
//+------------------------------------------------------------------+
//| 解析加仓手数字符串 |
//+------------------------------------------------------------------+
void ParseGridLots()
{
string temp = GridLotsStr;
string lots[];
int count = StringSplit(temp, ',', lots);
ArrayResize(gridLots, count);
for(int i = 0; i < count; i++)
{
gridLots[i] = StringToDouble(lots[i]);
}
}
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 解析加仓手数
ParseGridLots();
// 创建指标句柄
EMA5Handle = iMA(_Symbol, PERIOD_M5, 5, 0, MODE_EMA, PRICE_CLOSE);
EMA10Handle = iMA(_Symbol, PERIOD_M5, 10, 0, MODE_EMA, PRICE_CLOSE);
EMA20Handle = iMA(_Symbol, PERIOD_M5, 20, 0, MODE_EMA, PRICE_CLOSE);
BBHandle = iBands(_Symbol, PERIOD_M5, BBPPeriod, 0, BBDeviation, PRICE_CLOSE);
RSIHandle = iRSI(_Symbol, PERIOD_M5, RSIPeriod, PRICE_CLOSE);
// 检查句柄是否创建成功
if(EMA5Handle == INVALID_HANDLE || EMA10Handle == INVALID_HANDLE || EMA20Handle == INVALID_HANDLE ||
BBHandle == INVALID_HANDLE ||
RSIHandle == INVALID_HANDLE)
{
Print("指标句柄创建失败");
return INIT_FAILED;
}
// 设置交易
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
trade.SetAsyncMode(false);
// 初始化订单数组
ArrayFill(lastOrderTickets, 0, 3, 0);
// 获取上一根K线时间
lastBarTime = iTime(_Symbol, PERIOD_M5, 1);
Print("EA初始化成功,品种:", _Symbol, " 魔术号:", MagicNumber);
Print("加仓手数序列: ", GridLotsStr);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| 反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 释放指标句柄
if(EMA5Handle != INVALID_HANDLE) IndicatorRelease(EMA5Handle);
if(EMA10Handle != INVALID_HANDLE) IndicatorRelease(EMA10Handle);
if(EMA20Handle != INVALID_HANDLE) IndicatorRelease(EMA20Handle);
if(BBHandle != INVALID_HANDLE) IndicatorRelease(BBHandle);
if(RSIHandle != INVALID_HANDLE) IndicatorRelease(RSIHandle);
Print("EA已卸载,原因代码:", reason);
}
//+------------------------------------------------------------------+
//| 检查当前品种是否允许交易 |
//+------------------------------------------------------------------+
bool IsSymbolAllowed()
{
if(StringLen(AllowedSymbols) == 0)
return true;
string currentSymbol = _Symbol;
string symbolsList = AllowedSymbols;
StringToUpper(symbolsList);
StringToUpper(currentSymbol);
if(StringFind(symbolsList, currentSymbol) >= 0)
return true;
static bool warningPrinted = false;
if(!warningPrinted)
{
Print("品种 ", _Symbol, " 不在允许列表中");
warningPrinted = true;
}
return false;
}
//+------------------------------------------------------------------+
//| 异常处理 |
//+------------------------------------------------------------------+
bool HandleExceptions()
{
// 服务器时间检查
if(TimeCurrent() <= 0)
{
static datetime lastWarn = 0;
if(TimeCurrent() - lastWarn > 300)
{
Print("[异常] 服务器时间异常");
lastWarn = TimeCurrent();
}
return false;
}
// 周末检查
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
if(dt.day_of_week == 0 || dt.day_of_week == 6)
{
static datetime lastWarn = 0;
if(TimeCurrent() - lastWarn > 3600)
{
Print("[异常] 周末休市");
lastWarn = TimeCurrent();
}
return false;
}
// 连接检查
if(!TerminalInfoInteger(TERMINAL_CONNECTED))
{
static datetime lastWarn = 0;
if(TimeCurrent() - lastWarn > 60)
{
Print("[异常] 服务器断开连接");
lastWarn = TimeCurrent();
}
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| 检查点差 |
//+------------------------------------------------------------------+
bool IsSpreadAcceptable()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
if(ask <= 0 || bid <= 0 || point <= 0)
return false;
// 点差单位转换(5位报价平台)
double pipSize = point;
if(digits == 5 || digits == 3)
pipSize = point * 10;
double currentSpread = (ask - bid) / pipSize;
if(currentSpread > MaxSpread)
{
static datetime lastWarning = 0;
if(TimeCurrent() - lastWarning >= 5)
{
PrintFormat("点差过大: %.1f > %d", currentSpread, MaxSpread);
lastWarning = TimeCurrent();
}
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| 检查做多条件 |
//+------------------------------------------------------------------+
bool CheckBuyCondition()
{
// 获取指标数据
double ema5[1], ema10[1], ema20[1];
double rsi[1];
double bbMiddle[1];
CopyBuffer(EMA5Handle, 0, 1, 1, ema5);
CopyBuffer(EMA10Handle, 0, 1, 1, ema10);
CopyBuffer(EMA20Handle, 0, 1, 1, ema20);
CopyBuffer(RSIHandle, 0, 1, 1, rsi);
CopyBuffer(BBHandle, 0, 1, 1, bbMiddle);
double close = iClose(_Symbol, PERIOD_M5, 1);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// EMA多头排列
bool emaCondition = (ema5[0] > ema10[0] && ema10[0] > ema20[0]);
// 收盘价条件
bool closeCondition = (close > ema5[0] - 50 * point);
// MACD条件
// RSI条件
bool rsiCondition = (rsi[0] < 70);
// 布林带条件(收盘价 > 中轨)
bool bbCondition = (close > bbMiddle[0]);
return (emaCondition && closeCondition && rsiCondition && bbCondition);
}
//+------------------------------------------------------------------+
//| 检查做空条件 |
//+------------------------------------------------------------------+
bool CheckSellCondition()
{
// 获取指标数据
double ema5[1], ema10[1], ema20[1];
double rsi[1];
double bbMiddle[1];
CopyBuffer(EMA5Handle, 0, 1, 1, ema5);
CopyBuffer(EMA10Handle, 0, 1, 1, ema10);
CopyBuffer(EMA20Handle, 0, 1, 1, ema20);
CopyBuffer(RSIHandle, 0, 1, 1, rsi);
CopyBuffer(BBHandle, 0, 1, 1, bbMiddle);
double close = iClose(_Symbol, PERIOD_M5, 1);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// EMA空头排列
bool emaCondition = (ema5[0] < ema10[0] && ema10[0] < ema20[0]);
// 收盘价条件
bool closeCondition = (close < ema5[0] + 50 * point);
// RSI条件
bool rsiCondition = (rsi[0] > 30);
// 布林带条件(收盘价 < 中轨)
bool bbCondition = (close < bbMiddle[0]);
return (emaCondition && closeCondition && rsiCondition && bbCondition);
}
//+------------------------------------------------------------------+
//| 执行做多 |
//+------------------------------------------------------------------+
void ExecutionBuy()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double lot = NormalizeLot(InitialLotSize);
if(trade.Buy(lot, _Symbol, ask, 0, 0, "Trend Buy"))
{
lastOrderTickets[0] = (int)trade.ResultOrder();
currentDirection = 1;
Print("开首单成功 方向:BUY 手数:", lot, " Ticket:", lastOrderTickets[0]);
}
else
{
Print("开首单失败 错误:", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 执行做空 |
//+------------------------------------------------------------------+
void ExecutionSell()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double lot = NormalizeLot(InitialLotSize);
if(trade.Sell(lot, _Symbol, bid, 0, 0, "Trend Sell"))
{
lastOrderTickets[0] = (int)trade.ResultOrder();
currentDirection = -1;
Print("开首单成功 方向:SELL 手数:", lot, " Ticket:", lastOrderTickets[0]);
}
else
{
Print("开首单失败 错误:", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 检查并执行加仓 |
//+------------------------------------------------------------------+
void CheckAndAddGrid()
{
int count=CountOpenedOrders();
if(count==0 || count>=3) return;
if(currentDirection==0) return;
double lastPrice=GetLastOrderPrice();
if(lastPrice<=0) return;
double currentPrice=(currentDirection==1)?SymbolInfoDouble(_Symbol,SYMBOL_BID):SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
if(point<=0) return;
double diff=MathAbs(currentPrice-lastPrice)/point;
if(diff>=GridInterval)
{
int gridIndex=count-1;
if(gridIndex<0 || gridIndex>=ArraySize(gridLots))
{
Print("错误: gridIndex=",gridIndex," 超出范围");
return;
}
double lot=NormalizeLot(gridLots[gridIndex]);
if(currentDirection==1)
{
double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
if(ask<=0) return;
if(trade.Buy(lot,_Symbol,ask,0,0,"Grid Add"))
{
int newTicket=(int)trade.ResultOrder();
for(int i=0;i<3;i++)
{
if(lastOrderTickets[i]==0)
{
lastOrderTickets[i]=newTicket;
break;
}
}
if(count==2)
{
secondOrderOpenTime=TimeCurrent();
SetSecondGridStopLoss();
}
}
}
else
{
double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
if(bid<=0) return;
if(trade.Sell(lot,_Symbol,bid,0,0,"Grid Add"))
{
int newTicket=(int)trade.ResultOrder();
for(int i=0;i<3;i++)
{
if(lastOrderTickets[i]==0)
{
lastOrderTickets[i]=newTicket;
break;
}
}
if(count==2)
{
secondOrderOpenTime=TimeCurrent();
SetSecondGridStopLoss();
}
}
}
}
}
//+------------------------------------------------------------------+
//| 检查止盈条件 |
//+------------------------------------------------------------------+
bool CheckTakeProfit()
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// 首单止盈
if(lastOrderTickets[0] != 0 && GetOrderProfitInPoints(lastOrderTickets[0]) >= TakeProfitPoints)
{
CloseOrder(lastOrderTickets[0]);
lastOrderTickets[0] = 0;
Print("首单止盈平仓");
return true;
}
// 第一加仓单止盈(平首单+第一加仓单)
if(lastOrderTickets[1] != 0 && GetOrderProfitInPoints(lastOrderTickets[1]) >= TakeProfitPoints)
{
if(lastOrderTickets[0] != 0)
CloseOrder(lastOrderTickets[0]);
CloseOrder(lastOrderTickets[1]);
lastOrderTickets[0] = 0;
lastOrderTickets[1] = 0;
Print("第一加仓单止盈,平首单+第一加仓单");
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 检查第二加仓单移动止损 |
//+------------------------------------------------------------------+
void CheckTrailingStop()
{
if(lastOrderTickets[2] == 0) return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double profit = GetOrderProfitInPoints(lastOrderTickets[2]);
// 更新最高盈利
if(profit > secondGridHighestProfit)
secondGridHighestProfit = profit;
// 浮盈达到激活点数后启动移动止损
if(secondGridHighestProfit >= TrailingActivation)
{
if(profit <= secondGridHighestProfit - TrailingStopPoints)
{
CloseOrder(lastOrderTickets[2]);
lastOrderTickets[2] = 0;
secondGridHighestProfit = 0;
Print("第二加仓单移动止损平仓");
}
}
}
//+------------------------------------------------------------------+
//| 设置第二加仓单固定止损 |
//+------------------------------------------------------------------+
void SetSecondGridStopLoss()
{
if(lastOrderTickets[2] == 0) return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double sl = 0;
if(currentDirection == 1) // 做多
{
double openPrice = GetOrderOpenPrice(lastOrderTickets[2]);
sl = openPrice - SecondGridStopLoss * point;
}
else // 做空
{
double openPrice = GetOrderOpenPrice(lastOrderTickets[2]);
sl = openPrice + SecondGridStopLoss * point;
}
trade.PositionModify(lastOrderTickets[2], sl, 0);
Print("设置第二加仓单固定止损 ", SecondGridStopLoss, " 点");
}
//+------------------------------------------------------------------+
//| 时间风控:第二加仓单超时平仓 |
//+------------------------------------------------------------------+
bool CheckTimeStop()
{
if(lastOrderTickets[2] == 0) return false;
if(TimeCurrent() - secondOrderOpenTime >= TimeStopSeconds)
{
CloseAllOrders();
ArrayFill(lastOrderTickets, 0, 3, 0);
currentDirection = 0;
secondGridHighestProfit = 0;
g_eaState = STATE_PAUSED;
pauseUntil = TimeCurrent() + PauseSeconds;
Print("时间风控触发:第二加仓单超时,平全部持仓,暂停", PauseSeconds, "秒");
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 资金管理:15%全平重启,30%永久暂停 |
//+------------------------------------------------------------------+
bool CheckMoneyManagement()
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
if(balance <= 0) return false;
double floatingLossPercent = (balance - equity) / balance * 100;
// 30%永久暂停
if(floatingLossPercent >= MaxFloatingLoss2)
{
if(g_eaState != STATE_STOPPED)
{
CloseAllOrders();
g_eaState = STATE_STOPPED;
Print("资金管理:亏损达", MaxFloatingLoss2, "%,EA永久暂停");
}
return true;
}
// 15%全平并暂停
if(floatingLossPercent >= MaxFloatingLoss1)
{
if(g_eaState != STATE_PAUSED)
{
CloseAllOrders();
ArrayFill(lastOrderTickets, 0, 3, 0);
currentDirection = 0;
secondGridHighestProfit = 0;
g_eaState = STATE_PAUSED;
pauseUntil = TimeCurrent() + PauseSeconds;
Print("资金管理:亏损达", MaxFloatingLoss1, "%,全平平仓,暂停", PauseSeconds, "秒");
}
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 标准化手数 |
//+------------------------------------------------------------------+
double NormalizeLot(double lot)
{
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double normalizedLot = NormalizeDouble(lot / step, 0) * step;
if(normalizedLot < minLot) normalizedLot = minLot;
if(normalizedLot > maxLot) normalizedLot = maxLot;
return normalizedLot;
}
//+------------------------------------------------------------------+
//| 更新订单状态 |
//+------------------------------------------------------------------+
void UpdateOrderStatus()
{
for(int i=0;i<3;i++)
{
if(lastOrderTickets[i]!=0 && !PositionSelectByTicket(lastOrderTickets[i]))
lastOrderTickets[i]=0;
}
int actualCount=0;
for(int i=PositionsTotal()-1;i>=0;i--)
{
ulong ticket=PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==MagicNumber)
{
actualCount++;
bool found=false;
for(int j=0;j<3;j++)
{
if(lastOrderTickets[j]==(int)ticket)
{
found=true;
break;
}
}
if(!found)
{
for(int j=0;j<3;j++)
{
if(lastOrderTickets[j]==0)
{
lastOrderTickets[j]=(int)ticket;
break;
}
}
}
}
}
if(actualCount==0)
{
ArrayFill(lastOrderTickets,0,3,0);
currentDirection=0;
secondGridHighestProfit=0;
}
else
{
for(int i=0;i<3;i++)
{
if(lastOrderTickets[i]!=0 && PositionSelectByTicket(lastOrderTickets[i]))
{
currentDirection=(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)?1:-1;
break;
}
}
}
}
//+------------------------------------------------------------------+
//| 计算已开订单数量 |
//+------------------------------------------------------------------+
int CountOpenedOrders()
{
int count = 0;
for(int i = 0; i < 3; i++)
{
if(lastOrderTickets[i] != 0)
count++;
}
return count;
}
//+------------------------------------------------------------------+
//| 获取最后一个订单的开仓价 |
//+------------------------------------------------------------------+
double GetLastOrderPrice()
{
for(int i = 2; i >= 0; i--)
{
if(lastOrderTickets[i] != 0)
{
return GetOrderOpenPrice(lastOrderTickets[i]);
}
}
return 0;
}
//+------------------------------------------------------------------+
//| 获取订单开仓价 |
//+------------------------------------------------------------------+
double GetOrderOpenPrice(int ticket)
{
if(!PositionSelectByTicket(ticket)) return 0;
return PositionGetDouble(POSITION_PRICE_OPEN);
}
//+------------------------------------------------------------------+
//| 获取订单浮动盈亏(点数) |
//+------------------------------------------------------------------+
double GetOrderProfitInPoints(int ticket)
{
if(!PositionSelectByTicket(ticket)) return 0;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ?
SymbolInfoDouble(_Symbol, SYMBOL_BID) :
SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
return (currentPrice - openPrice) / point;
else
return (openPrice - currentPrice) / point;
}
//+------------------------------------------------------------------+
//| 平仓单个订单 |
//+------------------------------------------------------------------+
void CloseOrder(int ticket)
{
if(ticket == 0) return;
if(!PositionSelectByTicket(ticket)) return;
trade.PositionClose(ticket);
Print("平仓订单:", ticket);
}
//+------------------------------------------------------------------+
//| 平仓所有订单 |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
trade.PositionClose(ticket);
Print("平仓订单:", ticket);
}
}
}
}
//+------------------------------------------------------------------+
//| Tick函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// ========== 1. 基础检查 ==========
if(!IsSymbolAllowed()) return;
if(!HandleExceptions()) return;
//if(!IsSpreadAcceptable()) return;
// ========== 2. 状态检查 ==========
if(g_eaState == STATE_STOPPED)
{
// 30%风控触发,永久停止
return;
}
if(g_eaState == STATE_PAUSED)
{
if(TimeCurrent() < pauseUntil)
return;
else
{
// 暂停结束,重置状态
g_eaState = STATE_RUNNING;
isPaused = false;
ArrayFill(lastOrderTickets, 0, 3, 0);
currentDirection = 0;
secondGridHighestProfit = 0;
Print("暂停结束,恢复运行");
}
}
// ========== 3. 资金管理检查(优先级最高) ==========
if(CheckMoneyManagement()) return;
// ========== 4. 更新订单状态 ==========
UpdateOrderStatus();
// ========== 5. 检查第二加仓单移动止损 ==========
CheckTrailingStop();
// ========== 6. 检查止盈 ==========
if(CheckTakeProfit()) return;
// ========== 7. 时间风控(第二加仓单超时) ==========
if(CheckTimeStop()) return;
// ========== 8. 加仓逻辑 ==========
CheckAndAddGrid();
// ========== 9. 开新仓(首单) ==========
// 避免同一K线重复开单
datetime currentBarTime = iTime(_Symbol, PERIOD_M5, 0);
if(currentBarTime == lastBarTime)
return;
lastBarTime = currentBarTime;
// 无持仓时才能开首单
if(CountOpenedOrders() == 0 && currentDirection == 0)
{
// 避免同一信号重复开单(5秒内不重复)
if(TimeCurrent() - lastTradeTime < 5)
return;
if(CheckBuyCondition())
{
ExecutionBuy();
lastTradeTime = TimeCurrent();
}
else if(CheckSellCondition())
{
ExecutionSell();
lastTradeTime = TimeCurrent();
}
}
}
- 不懂就问。编程0基础,想学MQL5语言,有没有必要先学C++?谢谢各位大佬!
- 如何开始学习MQL5
- 各位大佬,有人能帮我把这个转成MT5的吗,超级简单的
马丁 你这是
【新手必看】如何防止机器人误判:讨论代码时请使用代码表述功能
- 2023.06.13
- www.mql5.com
大家好,我是官网版主。 官网内部有机器人辅助管理,目的是自动下架一些有误导性的内容。 内容过长,或同一个IP多次注册,容易导致机器人误判,而被无辜删帖。 如果您被无故删帖,我们对这种体验感到万分抱歉。 为了防止机器人误判,请在讨论代码的时候使用代码表述功能...