希望祠.同舟.量化.侦云取势势能研究中心

 找回密码
 立即注册

《周易.系辞》

君子藏器于身,待时而动!

《吕氏.春秋》

君子谋时而动,顺势而为!

《晏子·霸业因时而生》

识时务者为俊杰,通机变者为英豪!

《周易.系辞》

天之所助,吉无不利,天之所助者.顺天者也!

《史记.太史公自序》
天之势,浩浩汤汤,顺之者昌,逆之者亡!

《寒窑赋》

天不得时,日月无光.地 不得时,草木不长.

《周易.系辞》

刚柔者,立本者也!变通者,识时者也!

圣人云:

君子务本,本立而道生!

 《势胜学》

不知势,无以为人也.势易而未觉,必败焉!

《周易·系辞上传》:

富有之谓大业,日新之谓盛德!

《礼记.大学》:
格物致知,正心诚意,修身齐家!

《礼记.中庸》:

凡事预则立,不预则废!

查看: 4191|回复: 1

[【优秀推荐】曲线完美收益中等] 趋势网格加仓源码

[复制链接]

1731

主题

1986

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
12285

最佳新人活跃会员热心会员推广达人宣传达人荣誉版主勋章理事

QQ
侦云取势 发表于 2025-11-30 20:28:31 | 显示全部楼层 |阅读模式
这是一个mt4的指标,帮我用中文写一个ea,
多单开单:当指标出现LimeGreen颜色时,开始开多单。然后每隔200点加仓开多单一次,做多加仓300次。

空单开单:当指标出现Red颜色时,开单开空单。然后每隔200点,加仓开空单。

出场:单单独立止损,亏损5000点清仓, 盈利9000点清仓。


盈利保护:黄金的点差是160点。当盈利后的单,不能亏回去。

利润回撤30%时清仓


观天之道,执天之行。
行胜于言,取时于天。

成功=艰苦劳动+正确方法+少说空话 --爱因斯坦
回复

使用道具 举报

1731

主题

1986

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
12285

最佳新人活跃会员热心会员推广达人宣传达人荣誉版主勋章理事

QQ
 楼主| 侦云取势 发表于 2025-11-30 20:28:52 | 显示全部楼层
//+------------------------------------------------------------------+
//|                                           TrendDSEMA_EA_v3.0.mq4 |
//|                                  Copyright 2023, Automated Logic |
//|                                              For User Request    |
//+------------------------------------------------------------------+
#property copyright "Custom EA based on TrendDSEMA - Pyramiding"
#property link      ""
#property version   "3.00"
#property strict

//--- 输入参数
input string   _Comment1       = "=== 交易设置 ===";
input double   InpLots         = 0.01;        // 首单及加仓手数
input int      InpMagic        = 88888;       // 魔术棒号
input int      InpSlippage     = 5;           // 滑点

input string   _Comment2       = "=== 顺势加仓设置(盈利加仓) ===";
input int      InpGridStep     = 200;         // 加仓间隔 (点数)
input int      InpMaxOrders    = 300;         // 最大加仓次数 (做多/做空各300次)

input string   _Comment3       = "=== 止盈止损设置 ===";
input int      InpStopLoss     = 5000;        // 单单独立止损 (点数)
input int      InpTakeProfit   = 9000;        // 单单独立止盈 (点数)

input string   _Comment4       = "=== 盈利保护(保本)设置 ===";
input int      InpBreakEven    = 160;         // 黄金点差保护 (点数),大于此盈利后触发保本
input int      InpBE_Add       = 10;          // 保本时额外加的点数

input string   _Comment5       = "=== 单单独立利润回撤设置 ===";
input bool     InpUsePointRetrace = true;     // 是否启用点数回撤平仓
input int      InpRetraceStart    = 200;      // 启动监控的最小盈利点数 (建议>点差)
input double   InpRetracePct      = 30.0;     // 利润回撤百分比 (30%)

input string   _Comment6       = "=== 指标参数 (需与指标一致) ===";
input string   InpIndiName     = "TrendDSEMA"; // 指标文件名 (必须准确)
input int      InpTrendPeriod  = 20;          // Trend period
input double   InpSmooth       = 3;           // Smoothing period
input double   InpTriggerUp    = 0.05;        // Trigger up level
input double   InpTriggerDn    = -0.05;       // Trigger down level

