设为首页 收藏本站 切换语言
| 发表于 2025-5-28 20:55:40 | 显示全部楼层 |复制链接
N 字战法 MT4 实现[color=var(--md-box-samantha-normal-text-color) !important]N 字战法是一种基于价格形态识别的交易策略,其核心是识别价格走势中的 "N" 字形结构:上涨(第一笔)、回调(第二笔)、再上涨(第三笔)形成多头信号;反之则形成空头信号。以下是一个完整的 MT4 实现:
策略核心逻辑
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]N 字形态识别:
    • 看涨形态:低点→高点→回调低点→突破新高
    • 看跌形态:高点→低点→回调高点→跌破新低
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]形态参数:
    • 回调幅度:要求在第一笔幅度的 30%-70% 之间
    • 形态长度:最小 5 根 K 线,最大 20 根 K 线
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]交易信号:
    • 看涨信号:价格突破回调后的高点
    • 看跌信号:价格跌破回调后的低点
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]可视化功能:
    • 在图表上绘制识别出的 N 字形态
    • 标注看涨 / 看跌信号

使用建议
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]参数调整:
    • 根据不同货币对和时间周期调整 MinRetracePercent 和 MaxRetracePercent
    • 在波动较大的市场可以适当放宽回调幅度限制
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]确认条件:
    • 建议结合趋势指标(如均线)确认大趋势方向
    • 可添加成交量指标确认突破有效性
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]风险管理:
    • 严格执行止损,控制单笔风险
    • 可考虑使用追踪止损保护已有利润
  • [color=var(--md-box-samantha-normal-text-color) !important][color=var(--md-box-samantha-deep-text-color) !important]优化方向:
    • 添加时间过滤器,避免在低流动性时段交易
    • 增加对 N 字形态强度的评估
    • 结合其他指标(如 MACD、RSI)进行二次确认


这个 EA 提供了 N 字战法的基本实现,你可以根据自己的交易经验和市场特点进行个性化调整。//+------------------------------------------------------------------+
//| N字战法交易策略                                                   |
//+------------------------------------------------------------------+
#property copyright "DoubaoAssistant"
#property link      ""
#property version   "1.00"
#property strict

// 输入参数
input int MinBars = 5;            // 最小N字结构柱数
input int MaxBars = 20;           // 最大N字结构柱数
input double MinRetracePercent = 30.0; // 最小回调百分比(相对于第一笔)
input double MaxRetracePercent = 70.0; // 最大回调百分比(相对于第一笔)
input double LotSize = 0.1;       // 交易手数
input int StopLoss = 50;          // 止损点数
input int TakeProfit = 100;       // 止盈点数
input bool Alerts = true;         // 启用警报
input bool EmailAlert = false;    // 启用邮件警报
input bool PushAlert = false;     // 启用推送通知

// 全局变量
enum PatternType { NONE, BULLISH, BEARISH };
PatternType currentPattern = NONE;
int patternStartBar = 0;
int patternPeakBar = 0;
int patternEndBar = 0;
double patternPeakPrice = 0;
double patternStartPrice = 0;
double patternEndPrice = 0;

//+------------------------------------------------------------------+
//| EA初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA主函数                                                         |
//+------------------------------------------------------------------+
void OnTick()
{
    // 识别N字形态
    IdentifyPattern();

    // 检查交易信号
    CheckTradeSignal();

    // 绘制形态
    DrawPattern();
}

//+------------------------------------------------------------------+
//| 识别N字形态                                                       |
//+------------------------------------------------------------------+
void IdentifyPattern()
{
    // 重置当前形态
    currentPattern = NONE;

    // 从当前柱向前寻找可能的N字形态
    for(int i = MinBars; i <= MaxBars; i++)
    {
        // 寻找看涨N字形态
        if(IdentifyBullishPattern(i))
        {
            currentPattern = BULLISH;
            break;
        }

        // 寻找看跌N字形态
        if(IdentifyBearishPattern(i))
        {
            currentPattern = BEARISH;
            break;
        }
    }
}

//+------------------------------------------------------------------+
//| 识别看涨N字形态                                                   |
//+------------------------------------------------------------------+
bool IdentifyBullishPattern(int barsAgo)
{
    // 寻找第一个高点(峰)
    int peakBar = FindPeakBar(barsAgo, MODE_HIGH);
    if(peakBar == 0) return false;

    // 寻找起点(峰前的低点)
    int startBar = FindTroughBar(peakBar - 1, MODE_LOW);
    if(startBar == 0 || startBar >= peakBar) return false;

    // 寻找终点(峰后的低点)
    int endBar = FindTroughBar(peakBar + 1, MODE_LOW);
    if(endBar == 0 || endBar <= peakBar) return false;

    // 计算第一笔涨幅
    double firstLeg = High[peakBar] - Low[startBar];
    if(firstLeg <= 0) return false;

    // 计算回调幅度
    double retrace = High[peakBar] - Low[endBar];
    double retracePercent = (retrace / firstLeg) * 100;

    // 检查回调是否在合理范围内
    if(retracePercent < MinRetracePercent || retracePercent > MaxRetracePercent) return false;

    // 检查回调后是否有足够的上涨动能
    double currentPrice = Close[0];
    double breakout = currentPrice - Low[endBar];
    if(breakout <= 0) return false;

    // 保存形态信息
    patternStartBar = startBar;
    patternPeakBar = peakBar;
    patternEndBar = endBar;
    patternStartPrice = Low[startBar];
    patternPeakPrice = High[peakBar];
    patternEndPrice = Low[endBar];

    return true;
}

