设为首页 收藏本站 切换语言 切换语言
xinsanban186
B
 楼主 | 发表于 2025-9-15 20:54:46 来自手机 | 显示全部楼层
yb_fox 发表于 2025-9-15 19:37
跑了一天,就是有点改动
第一,左搜索的K线形态见上图
第二,加个移动止损 ...

那算什么形态,你形容一下
举报

点赞 评论 使用道具

Y1709833
DD
| 发表于 2025-9-16 03:11:03 | 显示全部楼层
你好楼主能不能把这个转换成EA 一下  谢谢+------------------------------------------------------------------+
//|                                                   ChanlunPro.mq4 |
//|                        Copyright 2024, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "2.00"
#property strict
#property indicator_chart_window

// 输入参数
input int    MaxBars       = 2000;      // 最大分析柱数
input int    SegmentBars   = 5;         // 波段最小K线数
input double MinHeight     = 0.0003;    // 中枢最小高度(点)
input double OverlapRatio  = 0.5;       // 波段重叠比例(0-1)
input int    FractalBars   = 2;         // 分型验证K线数
input color  ZS1Color      = clrGray;   // 一级中枢颜色
input color  ZS2Color      = C'100,100,255'; // 二级中枢颜色
input color  Buy1Color     = clrLime;   // 一买颜色
input color  Buy2Color     = clrDodgerBlue; // 二买颜色
input color  Buy3Color     = clrCyan;   // 三买颜色
input color  Sell1Color    = clrRed;    // 一卖颜色
input color  Sell2Color    = C'255,100,0'; // 二卖颜色
input color  Sell3Color    = clrMagenta;// 三卖颜色
input int    ArrowSize     = 2;         // 箭头尺寸
input bool   ShowLabels    = true;      // 显示中枢标签

// 全局变量
struct ZhongShu { double high,low; datetime start,end; int level; };
ZhongShu zsArray[];                     // 中枢存储数组
int lastProcessedBar = 0;               // 最后处理K线索引

//+------------------------------------------------------------------+
//| 初始化指标                                                       |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(0);
   ArrayResize(zsArray, 100);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 主计算函数                                                       |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   // 设置系列数组
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(time, true);
   
   // 确定计算范围
   int startBar = (prev_calculated == 0) ?
        MathMin(rates_total-1, MaxBars-1) :
        MathMin(rates_total - prev_calculated + 5, rates_total-1);
        
   // 删除新K线范围内的旧对象
   DeleteObjectsInRange(time[startBar]);
   
   // 识别中枢和买卖点
   for(int i = startBar; i >= SegmentBars*3+1; i--)
   {
      ZhongShu newZS;
      if(FindZhongshu(i, high, low, time, newZS))
      {
         // 检查是否新中枢
         bool isNew = true;
         for(int j = 0; j < ArraySize(zsArray); j++)
         {
            if(zsArray[j].start == newZS.start &&
               zsArray[j].end == newZS.end)
            {
               isNew = false;
               break;
            }
         }
         
         if(isNew)
         {
            // 保存中枢并绘制
            SaveAndDrawZS(newZS, time);
         }
      }
      
      // 识别买卖点
      IdentifyPoints(i, high, low, close, time);
   }
   
   lastProcessedBar = rates_total - 1;
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 删除指定时间后的对象                                             |
//+------------------------------------------------------------------+
void DeleteObjectsInRange(datetime afterTime)
{
   for(int i = ObjectsTotal()-1; i >= 0; i--)
   {
      string name = ObjectName(i);
      datetime objTime = (datetime)ObjectGetInteger(0, name, OBJPROP_TIME);
      
      if(StringFind(name, "ZS_") == 0 ||
         StringFind(name, "B") == 0 ||
         StringFind(name, "S") == 0)
      {
         if(objTime >= afterTime) ObjectDelete(name);
      }
   }
}

