MQL4 EA策略:趋势追踪与加仓策略
MQL4 EA策略:趋势追踪与加仓策略
这篇文章分享一个结合了趋势追踪和加仓策略的MQL4 EA策略。该策略会在价格突破特定范围后进行建仓,并在盈利目标未达到前,根据价格走势进行加仓操作。
代码cpp//定义可更改参数extern int MagicNumber = 92133; //魔术码extern double OrderVolume = 0.5; //挂单手数extern int Gap = 100; //间距extern double AddVolumeMultiplier = 0.6; //补仓倍数extern int MaxAdditions = 5; //补仓次数extern double ProfitTarget = 40.0; //盈利目标(美金)extern int Slippage = 3; //允许的滑点
//定义全局变量bool firstTradeExecuted = false; //是否已执行第一单交易double markPrice = 0.0; //蓝色标记线价格
color clrNone = clrNONE;
//检查给定魔术码下的特定订单类型的持仓数量int CheckPositionsType(int magicNumber, int orderType){ int totalPositions = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol() && OrderType() == orderType) { totalPositions += OrderLots(); } } return totalPositions;}
//获取给定魔术码下的最后一个特定订单类型的持仓手数double GetLastPositionVolume(int magicNumber, int orderType){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol() && OrderType() == orderType) { return OrderLots(); } } return 0.0;}
//计算给定魔术码下的总盈利double GetTotalProfit(int magicNumber){ double totalProfit = 0.0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol()) { totalProfit += OrderProfit(); } } return totalProfit;}
//检查给定魔术码下的持仓数量int CheckPositions(int magicNumber){ int totalPositions = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol()) { if (OrderType() == OP_BUY || OrderType() == OP_SELL) { totalPositions += OrderLots(); } } } return totalPositions;}
//删除给定魔术码下的所有指定订单类型的挂单void DeletePendingOrders(int magicNumber, int orderType){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol() && OrderType() == orderType) { OrderDelete(OrderTicket()); } }}
//平掉给定魔术码下的所有持仓订单void CloseAllPositions(int magicNumber){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol()) { if (OrderType() == OP_BUY || OrderType() == OP_SELL) { OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), Slippage, clrNone); } } }}
void OnTick(){ // 获取最新价格 double currentPrice = MarketInfo(Symbol(), MODE_BID);
// 检查当前魔术码下是否持仓 if (CheckPositions(MagicNumber) == 0) { // 以当前价格加100点挂单0.5手多单 double buyPrice = currentPrice + Gap; double buyVolume = OrderVolume; int buyTicket = OrderSend(Symbol(), OP_BUYSTOP, buyVolume, buyPrice, Slippage, 0, 0, 'Buy Order', MagicNumber); if (buyTicket > 0) { // 以当前价格减100点挂单0.5手空单 double sellPrice = currentPrice - Gap; double sellVolume = OrderVolume; int sellTicket = OrderSend(Symbol(), OP_SELLSTOP, sellVolume, sellPrice, Slippage, 0, 0, 'Sell Order', MagicNumber); if (sellTicket > 0) { // 删除挂单的多单和空单 DeletePendingOrders(MagicNumber, OP_BUYSTOP); DeletePendingOrders(MagicNumber, OP_SELLSTOP); } } }
// 获取最新价 double latestPrice = MarketInfo(Symbol(), MODE_BID);
// 如果没有执行第一单交易,并且持仓数量不为0,则设置第一单交易标记,并记录蓝色标记线价格 if (!firstTradeExecuted && CheckPositions(MagicNumber) > 0) { firstTradeExecuted = true; markPrice = latestPrice; }
// 如果已执行第一单交易并且最新价在蓝色标记线以下100点,做空0.5手 if (firstTradeExecuted && latestPrice < markPrice - Gap) { double sellVolume; if (!CheckPositionsType(MagicNumber, OP_SELL)) { sellVolume = OrderVolume; int sellTicket = OrderSend(Symbol(), OP_SELL, sellVolume, latestPrice, Slippage, 0, 0, 'Short Order', MagicNumber); if (sellTicket > 0) { return; } } }
// 如果已执行第一单交易并且最新价在蓝色标记线以上100点,做多0.5手 if (firstTradeExecuted && latestPrice > markPrice + Gap) { double buyVolume; if (!CheckPositionsType(MagicNumber, OP_BUY)) { buyVolume = OrderVolume; int buyTicket = OrderSend(Symbol(), OP_BUY, buyVolume, latestPrice, Slippage, 0, 0, 'Long Order', MagicNumber); if (buyTicket > 0) { return; } } }
// 检查当前魔术码是否持仓多单 if (CheckPositionsType(MagicNumber, OP_BUY)) { double lastBuyVolume = GetLastPositionVolume(MagicNumber, OP_BUY); double currentProfit = GetTotalProfit(MagicNumber);
// 每上涨100点补仓一次,最多补仓5次 for (int i = 0; i < MaxAdditions; i++) { if (latestPrice > markPrice + Gap * (i + 1) && currentProfit < ProfitTarget) { double buyVolume = lastBuyVolume * AddVolumeMultiplier; int buyTicket = OrderSend(Symbol(), OP_BUY, buyVolume, latestPrice, Slippage, 0, 0, 'Additional Buy Order', MagicNumber); if (buyTicket > 0) { return; } } } }
// 检查当前魔术码是否持仓空单 if (CheckPositionsType(MagicNumber, OP_SELL)) { double lastSellVolume = GetLastPositionVolume(MagicNumber, OP_SELL); double currentProfit = GetTotalProfit(MagicNumber);
// 每下跌100点补仓一次,最多补仓5次 for (int i = 0; i < MaxAdditions; i++) { if (latestPrice < markPrice - Gap * (i + 1) && currentProfit < ProfitTarget) { double sellVolume = lastSellVolume * AddVolumeMultiplier; int sellTicket = OrderSend(Symbol(), OP_SELL, sellVolume, latestPrice, Slippage, 0, 0, 'Additional Sell Order', MagicNumber); if (sellTicket > 0) { return; } } } }
// 判断当前魔}
策略逻辑
- 初始阶段: EA会先挂两个反向的停止订单,分别在当前价格上方和下方一定点数(Gap)。2. 突破建仓: 当价格突破任意一个停止订单后,EA会删除另一个停止订单,并根据突破方向进行建仓。3. 加仓逻辑: 在盈利目标未达到前,EA会根据价格走势进行加仓。如果价格朝有利方向移动,EA会在每隔一定点数(Gap)进行加仓,加仓手数为上次交易手数的倍数(AddVolumeMultiplier),最多加仓次数为MaxAdditions。4. 平仓: 当盈利达到ProfitTarget时,EA会平掉所有持仓。
参数说明
- MagicNumber: EA的唯一标识符,用于区分不同的EA。* OrderVolume: 初始建仓手数。* Gap: 突破建仓和加仓的点数间隔。* AddVolumeMultiplier: 加仓手数倍数。* MaxAdditions: 最大加仓次数。* ProfitTarget: 盈利目标。* Slippage: 允许的滑点。
风险提示
- 该策略仅供参考,不构成任何投资建议。* 任何交易策略都存在风险,请根据自身情况谨慎使用。
总结
这款MQL4 EA策略结合了趋势追踪和加仓策略,可以帮助交易者在市场趋势明确时自动进行交易。但请注意,任何交易策略都存在风险,使用前请充分了解其逻辑和风险。
原文地址: https://www.cveoy.top/t/topic/ccMK 著作权归作者所有。请勿转载和采集!