设为首页 收藏本站 切换语言 切换语言

自己写了一个K线形态指标,有几十种形态,一张完整的图你就能找到属于自己的交易系统,想要的私聊我,另外有EA要写的可找我 ...

| 发表于 2025-10-3 20:24:27 | 显示全部楼层 |复制链接
自己写了一个K线形态指标,有几十种形态,一张完整的图你就能找到属于自己的交易系统,想要的私聊我,另外有EA要写的可找我
wechat_2025-10-03_180919_348.png
举报

评论 使用道具

精彩评论2

fx8
CC
| 发表于 2025-11-30 19:35:34 | 显示全部楼层
发上来就好,还要私聊不麻烦啊
举报

点赞 评论 使用道具

fx8
CC
| 发表于 2025-11-30 19:39:23 | 显示全部楼层
//+------------------------------------------------------------------+
//|                                                    KLinePatterns.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots   8

//--- 输入参数
input bool ShowPinBar = true;           // 显示Pin Bar
input bool ShowEngulfing = true;        // 显示吞没形态
input bool ShowHammer = true;           // 显示锤子线
input bool ShowShootingStar = true;     // 显示射击之星
input bool ShowThreeSoldiers = true;    // 显示红三兵
input bool ShowThreeCrows = true;       // 显示三只乌鸦
input bool ShowDoji = true;             // 显示十字星
input bool ShowHarami = true;           // 显示孕线
input int  MinBodySizePoints = 30;      // 最小实体大小(点)
input int  LookbackBars = 100;          // 检查的K线数量

//--- 缓冲区
double PinBarBuffer[];
double EngulfingBuffer[];
double HammerBuffer[];
double ShootingStarBuffer[];
double ThreeSoldiersBuffer[];
double ThreeCrowsBuffer[];
double DojiBuffer[];
double HaramiBuffer[];