//+------------------------------------------------------------------+
//| 识别中枢(增强版)                                               |
//+------------------------------------------------------------------+
bool FindZhongshu(int startIdx, const double &high[], const double &low[],
                 const datetime &time[], ZhongShu &outZS)
{
   // 查找三个波段
   int peaks[6];
   peaks[0] = FindPeak(startIdx, MODE_HIGH, SegmentBars, high, low); // 第一段高点
   peaks[1] = FindPeak(peaks[0], MODE_LOW, SegmentBars, high, low);  // 第一段低点
   peaks[2] = FindPeak(peaks[1], MODE_HIGH, SegmentBars, high, low); // 第二段高点
   peaks[3] = FindPeak(peaks[2], MODE_LOW, SegmentBars, high, low);  // 第二段低点
   peaks[4] = FindPeak(peaks[3], MODE_HIGH, SegmentBars, high, low); // 第三段高点
   peaks[5] = FindPeak(peaks[4], MODE_LOW, SegmentBars, high, low);  // 第三段低点

   // 验证所有极点有效
   for(int i = 0; i < 6; i++)
      if(peaks[i] < 0) return false;
   
   // 计算波段区间
   double segHigh[3], segLow[3];
   segHigh[0] = HighMax(peaks[0], peaks[1], high);
   segLow[0]  = LowMin(peaks[0], peaks[1], low);
   segHigh[1] = HighMax(peaks[2], peaks[3], high);
   segLow[1]  = LowMin(peaks[2], peaks[3], low);
   segHigh[2] = HighMax(peaks[4], peaks[5], high);
   segLow[2]  = LowMin(peaks[4], peaks[5], low);
   
   // 计算中枢区间
   double zsHigh = MathMin(segHigh[0], MathMin(segHigh[1], segHigh[2]));
   double zsLow  = MathMax(segLow[0], MathMax(segLow[1], segLow[2]));
   
   // 验证中枢有效性
   if(zsHigh <= zsLow) return false;
   if((zsHigh - zsLow) < MinHeight * Point) return false;
   
   // 验证重叠比例
   double overlap1 = (MathMin(segHigh[0], segHigh[1]) - MathMax(segLow[0], segLow[1]));
   double overlap2 = (MathMin(segHigh[1], segHigh[2]) - MathMax(segLow[1], segLow[2]));
   double minRange = MathMin(zsHigh - zsLow, MathMin(segHigh[0]-segLow[0], segHigh[1]-segLow[1]));
   
   if(overlap1/minRange < OverlapRatio || overlap2/minRange < OverlapRatio)
      return false;
   
   // 确定中枢级别(基于持续时间)
   int duration = (int)((time[peaks[0]] - time[peaks[5]]) / PeriodSeconds());
   outZS.level = (duration > SegmentBars*20) ? 2 : 1;
   outZS.high = zsHigh;
   outZS.low = zsLow;
   outZS.start = time[peaks[5]];
   outZS.end = time[peaks[0]];
   
   return true;
}