//--- 结构体:用于记录每张单子的历史最高盈利点数
struct OrderMonitor {
   int ticket;
   double maxPoints;
};
OrderMonitor g_monitors[]; // 动态数组存储监控信息

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   ArrayResize(g_monitors, 0);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. 获取指标信号 (取1号柱)
   double signal = iCustom(NULL, 0, InpIndiName, InpTrendPeriod, InpSmooth, InpTriggerUp, InpTriggerDn, 5, 1);

   // 2. 统计持仓 (获取最后一单的价格)
   int buyCount = 0;
   int sellCount = 0;
   double lastBuyPrice = 0;
   double lastSellPrice = 0;
   
   CountOrders(buyCount, sellCount, lastBuyPrice, lastSellPrice);

   // 3. 多单逻辑 (LimeGreen)
   if (signal == 1.0)
   {
      // 首单
      if (buyCount == 0)
      {
         OpenOrder(OP_BUY);
      }
      // 顺势加仓:当前价格比上一单高出 GridStep 点
      else if (buyCount < InpMaxOrders)
      {
         // 修改为:(当前买价 - 上次买入价) >= 间隔
         if (Ask - lastBuyPrice >= InpGridStep * Point)
         {
            OpenOrder(OP_BUY);
         }
      }
   }

   // 4. 空单逻辑 (Red)
   if (signal == -1.0)
   {
      // 首单
      if (sellCount == 0)
      {
         OpenOrder(OP_SELL);
      }
      // 顺势加仓:当前价格比上一单低出 GridStep 点
      else if (sellCount < InpMaxOrders)
      {
         // 修改为:(上次卖出价 - 当前卖价) >= 间隔
         if (lastSellPrice - Bid >= InpGridStep * Point)
         {
            OpenOrder(OP_SELL);
         }
      }
   }

   // 5. 盈利保护 (保本)
   ManageBreakEven();

   // 6. 单单独立利润回撤清仓
   if (InpUsePointRetrace)
   {
      ManageIndividualRetracement();
   }
}

//+------------------------------------------------------------------+
//| 开仓函数                                                         |
//+------------------------------------------------------------------+
void OpenOrder(int type)
{
   double sl = 0, tp = 0;
   double price = (type == OP_BUY) ? Ask : Bid;
   
   if (InpStopLoss > 0)
      sl = (type == OP_BUY) ? NormalizeDouble(price - InpStopLoss * Point, Digits) : NormalizeDouble(price + InpStopLoss * Point, Digits);
      
   if (InpTakeProfit > 0)
      tp = (type == OP_BUY) ? NormalizeDouble(price + InpTakeProfit * Point, Digits) : NormalizeDouble(price - InpTakeProfit * Point, Digits);

   int ticket = OrderSend(Symbol(), type, InpLots, price, InpSlippage, sl, tp, "TrendDSEMA EA", InpMagic, 0, (type == OP_BUY ? clrGreen : clrRed));
   
   if (ticket < 0) Print("开单失败: ", GetLastError());
}

