比如:给我写一个趋势 EA,赢利加仓金字塔 EA,先看日线阻力位置,如果 K 线在 15 日均线下,均线向下发散,判断大方向为空。再 4 小时,1 小时,15 分钟找共振。
//+------------------------------------------------------------------+//| TrendPyramid.mq4 |//| Copyright 2026, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2026, MetaQuotes Software Corp."#property link "https://www.mql5.com"#property version "1.00"#property strict//===== 输入参数区 =====input int EMA_Period = 15; //EMA周期(和你截图一致15)input ENUM_MA_METHOD MA_Method = MODE_EMA; //指数EMAinput ENUM_APPLIED_PRICE Apply_Price = PRICE_CLOSE; //应用收盘价Closeinput double Base_Lot = 0.01; //底仓初始手数input double Pyramid_Factor = 1.3; //金字塔加仓系数 >1,逐级放大input int Max_Add_Layers = 4; //最多加仓几次(不含底仓)input int Profit_Add_Points = 40; //浮盈达到多少点才允许加仓input int StopLoss_Points = 80; //初始止损点数input int BreakEven_Points = 30; //浮盈到达该点数,全部单子移保本input bool Auto_Close_Revert = true; //趋势反转(站上EMA)全部平仓input int Slippage = 3; //滑点input int Magic_Number = 7788; //EA魔术码//===== 全局函数:获取指定周期EMA值 =====double GetEMA(ENUM_TIMEFRAMES tf, int shift){ return iMA(_Symbol, tf, EMA_Period, 0, MA_Method, Apply_Price, shift);}//===== 判断单个周期是否空头条件:价格在EMA下方,且EMA向下发散 =====bool IsBearTF(ENUM_TIMEFRAMES tf){ double ema0 = GetEMA(tf,0); double ema1 = GetEMA(tf,1); double close0 = iClose(_Symbol, tf, 0); //条件:收盘价在EMA下方 + EMA当前值 < 前一根K线EMA(均线向下) return (close0 < ema0) && (ema0 < ema1);}//===== 统计当前EA的空单数量 =====int CountShortOrders(){ int cnt=0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==OP_SELL) { cnt++; } } } return cnt;}//===== 获取当前所有空单的总浮盈(点数) =====double GetShortProfitPoints(){ double totalPts=0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==OP_SELL) { double pts = (OrderOpenPrice() - Bid) / Point; totalPts += pts; } } } return totalPts;}//===== 全部平空单 =====void CloseAllShort(){ for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==OP_SELL) { double ask = Ask; bool res = OrderClose(OrderTicket(),OrderLots(),ask,Slippage,Red); } } }}//===== 移动全部空单到保本价 =====void MoveToBreakEven(){ for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==OP_SELL) { double bePrice = OrderOpenPrice(); if(OrderStopLoss() < bePrice) { OrderModify(OrderTicket(),OrderOpenPrice(),bePrice,0,0,Green); } } } }}//===== 开空单函数 =====bool OpenSell(double lot){ double sl = Ask + StopLoss_Points * Point; return OrderSend(_Symbol,OP_SELL,lot,Bid,Slippage,sl,0,"D1-15EMA共振空",Magic_Number,0,Red);}//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+void OnTick(){ //---------- 四周期共振判断 D1 H4 H1 M15 全部空头 ---------- bool condD1 = IsBearTF(PERIOD_D1); bool condH4 = IsBearTF(PERIOD_H4); bool condH1 = IsBearTF(PERIOD_H1); bool condM15 = IsBearTF(PERIOD_M15); bool AllBear = condD1 && condH4 && condH1 && condM15; int shortCnt = CountShortOrders(); double profitPts = GetShortProfitPoints(); //===== 情况1:趋势反转,全部平仓 ===== if(Auto_Close_Revert && !AllBear) { if(shortCnt>0) { CloseAllShort(); return; } } //===== 情况2:没有持仓,共振满足 → 开底仓空单 ===== if(shortCnt == 0) { if(AllBear) { OpenSell(Base_Lot); } return; } //===== 情况3:已有持仓,判断保本移动 ===== if(profitPts >= BreakEven_Points) { MoveToBreakEven(); } //===== 情况4:盈利金字塔加仓(浮盈达标、加仓层数没到上限、共振依然成立) ===== if(AllBear && profitPts >= Profit_Add_Points && shortCnt <= Max_Add_Layers) { double addLot = Base_Lot * pow(Pyramid_Factor, shortCnt); OpenSell(addLot); }}//+------------------------------------------------------------------+
如果报错,就截图给豆包让他修复
//+------------------------------------------------------------------+//| TrendPyramid_v2_Fixed_LotStep.mq4 |//| 修复 LotStep 未定义报错,双向共振金字塔EA |//+------------------------------------------------------------------+#property copyright "Copyright 2026"#property link ""#property version "2.02"#property strict//===== 输入参数区 =====input int EMA_Period = 15; //EMA周期input ENUM_MA_METHOD MA_Method = MODE_EMA; //指数EMAinput ENUM_APPLIED_PRICE Apply_Price = PRICE_CLOSE; //应用收盘价Closeinput bool Allow_Buy = true; //允许多头input bool Allow_Sell = true; //允许空头input double Base_Lot = 0.01; //底仓初始手数input double Pyramid_Factor = 1.3; //金字塔加仓系数input int Max_Add_Layers = 4; //最多加仓层数(不含底仓)input int Profit_Add_Points = 40; //总浮盈门槛(满足才允许加仓)input int Add_Gap_Points = 50; //加仓价格间隔过滤(行情拉开距离再加)input int StopLoss_Points = 80; //初始止损点数input int BreakEven_Points = 30; //保本移动浮盈门槛input int TP1_Points = 120; //第一止盈点位input double TP1_Close_Ratio = 0.5; //TP1平仓比例 0.5=平一半input int TP2_Points = 300; //第二止盈点位,全部平仓input int Slippage = 3; //最大滑点input int Magic_Number = 7788; //魔术码input bool Auto_Close_Revert = true; //趋势反转,同向全部平仓//===== 全局变量:新K线标记 =====datetime lastM15BarTime = 0;//===== 手数标准化函数(自动读取品种VOLUME_STEP)=====double NormalizeLot(double lot){ double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); if(step <= 0) step = 0.01; lot = NormalizeDouble(lot, 8); lot = MathRound(lot / step) * step; double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); if(lot < minLot) lot = minLot; return lot;}//===== 获取指定周期EMA(取已收盘K线 shift=1) =====double GetEMA(ENUM_TIMEFRAMES tf, int shift){ return iMA(_Symbol, tf, EMA_Period, 0, MA_Method, Apply_Price, shift);}//===== 判断单周期多头条件:收盘K线价格在EMA上方,EMA向上 =====bool IsBullTF(ENUM_TIMEFRAMES tf){ double ema0 = GetEMA(tf,1); double ema1 = GetEMA(tf,2); double close0 = iClose(_Symbol, tf, 1); return (close0 > ema0) && (ema0 > ema1);}//===== 判断单周期空头条件:收盘K线价格在EMA下方,EMA向下 =====bool IsBearTF(ENUM_TIMEFRAMES tf){ double ema0 = GetEMA(tf,1); double ema1 = GetEMA(tf,2); double close0 = iClose(_Symbol, tf, 1); return (close0 < ema0) && (ema0 < ema1);}//===== 判断是否M15新K线(收盘触发) =====bool IsNewBarM15(){ datetime currBar = iTime(_Symbol, PERIOD_M15, 0); if(currBar != lastM15BarTime) { lastM15BarTime = currBar; return true; } return false;}//===== 统计EA指定方向订单数量 =====int CountOrders(int ordType){ int cnt=0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { cnt++; } } } return cnt;}//===== 获取同方向全部订单总浮盈点数 =====double GetTotalProfitPoints(int ordType){ double totalPts=0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { if(ordType == OP_BUY) totalPts += (Bid - OrderOpenPrice()) / Point; else totalPts += (OrderOpenPrice() - Bid) / Point; } } } return totalPts;}//===== 获取最近一张同方向订单开仓价 =====double GetLastOpenPrice(int ordType){ double lastPrice = 0; for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { lastPrice = OrderOpenPrice(); } } } return lastPrice;}//===== 平掉全部同方向订单(校验返回值+日志) =====void CloseAllDir(int ordType){ for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { double closePrice = (ordType == OP_BUY) ? Bid : Ask; bool ok = OrderClose(OrderTicket(), OrderLots(), closePrice, Slippage, Red); if(!ok) Print("CloseAllDir 平仓失败! Ticket:",OrderTicket()," Error:",GetLastError()); else Print("CloseAllDir 平仓成功 Ticket:",OrderTicket()); } } }}//===== 移动全部同方向订单到保本价(校验返回值) =====void MoveAllToBE(int ordType){ for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { double bePrice = OrderOpenPrice(); double currSL = OrderStopLoss(); if( (ordType == OP_BUY && bePrice > currSL) || (ordType == OP_SELL && bePrice < currSL) ) { bool ok = OrderModify(OrderTicket(), OrderOpenPrice(), bePrice, OrderTakeProfit(), 0, Green); if(!ok) Print("MoveAllToBE 修改保本失败 Ticket:",OrderTicket()," Error:",GetLastError()); } } } }}//===== 分批止盈处理 =====void ProcessPartialTP(int ordType){ for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic_Number && OrderType()==ordType) { double op = OrderOpenPrice(); double currPts = (ordType == OP_BUY) ? (Bid - op)/Point : (op - Bid)/Point; double closePrice = (ordType == OP_BUY) ? Bid : Ask; if(currPts >= TP2_Points) { bool ok = OrderClose(OrderTicket(), OrderLots(), closePrice, Slippage, Green); if(!ok) Print("TP2全平失败 Ticket:",OrderTicket()," Err:",GetLastError()); continue; } if(currPts >= TP1_Points && OrderLots() > 0.0001) { double closeLot = NormalizeLot(OrderLots() * TP1_Close_Ratio); bool ok = OrderClose(OrderTicket(), closeLot, closePrice, Slippage, Green); if(!ok) Print("TP1部分平仓失败 Ticket:",OrderTicket()," Err:",GetLastError()); } } } }}//===== 开多单 =====bool OpenBuy(double lot){ lot = NormalizeLot(lot); double sl = Ask - StopLoss_Points * Point; bool ok = OrderSend(_Symbol, OP_BUY, lot, Ask, Slippage, sl, 0, "D1-15EMA共振多", Magic_Number, 0, Green); if(!ok) Print("开多失败, Error:",GetLastError()); return ok;}//===== 开空单 =====bool OpenSell(double lot){ lot = NormalizeLot(lot); double sl = Bid + StopLoss_Points * Point; bool ok = OrderSend(_Symbol, OP_SELL, lot, Bid, Slippage, sl, 0, "D1-15EMA共振空", Magic_Number, 0, Red); if(!ok) Print("开空失败, Error:",GetLastError()); return ok;}//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+void OnTick(){ //===== 1. 读取四周期共振条件(只用已经收盘K线) ===== bool bullD1 = IsBullTF(PERIOD_D1); bool bullH4 = IsBullTF(PERIOD_H4); bool bullH1 = IsBullTF(PERIOD_H1); bool bullM15 = IsBullTF(PERIOD_M15); bool AllBull = bullD1 && bullH4 && bullH1 && bullM15; bool bearD1 = IsBearTF(PERIOD_D1); bool bearH4 = IsBearTF(PERIOD_H4); bool bearH1 = IsBearTF(PERIOD_H1); bool bearM15 = IsBearTF(PERIOD_M15); bool AllBear = bearD1 && bearH4 && bearH1 && bearM15; int buyCnt = CountOrders(OP_BUY); int sellCnt = CountOrders(OP_SELL); double buyProfitPts = GetTotalProfitPoints(OP_BUY); double sellProfitPts = GetTotalProfitPoints(OP_SELL); //===== 分批止盈 每tick持续检测 ===== if(buyCnt>0) ProcessPartialTP(OP_BUY); if(sellCnt>0) ProcessPartialTP(OP_SELL); //===== 保本移动 每tick持续检测 ===== if(buyCnt>0 && buyProfitPts >= BreakEven_Points) MoveAllToBE(OP_BUY); if(sellCnt>0 && sellProfitPts >= BreakEven_Points) MoveAllToBE(OP_SELL); //===== 趋势反转自动平仓 ===== if(Auto_Close_Revert) { if(buyCnt>0 && !AllBull) CloseAllDir(OP_BUY); if(sellCnt>0 && !AllBear) CloseAllDir(OP_SELL); } //===== 仅M15新K线收盘才执行开仓/加仓逻辑,过滤盘中毛刺 ===== if(!IsNewBarM15()) return; //============= 多头逻辑 ============= if(Allow_Buy) { if(buyCnt == 0) { if(AllBull) OpenBuy(Base_Lot); } else { if(AllBull && buyProfitPts >= Profit_Add_Points && buyCnt <= Max_Add_Layers) { double lastOpen = GetLastOpenPrice(OP_BUY); double gapPts = (Bid - lastOpen)/Point; if(gapPts >= Add_Gap_Points) { double addLot = Base_Lot * pow(Pyramid_Factor, buyCnt); OpenBuy(addLot); } } } } //============= 空头逻辑 ============= if(Allow_Sell) { if(sellCnt == 0) { if(AllBear) OpenSell(Base_Lot); } else { if(AllBear && sellProfitPts >= Profit_Add_Points && sellCnt <= Max_Add_Layers) { double lastOpen = GetLastOpenPrice(OP_SELL); double gapPts = (lastOpen - Bid)/Point; if(gapPts >= Add_Gap_Points) { double addLot = Base_Lot * pow(Pyramid_Factor, sellCnt); OpenSell(addLot); } } } }}//+------------------------------------------------------------------+
只给大家一个方向,可以写自己的策略 |