//+------------------------------------------------------------------+
//| 保存并绘制中枢                                                   |
//+------------------------------------------------------------------+
void SaveAndDrawZS(ZhongShu &zs, const datetime &time[])
{
   // 保存到数组
   int size = ArraySize(zsArray);
   for(int i = 0; i < size; i++)
   {
      if(zsArray[i].start == 0)
      {
         zsArray[i] = zs;
         break;
      }
   }
   
   // 绘制中枢
   string zsName = "ZS_" + IntegerToString(zs.start) + "_" + IntegerToString(zs.end);
   color zsColor = (zs.level == 1) ? ZS1Color : ZS2Color;
   
   ObjectCreate(0, zsName, OBJ_RECTANGLE, 0, zs.start, zs.low, zs.end, zs.high);
   ObjectSetInteger(0, zsName, OBJPROP_COLOR, zsColor);
   ObjectSetInteger(0, zsName, OBJPROP_BACK, true);
   ObjectSetInteger(0, zsName, OBJPROP_WIDTH, 1);
   ObjectSetInteger(0, zsName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSetInteger(0, zsName, OBJPROP_FILL, true);
   ObjectSetInteger(0, zsName, OBJPROP_SELECTABLE, false);
   
   // 添加中枢标签
   if(ShowLabels)
   {
      string labelName = "LBL_" + zsName;
      string text = StringFormat("ZS#%d\n%.5f-%.5f", zs.level, zs.low, zs.high);
      datetime labelTime = zs.start + (zs.end - zs.start)/2;
      double labelPrice = (zs.low + zs.high)/2;
      
      ObjectCreate(0, labelName, OBJ_TEXT, 0, labelTime, labelPrice);
      ObjectSetString(0, labelName, OBJPROP_TEXT, text);
      ObjectSetInteger(0, labelName, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 8);
      ObjectSetInteger(0, labelName, OBJPROP_BACK, true);
   }
}

//+------------------------------------------------------------------+
//| 识别全系列买卖点                                                 |
//+------------------------------------------------------------------+
void IdentifyPoints(int idx, const double &high[], const double &low[],
                   const double &close[], const datetime &time[])
{
   // 查找有效中枢
   for(int i = 0; i < ArraySize(zsArray); i++)
   {
      if(zsArray[i].start == 0) continue;
      
      double zsHigh = zsArray[i].high;
      double zsLow = zsArray[i].low;
      datetime zsEnd = zsArray[i].end;
      
      // 忽略未完成中枢
      if(time[idx] < zsEnd) continue;
      
      // 1. 一买点:中枢下方底分型
      if(close[idx] < zsLow && IsBottomFractal(idx, low, FractalBars))
      {
         string name = "B1_" + IntegerToString(idx);
         CreateArrow(name, time[idx], low[idx]-10*Point, Buy1Color, SYMBOL_ARROWUP);
      }
      
      // 2. 一卖点:中枢上方顶分型
      if(close[idx] > zsHigh && IsTopFractal(idx, high, FractalBars))
      {
         string name = "S1_" + IntegerToString(idx);
         CreateArrow(name, time[idx], high[idx]+10*Point, Sell1Color, SYMBOL_ARROWDOWN);
      }
      
      // 3. 二买点:回调不破前低
      if(close[idx] > zsLow && close[idx] < zsHigh &&
         IsBottomFractal(idx, low, FractalBars) &&
         IsHigherLow(idx, 10, low)) // 10周期内低点抬高
      {
         string name = "B2_" + IntegerToString(idx);
         CreateArrow(name, time[idx], low[idx]-10*Point, Buy2Color, SYMBOL_ARROWUP);
      }
      
      // 4. 二卖点:反弹不破前高
      if(close[idx] < zsHigh && close[idx] > zsLow &&
         IsTopFractal(idx, high, FractalBars) &&
         IsLowerHigh(idx, 10, high)) // 10周期内高点降低
      {
         string name = "S2_" + IntegerToString(idx);
         CreateArrow(name, time[idx], high[idx]+10*Point, Sell2Color, SYMBOL_ARROWDOWN);
      }
      
      // 5. 三买点:突破后回踩不破中枢
      if(close[idx] > zsHigh &&
         IsPullbackToZS(idx, 10, zsHigh, low) && // 回踩中枢上方
         IsBottomFractal(idx, low, FractalBars))
      {
         string name = "B3_" + IntegerToString(idx);
         CreateArrow(name, time[idx], low[idx]-10*Point, Buy3Color, SYMBOL_ARROWUP);
      }
      
      // 6. 三卖点:跌破后回抽不破中枢
      if(close[idx] < zsLow &&
         IsPullbackToZS(idx, 10, zsLow, high) && // 回抽中枢下方
         IsTopFractal(idx, high, FractalBars))
      {
         string name = "S3_" + IntegerToString(idx);
         CreateArrow(name, time[idx], high[idx]+10*Point, Sell3Color, SYMBOL_ARROWDOWN);
      }
   }
}

//+------------------------------------------------------------------+
//| 创建箭头对象                                                     |
//+------------------------------------------------------------------+
void CreateArrow(string name, datetime time, double price, color clr, int code)
{
   ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, ArrowSize);
   ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}