//+------------------------------------------------------------------+
//| 识别看跌N字形态                                                   |
//+------------------------------------------------------------------+
bool IdentifyBearishPattern(int barsAgo)
{
    // 寻找第一个低点(谷)
    int troughBar = FindTroughBar(barsAgo, MODE_LOW);
    if(troughBar == 0) return false;

    // 寻找起点(谷前的高点)
    int startBar = FindPeakBar(troughBar - 1, MODE_HIGH);
    if(startBar == 0 || startBar >= troughBar) return false;

    // 寻找终点(谷后的高点)
    int endBar = FindPeakBar(troughBar + 1, MODE_HIGH);
    if(endBar == 0 || endBar <= troughBar) return false;

    // 计算第一笔跌幅
    double firstLeg = High[startBar] - Low[troughBar];
    if(firstLeg <= 0) return false;

    // 计算回调幅度
    double retrace = High[endBar] - Low[troughBar];
    double retracePercent = (retrace / firstLeg) * 100;

    // 检查回调是否在合理范围内
    if(retracePercent < MinRetracePercent || retracePercent > MaxRetracePercent) return false;

    // 检查回调后是否有足够的下跌动能
    double currentPrice = Close[0];
    double breakout = High[endBar] - currentPrice;
    if(breakout <= 0) return false;

    // 保存形态信息
    patternStartBar = startBar;
    patternPeakBar = troughBar; // 看跌形态中,第一个低点是峰
    patternEndBar = endBar;
    patternStartPrice = High[startBar];
    patternPeakPrice = Low[troughBar];
    patternEndPrice = High[endBar];

    return true;
}

//+------------------------------------------------------------------+
//| 寻找峰值柱                                                        |
//+------------------------------------------------------------------+
int FindPeakBar(int startBar, int priceType)
{
    double peakPrice = (priceType == MODE_HIGH) ? High[startBar] : Low[startBar];
    int peakBar = startBar;

    // 向前查找
    for(int i = startBar; i >= 0; i--)
    {
        double currentPrice = (priceType == MODE_HIGH) ? High : Low;
        if(currentPrice > peakPrice)
        {
            peakPrice = currentPrice;
            peakBar = i;
        }
        else if(currentPrice < peakPrice)
        {
            break;
        }
    }

    // 向后查找
    for(int i = startBar + 1; i < Bars; i++)
    {
        double currentPrice = (priceType == MODE_HIGH) ? High : Low;
        if(currentPrice > peakPrice)
        {
            return 0; // 不是峰值
        }
        else if(currentPrice < peakPrice)
        {
            break;
        }
    }

    return peakBar;
}

//+------------------------------------------------------------------+
//| 寻找谷值柱                                                        |
//+------------------------------------------------------------------+
int FindTroughBar(int startBar, int priceType)
{
    double troughPrice = (priceType == MODE_HIGH) ? High[startBar] : Low[startBar];
    int troughBar = startBar;

    // 向前查找
    for(int i = startBar; i >= 0; i--)
    {
        double currentPrice = (priceType == MODE_HIGH) ? High : Low;
        if(currentPrice < troughPrice)
        {
            troughPrice = currentPrice;
            troughBar = i;
        }
        else if(currentPrice > troughPrice)
        {
            break;
        }
    }

    // 向后查找
    for(int i = startBar + 1; i < Bars; i++)
    {
        double currentPrice = (priceType == MODE_HIGH) ? High : Low;
        if(currentPrice < troughPrice)
        {
            return 0; // 不是谷值
        }
        else if(currentPrice > troughPrice)
        {
            break;
        }
    }

    return troughBar;
}