//+------------------------------------------------------------------+
//| 自定义初始化函数                                                 |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- 设置指标缓冲区
   SetIndexBuffer(0, PinBarBuffer);
   SetIndexBuffer(1, EngulfingBuffer);
   SetIndexBuffer(2, HammerBuffer);
   SetIndexBuffer(3, ShootingStarBuffer);
   SetIndexBuffer(4, ThreeSoldiersBuffer);
   SetIndexBuffer(5, ThreeCrowsBuffer);
   SetIndexBuffer(6, DojiBuffer);
   SetIndexBuffer(7, HaramiBuffer);
   
   //--- 设置指标线属性
   SetIndexStyle(0, DRAW_ARROW, EMPTY, 2, clrYellow);
   SetIndexArrow(0, 108);
   SetIndexLabel(0, "Pin Bar");
   
   SetIndexStyle(1, DRAW_ARROW, EMPTY, 2, clrBlue);
   SetIndexArrow(1, 110);
   SetIndexLabel(1, "Engulfing");
   
   SetIndexStyle(2, DRAW_ARROW, EMPTY, 2, clrGreen);
   SetIndexArrow(2, 115);
   SetIndexLabel(2, "Hammer");
   
   SetIndexStyle(3, DRAW_ARROW, EMPTY, 2, clrRed);
   SetIndexArrow(3, 116);
   SetIndexLabel(3, "Shooting Star");
   
   SetIndexStyle(4, DRAW_ARROW, EMPTY, 2, clrLime);
   SetIndexArrow(4, 118);
   SetIndexLabel(4, "Three Soldiers");
   
   SetIndexStyle(5, DRAW_ARROW, EMPTY, 2, clrMaroon);
   SetIndexArrow(5, 119);
   SetIndexLabel(5, "Three Crows");
   
   SetIndexStyle(6, DRAW_ARROW, EMPTY, 2, clrGray);
   SetIndexArrow(6, 120);
   SetIndexLabel(6, "Doji");
   
   SetIndexStyle(7, DRAW_ARROW, EMPTY, 2, clrPurple);
   SetIndexArrow(7, 121);
   SetIndexLabel(7, "Harami");
   
   //--- 初始化缓冲区
   ArrayInitialize(PinBarBuffer, EMPTY_VALUE);
   ArrayInitialize(EngulfingBuffer, EMPTY_VALUE);
   ArrayInitialize(HammerBuffer, EMPTY_VALUE);
   ArrayInitialize(ShootingStarBuffer, EMPTY_VALUE);
   ArrayInitialize(ThreeSoldiersBuffer, EMPTY_VALUE);
   ArrayInitialize(ThreeCrowsBuffer, EMPTY_VALUE);
   ArrayInitialize(DojiBuffer, EMPTY_VALUE);
   ArrayInitialize(HaramiBuffer, EMPTY_VALUE);
   
   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[])
{
   int limit = rates_total - prev_calculated;
   if(prev_calculated > 0)
      limit++;
   
   limit = MathMin(limit, LookbackBars);
   
   for(int i = limit - 1; i >= 0; i--)
   {
      // 清除当前值
      PinBarBuffer[i] = EMPTY_VALUE;
      EngulfingBuffer[i] = EMPTY_VALUE;
      HammerBuffer[i] = EMPTY_VALUE;
      ShootingStarBuffer[i] = EMPTY_VALUE;
      ThreeSoldiersBuffer[i] = EMPTY_VALUE;
      ThreeCrowsBuffer[i] = EMPTY_VALUE;
      DojiBuffer[i] = EMPTY_VALUE;
      HaramiBuffer[i] = EMPTY_VALUE;
      
      // 检查各种形态
      if(ShowPinBar && IsPinBar(i, open, high, low, close))
         PinBarBuffer[i] = low[i] - 10 * Point;
         
      if(ShowEngulfing && IsEngulfing(i, open, high, low, close))
         EngulfingBuffer[i] = high[i] + 10 * Point;
         
      if(ShowHammer && IsHammer(i, open, high, low, close))
         HammerBuffer[i] = low[i] - 10 * Point;
         
      if(ShowShootingStar && IsShootingStar(i, open, high, low, close))
         ShootingStarBuffer[i] = high[i] + 10 * Point;
         
      if(ShowThreeSoldiers && IsThreeSoldiers(i, open, high, low, close))
         ThreeSoldiersBuffer[i] = low[i] - 15 * Point;
         
      if(ShowThreeCrows && IsThreeCrows(i, open, high, low, close))
         ThreeCrowsBuffer[i] = high[i] + 15 * Point;
         
      if(ShowDoji && IsDoji(i, open, high, low, close))
         DojiBuffer[i] = close[i];
         
      if(ShowHarami && IsHarami(i, open, high, low, close))
         HaramiBuffer[i] = high[i] + 10 * Point;
   }
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 判断是否为Pin Bar                                                |
//+------------------------------------------------------------------+
bool IsPinBar(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   double body = MathAbs(close[idx] - open[idx]);
   double upperShadow = high[idx] - MathMax(open[idx], close[idx]);
   double lowerShadow = MathMin(open[idx], close[idx]) - low[idx]);
   double totalRange = high[idx] - low[idx];
   
   if(totalRange == 0) return false;
   
   // Pin Bar特征:长影线,小实体
   double bodyRatio = body / totalRange;
   double shadowRatio = (upperShadow > lowerShadow) ? upperShadow/totalRange : lowerShadow/totalRange;
   
   return (bodyRatio < 0.3 && shadowRatio > 0.6);
}

//+------------------------------------------------------------------+
//| 判断是否为吞没形态                                               |
//+------------------------------------------------------------------+
bool IsEngulfing(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   if(idx + 1 >= ArraySize(open)) return false;
   
   double currentBody = close[idx] - open[idx];
   double prevBody = close[idx+1] - open[idx+1];
   
   // 看涨吞没:前一根阴线,当前阳线完全吞没前一根
   if(currentBody > 0 && prevBody < 0)
   {
      if(close[idx] > open[idx+1] && open[idx] < close[idx+1])
         return true;
   }
   // 看跌吞没:前一根阳线,当前阴线完全吞没前一根
   else if(currentBody < 0 && prevBody > 0)
   {
      if(open[idx] > close[idx+1] && close[idx] < open[idx+1])
         return true;
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| 判断是否为锤子线                                                 |
//+------------------------------------------------------------------+
bool IsHammer(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   double body = MathAbs(close[idx] - open[idx]);
   double upperShadow = high[idx] - MathMax(open[idx], close[idx]);
   double lowerShadow = MathMin(open[idx], close[idx]) - low[idx]);
   double totalRange = high[idx] - low[idx];
   
   if(totalRange == 0) return false;
   
   // 锤子线特征:长下影线,短上影线,小实体
   bool isSmallBody = (body / totalRange) < 0.3;
   bool isLongLowerShadow = (lowerShadow / totalRange) > 0.6;
   bool isShortUpperShadow = (upperShadow / totalRange) < 0.1;
   
   return (isSmallBody && isLongLowerShadow && isShortUpperShadow);
}

//+------------------------------------------------------------------+
//| 判断是否为射击之星                                               |
//+------------------------------------------------------------------+
bool IsShootingStar(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   double body = MathAbs(close[idx] - open[idx]);
   double upperShadow = high[idx] - MathMax(open[idx], close[idx]);
   double lowerShadow = MathMin(open[idx], close[idx]) - low[idx]);
   double totalRange = high[idx] - low[idx];
   
   if(totalRange == 0) return false;
   
   // 射击之星特征:长上影线,短下影线,小实体
   bool isSmallBody = (body / totalRange) < 0.3;
   bool isLongUpperShadow = (upperShadow / totalRange) > 0.6;
   bool isShortLowerShadow = (lowerShadow / totalRange) < 0.1;
   
   return (isSmallBody && isLongUpperShadow && isShortLowerShadow);
}