//+------------------------------------------------------------------+
//| 辅助函数: 查找波段极点                                           |
//+------------------------------------------------------------------+
int FindPeak(int startIdx, int mode, int minBars, const double &high[], const double &low[])
{
   int peakIdx = startIdx;
   int endIdx = MathMax(startIdx - minBars, 0);
   
   for(int i = startIdx; i >= endIdx; i--)
   {
      if(mode == MODE_HIGH)
      {
         if(high[i] > high[peakIdx]) peakIdx = i;
      }
      else
      {
         if(low[i] < low[peakIdx]) peakIdx = i;
      }
   }
   return peakIdx;
}

//+------------------------------------------------------------------+
//| 辅助函数: 计算区间最高价                                         |
//+------------------------------------------------------------------+
double HighMax(int start, int end, const double &high[])
{
   double val = high[start];
   int step = (start < end) ? 1 : -1;
   for(int i = start; i != end; i += step)
      if(high[i] > val) val = high[i];
   return val;
}

//+------------------------------------------------------------------+
//| 辅助函数: 计算区间最低价                                         |
//+------------------------------------------------------------------+
double LowMin(int start, int end, const double &low[])
{
   double val = low[start];
   int step = (start < end) ? 1 : -1;
   for(int i = start; i != end; i += step)
      if(low[i] < val) val = low[i];
   return val;
}

//+------------------------------------------------------------------+
//| 判断底分型(增强版)                                             |
//+------------------------------------------------------------------+
bool IsBottomFractal(int idx, const double &low[], int verifyBars)
{
   // 中心点必须是低点
   if(low[idx] > low[idx-1] || low[idx] > low[idx+1])
      return false;
   
   // 左侧验证
   for(int i = 1; i <= verifyBars; i++)
   {
      if(low[idx-i] < low[idx] || low[idx+i] < low[idx])
         return false;
   }
   return true;
}

//+------------------------------------------------------------------+
//| 判断顶分型(增强版)                                             |
//+------------------------------------------------------------------+
bool IsTopFractal(int idx, const double &high[], int verifyBars)
{
   // 中心点必须是高点
   if(high[idx] < high[idx-1] || high[idx] < high[idx+1])
      return false;
   
   // 左侧验证
   for(int i = 1; i <= verifyBars; i++)
   {
      if(high[idx-i] > high[idx] || high[idx+i] > high[idx])
         return false;
   }
   return true;
}

//+------------------------------------------------------------------+
//| 判断低点是否抬高                                                 |
//+------------------------------------------------------------------+
bool IsHigherLow(int idx, int period, const double &low[])
{
   double currentLow = low[idx];
   for(int i = 1; i <= period; i++)
   {
      if(low[idx+i] < currentLow) return false;
      if(low[idx-i] < currentLow) return false;
   }
   return true;
}

//+------------------------------------------------------------------+
//| 判断高点是否降低                                                 |
//+------------------------------------------------------------------+
bool IsLowerHigh(int idx, int period, const double &high[])
{
   double currentHigh = high[idx];
   for(int i = 1; i <= period; i++)
   {
      if(high[idx+i] > currentHigh) return false;
      if(high[idx-i] > currentHigh) return false;
   }
   return true;
}

//+------------------------------------------------------------------+
//| 判断回踩中枢支撑                                                 |
//+------------------------------------------------------------------+
bool IsPullbackToZS(int idx, int period, double zsLevel, const double &price[])
{
   for(int i = 0; i < period; i++)
   {
      if(price[idx-i] <= zsLevel) return true;
   }
   return false;
}
//+------------------------------------------------------------------+
举报

点赞 评论 使用道具