//+------------------------------------------------------------------+
//| 检查交易信号                                                     |
//+------------------------------------------------------------------+
void CheckTradeSignal()
{
    // 检查是否有未平仓订单
    if(HasOpenOrders()) return;

    // 看涨N字信号
    if(currentPattern == BULLISH)
    {
        // 价格突破回调后的高点
        if(Close[0] > High[patternEndBar])
        {
            OpenBuyOrder();

            if(Alerts)
            {
                string alertMsg = Symbol() + " N字看涨信号 @" + TimeToStr(TimeCurrent(), TIME_SECONDS);
                Print(alertMsg);
                if(EmailAlert) SendMail("N字战法警报", alertMsg);
                if(PushAlert) SendNotification(alertMsg);
            }
        }
    }
    // 看跌N字信号
    else if(currentPattern == BEARISH)
    {
        // 价格跌破回调后的低点
        if(Close[0] < Low[patternEndBar])
        {
            OpenSellOrder();

            if(Alerts)
            {
                string alertMsg = Symbol() + " N字看跌信号 @" + TimeToStr(TimeCurrent(), TIME_SECONDS);
                Print(alertMsg);
                if(EmailAlert) SendMail("N字战法警报", alertMsg);
                if(PushAlert) SendNotification(alertMsg);
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 绘制N字形态                                                       |
//+------------------------------------------------------------------+
void DrawPattern()
{
    // 清除旧标记
    ObjectsDeleteAll(0, "NPattern_");

    if(currentPattern == NONE) return;

    string prefix = "NPattern_" + IntegerToString(patternStartBar);
    color patternColor = (currentPattern == BULLISH) ? clrGreen : clrRed;

    // 绘制N字形态
    ObjectCreate(prefix + "_L1", OBJ_TREND, 0, Time[patternStartBar], patternStartPrice, Time[patternPeakBar], patternPeakPrice);
    ObjectSet(prefix + "_L1", OBJPROP_COLOR, patternColor);
    ObjectSet(prefix + "_L1", OBJPROP_WIDTH, 2);

    ObjectCreate(prefix + "_L2", OBJ_TREND, 0, Time[patternPeakBar], patternPeakPrice, Time[patternEndBar], patternEndPrice);
    ObjectSet(prefix + "_L2", OBJPROP_COLOR, patternColor);
    ObjectSet(prefix + "_L2", OBJPROP_WIDTH, 2);

    // 添加标签
    string label = (currentPattern == BULLISH) ? "Bullish N" : "Bearish N";
    ObjectCreate(prefix + "_Label", OBJ_TEXT, 0, Time[patternEndBar], patternEndPrice);
    ObjectSetText(prefix + "_Label", label, 8, "Arial", patternColor);
}

//+------------------------------------------------------------------+
//| 检查是否有未平仓订单                                             |
//+------------------------------------------------------------------+
bool HasOpenOrders()
{
    for(int i = 0; i < OrdersTotal(); i++) {
        if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol()) {
            return true;
        }
    }
    return false;
}

//+------------------------------------------------------------------+
//| 开多单                                                            |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
    int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, Ask - StopLoss * Point,
                          Ask + TakeProfit * Point, "N Pattern Buy", 0, 0, clrGreen);

    if(ticket > 0) {
        Print("买入订单执行成功,单号: ", ticket);
    } else {
        Print("买入订单执行失败,错误码: ", GetLastError());
    }
}

//+------------------------------------------------------------------+
//| 开空单                                                            |
//+------------------------------------------------------------------+
void OpenSellOrder()
{
    int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, Bid + StopLoss * Point,
                          Bid - TakeProfit * Point, "N Pattern Sell", 0, 0, clrRed);

    if(ticket > 0) {
        Print("卖出订单执行成功,单号: ", ticket);
    } else {
        Print("卖出订单执行失败,错误码: ", GetLastError());
    } QQ_1748436521425.png
}    QQ_1748436942790.png
举报

评论 使用道具

精彩评论14

hyuen86
DD
| 发表于 2025-5-28 21:23:23 | 显示全部楼层
谢谢分享
举报

点赞 评论 使用道具

kerrceo
DD
| 发表于 2025-5-28 22:10:40 | 显示全部楼层
谢谢楼主,直接把源码分享!
举报

点赞 评论 使用道具

禾胜量化
D
| 发表于 2025-5-28 22:27:15 | 显示全部楼层
感谢楼主
举报

点赞 评论 使用道具

Xander
DD
| 发表于 2025-5-29 06:00:41 | 显示全部楼层
楼主厉害了,又得一个财富收割器。
举报

点赞 评论 使用道具

我曾经是队长
DDD
| 发表于 2025-5-29 09:11:59 | 显示全部楼层
很好 楼主辛苦了
举报

点赞 评论 使用道具

13322835587
DD
| 发表于 2025-5-29 10:31:33 | 显示全部楼层
有人拿来测试了吗
举报

点赞 评论 使用道具

sjwlyl
D
| 发表于 2025-5-29 15:11:24 | 显示全部楼层
有谁成功试过了
举报

点赞 评论 使用道具

irule
DD
| 发表于 2025-5-29 15:14:45 | 显示全部楼层
直接贴出代码,完全免费吗?
举报

点赞 评论 使用道具

Tx88101
DD
| 发表于 2025-5-29 15:19:27 | 显示全部楼层
太高深了,有成功用过的吗
举报

点赞 评论 使用道具

irule
DD
| 发表于 2025-5-29 15:24:19 | 显示全部楼层
挂什么品种什么周期?
举报

点赞 评论 使用道具

Tx88101
DD
| 发表于 2025-5-30 08:55:25 | 显示全部楼层
看到源码点歌赞再说
举报

点赞 评论 使用道具

guanxinvip
D
| 发表于 2025-6-3 13:24:38 | 显示全部楼层
源码直接赞
举报

点赞 评论 使用道具

183257873
D
| 发表于 2025-7-15 12:00:16 | 显示全部楼层
源码必须点赞
举报

点赞 评论 使用道具

a84368702
DDD
| 发表于 4 天前 | 显示全部楼层
代码有问题呀 Snipaste_2025-09-05_09-48-57.jpg
举报

点赞 评论 使用道具

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

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