//+------------------------------------------------------------------+
//| 判断是否为红三兵                                                 |
//+------------------------------------------------------------------+
bool IsThreeSoldiers(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   if(idx + 2 >= ArraySize(open)) return false;
   
   // 连续三根阳线
   bool threeBullish = (close[idx] > open[idx]) &&
                      (close[idx+1] > open[idx+1]) &&
                      (close[idx+2] > open[idx+2]);
   
   if(!threeBullish) return false;
   
   // 每根K线的收盘价都高于前一根的收盘价
   bool ascendingCloses = (close[idx] > close[idx+1]) &&
                         (close[idx+1] > close[idx+2]);
   
   // 每根K线都有明显的实体
   bool significantBodies = (MathAbs(close[idx] - open[idx]) > MinBodySizePoints * Point) &&
                           (MathAbs(close[idx+1] - open[idx+1]) > MinBodySizePoints * Point) &&
                           (MathAbs(close[idx+2] - open[idx+2]) > MinBodySizePoints * Point);
   
   return (ascendingCloses && significantBodies);
}

//+------------------------------------------------------------------+
//| 判断是否为三只乌鸦                                               |
//+------------------------------------------------------------------+
bool IsThreeCrows(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   if(idx + 2 >= ArraySize(open)) return false;
   
   // 连续三根阴线
   bool threeBearish = (close[idx] < open[idx]) &&
                      (close[idx+1] < open[idx+1]) &&
                      (close[idx+2] < open[idx+2]);
   
   if(!threeBearish) return false;
   
   // 每根K线的收盘价都低于前一根的收盘价
   bool descendingCloses = (close[idx] < close[idx+1]) &&
                          (close[idx+1] < close[idx+2]);
   
   // 每根K线都有明显的实体
   bool significantBodies = (MathAbs(close[idx] - open[idx]) > MinBodySizePoints * Point) &&
                           (MathAbs(close[idx+1] - open[idx+1]) > MinBodySizePoints * Point) &&
                           (MathAbs(close[idx+2] - open[idx+2]) > MinBodySizePoints * Point);
   
   return (descendingCloses && significantBodies);
}

//+------------------------------------------------------------------+
//| 判断是否为十字星                                                 |
//+------------------------------------------------------------------+
bool IsDoji(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   double body = MathAbs(close[idx] - open[idx]);
   double totalRange = high[idx] - low[idx];
   
   if(totalRange == 0) return false;
   
   // 十字星特征:实体非常小
   return (body / totalRange < 0.1);
}

//+------------------------------------------------------------------+
//| 判断是否为孕线                                                   |
//+------------------------------------------------------------------+
bool IsHarami(int idx, const double &open[], const double &high[], const double &low[], const double &close[])
{
   if(idx + 1 >= ArraySize(open)) return false;
   
   double currentBody = MathAbs(close[idx] - open[idx]);
   double prevBody = MathAbs(close[idx+1] - open[idx+1]);
   
   // 当前K线的实体完全包含在前一根K线的实体范围内
   bool bodyContained = (MathMax(open[idx], close[idx]) < MathMax(open[idx+1], close[idx+1])) &&
                       (MathMin(open[idx], close[idx]) > MathMin(open[idx+1], close[idx+1]));
   
   return (bodyContained && (currentBody < prevBody));
}
举报

点赞 评论 使用道具

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

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