Y1709833
DD
| 发表于 2025-9-16 03:49:49 | 显示全部楼层
帮忙转换一下
filetype

缠论指标源码.rar

3.69 KB, 下载次数: 1, 下载积分: 活跃度 -5  [下载]

帮忙转换一下

举报

点赞 评论 使用道具

Y1709833
DD
| 发表于 2025-9-16 03:51:24 | 显示全部楼层

   不会弄EA     谢谢
举报

点赞 评论 使用道具

德鲁TWT
D
| 发表于 2025-9-16 08:48:25 | 显示全部楼层
哇塞,大佬人太好了
举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-16 09:18:01 | 显示全部楼层
wechat_2025-09-16_091523_511.png 这个指标加载出来特别乱,你试试吧。
filetype

缠论指标源码.ex4

36.84 KB, 下载次数: 0, 下载积分: 活跃度 -5  [下载]

filetype

缠论指标源码.mq4

29.96 KB, 下载次数: 2, 下载积分: 活跃度 -5  [下载]

filetype

缠论指标源码.txt

15.47 KB, 下载次数: 0, 下载积分: 活跃度 -5  [下载]

举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-16 09:19:35 | 显示全部楼层

你好,86楼自行下载。
把txt的文档转换了一个.mq4,一个.ex4文件,.mq4的就是源码。
不过在MT4里面加载的时候特别乱,你可以看看图片或者自己试试。
举报

点赞 1 评论 使用道具

yb_fox
D
| 发表于 2025-9-16 11:17:42 | 显示全部楼层
xinsanban186 发表于 2025-9-15 20:54
那算什么形态,你形容一下

阴K,开盘价大于均线,收盘价小于均线,均线与K交叉
阳K,开盘价小于均线,收盘价大于均线,均线与K交叉
举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-16 12:28:25 | 显示全部楼层
yb_fox 发表于 2025-9-16 11:17
阴K,开盘价大于均线,收盘价小于均线,均线与K交叉
阳K,开盘价小于均线,收盘价大于均线,均线与K交叉 ...

有点乱了,最近写的有点多。
你重新整理一下整体思路吧,不要用你自己做单的思维,用程序能懂的思维,比如搜索,只能向左搜索,不能向右搜索。
举报

点赞 评论 使用道具

yb_fox
D
| 发表于 2025-9-16 14:47:06 | 显示全部楼层
xinsanban186 发表于 2025-9-16 12:28
有点乱了,最近写的有点多。
你重新整理一下整体思路吧,不要用你自己做单的思维,用程序能懂的思维,比 ...

买多:
打开EA当前阳K。向左搜索阴K(阴K满足开盘价大于均线,收盘价小于均线,并且均线与阴K交叉形态)
阳K收盘价大于此阴K最高价。MACD大于0轴线。
卖空:
打开EA当前阴K。向左搜索阳K(阳K满足开盘价小于均线,收盘价大于均线,并且均线与阳K交叉形态)
阴K收盘价小于阳K最低价。MACD小于0轴线。
止盈,止损,平保、移损。
举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-17 10:37:49 | 显示全部楼层
修改后逻辑:
“多单建仓:
打开EA当前为阳线。向左搜索N根K线,找到一条K线满足阴线,开盘价大于均线,收盘价小于均线,并且均线与K线交叉形态,记录该条K线的最高价最低价,当前阳线收盘价大于记录的这根K线的最高价,并且MACD大于0轴线,多单进场“。
“空单建仓:
打开EA当前为阴线。向左搜索N根K线,找到一条K线满足阳线,开盘价小于均线,收盘价大于均线,并且均线与K线交叉形态,记录该条K线的最高价最低价,当前阴线收盘价小于阳K最低价。MACD小于0轴线,空单进场”
filetype

破均线 高低点 MACD-2.0.ex4

14.04 KB, 下载次数: 5, 下载积分: 活跃度 -5  [下载]

filetype

破均线 高低点 MACD-2.0.mq4