//+------------------------------------------------------------------+
//| 统计订单 (寻找最新一单的开仓价)                                  |
//+------------------------------------------------------------------+
void CountOrders(int &bCount, int &sCount, double &lBuyPrice, double &lSellPrice)
{
   bCount = 0; sCount = 0; lBuyPrice = 0; lSellPrice = 0;
   datetime lastBuyTime = 0;
   datetime lastSellTime = 0;

   for (int i = 0; i < OrdersTotal(); i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic)
         {
            if (OrderType() == OP_BUY)
            {
               bCount++;
               // 寻找开仓时间最晚的那一单
               if (OrderOpenTime() > lastBuyTime) {
                  lastBuyTime = OrderOpenTime();
                  lBuyPrice = OrderOpenPrice();
               }
            }
            if (OrderType() == OP_SELL)
            {
               sCount++;
               // 寻找开仓时间最晚的那一单
               if (OrderOpenTime() > lastSellTime) {
                  lastSellTime = OrderOpenTime();
                  lSellPrice = OrderOpenPrice();
               }
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| 保本逻辑                                                         |
//+------------------------------------------------------------------+
void ManageBreakEven()
{
   for (int i = 0; i < OrdersTotal(); i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic)
         {
            double openPrice = OrderOpenPrice();
            if (OrderType() == OP_BUY)
            {
               if (Bid - openPrice > InpBreakEven * Point)
               {
                  double newSL = NormalizeDouble(openPrice + InpBE_Add * Point, Digits);
                  if (OrderStopLoss() < newSL || OrderStopLoss() == 0)
                     OrderModify(OrderTicket(), openPrice, newSL, OrderTakeProfit(), 0, clrBlue);
               }
            }
            if (OrderType() == OP_SELL)
            {
               if (openPrice - Ask > InpBreakEven * Point)
               {
                  double newSL = NormalizeDouble(openPrice - InpBE_Add * Point, Digits);
                  if (OrderStopLoss() > newSL || OrderStopLoss() == 0)
                     OrderModify(OrderTicket(), openPrice, newSL, OrderTakeProfit(), 0, clrBlue);
               }
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| 单单独立利润回撤清仓 (基于点数)                                  |
//+------------------------------------------------------------------+
void ManageIndividualRetracement()
{
   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic)
         {
            int ticket = OrderTicket();
            double currentPoints = 0;

            // 1. 计算当前单子的盈利点数
            if (OrderType() == OP_BUY)
               currentPoints = (Bid - OrderOpenPrice()) / Point;
            else if (OrderType() == OP_SELL)
               currentPoints = (OrderOpenPrice() - Ask) / Point;
            else
               continue;

            // 2. 在数组中查找或注册该订单
            int index = -1;
            for (int k = 0; k < ArraySize(g_monitors); k++)
            {
               if (g_monitors[k].ticket == ticket)
               {
                  index = k;
                  break;
               }
            }

            // 如果是新订单,加入数组
            if (index == -1)
            {
               int s = ArraySize(g_monitors);
               ArrayResize(g_monitors, s + 1);
               g_monitors[s].ticket = ticket;
               g_monitors[s].maxPoints = currentPoints; // 初始最高点
               index = s;
            }

            // 3. 更新最高盈利点数
            if (currentPoints > g_monitors[index].maxPoints)
            {
               g_monitors[index].maxPoints = currentPoints;
            }

            // 4. 判断回撤平仓条件
            // 必须先满足最低启动点数(InpRetraceStart),防止刚开单震荡就被平
            if (g_monitors[index].maxPoints >= InpRetraceStart)
            {
               double limitPoints = g_monitors[index].maxPoints * (1.0 - InpRetracePct / 100.0);
               
               if (currentPoints < limitPoints)
               {
                  Print("触发单单独立回撤平仓! 订单号:", ticket, " 最高点数:", g_monitors[index].maxPoints, " 当前点数:", currentPoints, " 阈值:", limitPoints);
                  
                  bool res = false;
                  if (OrderType() == OP_BUY)
                     res = OrderClose(ticket, OrderLots(), Bid, InpSlippage, clrYellow);
                  else
                     res = OrderClose(ticket, OrderLots(), Ask, InpSlippage, clrYellow);
                     
                  if (!res) Print("回撤平仓失败: ", GetLastError());
               }
            }
         }
      }
   }
   
   CleanUpMonitorArray();
}

//+------------------------------------------------------------------+
//| 清理监控数组                                                     |
//+------------------------------------------------------------------+
void CleanUpMonitorArray()
{
   for (int i = ArraySize(g_monitors) - 1; i >= 0; i--)
   {
      if (!OrderSelect(g_monitors[i].ticket, SELECT_BY_TICKET) || OrderCloseTime() > 0)
      {
         RemoveFromArray(i);
      }
   }
}

//+------------------------------------------------------------------+
//| 辅助函数:移除数组元素                                           |
//+------------------------------------------------------------------+
void RemoveFromArray(int index)
{
   int size = ArraySize(g_monitors);
   if (index < size - 1)
   {
      g_monitors[index] = g_monitors[size - 1];
   }
   ArrayResize(g_monitors, size - 1);
}
//+------------------------------------------------------------------+
观天之道,执天之行。
行胜于言,取时于天。

成功=艰苦劳动+正确方法+少说空话 --爱因斯坦
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /5 下一条

人生者,生存也。
生存所需,财(钱)官(权)也。
财自食伤(子孙福德爻)生,
印星生身荫护,官财印全,适合人间生存也。
若命缺财,缺官,则失去生存权。
一旦脱离父母养育,将天天面临,
从绝望中醒来,又从绝望中睡去。来去如烟!

Archiver|小黑屋|希望祠.同舟.量化

GMT+8, 2026-1-1 21:08 , Processed in 0.020941 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表