15.07 KB, 下载次数: 10, 下载积分: 活跃度 -5  [下载]

举报

点赞 1 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-17 10:38:15 | 显示全部楼层
yb_fox 发表于 2025-9-16 14:47
买多:
打开EA当前阳K。向左搜索阴K(阴K满足开盘价大于均线,收盘价小于均线,并且均线与阴K交叉形态)
...

你好,91楼自行下载测试。
举报

点赞 评论 使用道具

yb_fox
D
| 发表于 2025-9-17 18:38:55 | 显示全部楼层
xinsanban186 发表于 2025-9-17 10:38
你好,91楼自行下载测试。

入场没问题,怎么加代码。同方向只做一单,现在一个K线一单,最后一单把前面利润又亏回去了
举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-17 21:14:39 来自手机 | 显示全部楼层
yb_fox 发表于 2025-9-17 18:38
入场没问题,怎么加代码。同方向只做一单,现在一个K线一单,最后一单把前面利润又亏回去了 ...

加个限制参数,同向单最大持仓单数
举报

点赞 评论 使用道具

Y1709833
DD
| 发表于 2025-9-17 23:39:48 | 显示全部楼层
xinsanban186 发表于 2025-9-16 09:19
你好,86楼自行下载。
把txt的文档转换了一个.mq4,一个.ex4文件,.mq4的就是源码。
不过在MT4里面加载的 ...

好的  谢谢
举报

点赞 评论 使用道具

dy008524
D
| 发表于 2025-9-20 12:12:05 | 显示全部楼层
NiuXdeID 发表于 2025-9-9 13:30
楼主效率很高啊,我找个时间测试看看,有什么想法再和你联系,谢谢

只要不是一美金震荡这个还是行得通的,利润也可以
举报

点赞 评论 使用道具

NiuXdeID
DDD
| 发表于 2025-9-21 14:14:24 | 显示全部楼层
dy008524 发表于 2025-9-20 12:12
只要不是一美金震荡这个还是行得通的,利润也可以

怕震荡,震荡久了还是会爆仓,个人感觉收益比不上马丁,风险一点也不比马丁小,我已放弃
举报

点赞 评论 使用道具

zhangyang123
DDD
| 发表于 2025-9-22 14:00:24 | 显示全部楼层
xinsanban186 发表于 2025-9-2 17:43
布林带+斐波那契EA已完成,放在下面附件里了。

感谢老板!!
左上角的显示信息字有点小,这个能麻烦把字体调大一点吗?辛苦了
举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-23 16:19:35 | 显示全部楼层
显示信息放大.png
EA运行界面.png
filetype

布林带 斐波那契.ex4

37.87 KB, 下载次数: 0, 下载积分: 活跃度 -5  [下载]

filetype

布林带 斐波那契.mq4

48.76 KB, 下载次数: 10, 下载积分: 活跃度 -5  [下载]

举报

点赞 评论 使用道具

xinsanban186
B
 楼主 | 发表于 2025-9-23 16:20:18 | 显示全部楼层
zhangyang123 发表于 2025-9-22 14:00
感谢老板!!
左上角的显示信息字有点小,这个能麻烦把字体调大一点吗?辛苦了 ...

你好,99楼自行下载,显示信息放大了1倍,足够清晰。
举报

点赞 评论 使用道具

EA交易
您需要登录后才可以评论 登录 | 立即注册

 简体中文国旗 简体中文
 繁體中文国旗 繁體中文
 English国旗 English(英语)
 日本語国旗 日本語(日语)
 Deutsch国旗 Deutsch(德语)
 Русский язык国旗 Русский язык(俄语)
 بالعربية国旗 بالعربية(阿拉伯语)
 Türkçe国旗 Türkçe(土耳其语)
 Português国旗 Português(葡萄牙语)
 ภาษาไทย国旗 ภาษาไทย(泰国语)
 한어国旗 한어(朝鲜语/韩语)
 Français国旗 Français(法语)
翻译