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

 找回密码
 立即注册

《周易.系辞》

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

《吕氏.春秋》

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

《晏子·霸业因时而生》

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

《周易.系辞》

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

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

《寒窑赋》

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

《周易.系辞》

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

圣人云:

君子务本,本立而道生!

 《势胜学》

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

《周易·系辞上传》:

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

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

《礼记.中庸》:

凡事预则立,不预则废!

查看: 1359|回复: 1

[【优秀推荐】曲线完美收益中等] 嗷嗷叫

[复制链接]

1657

主题

1896

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
11950

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

QQ
侦云取势 发表于 2025-6-18 23:57:00 | 显示全部楼层 |阅读模式
这是一个叫:【圆点指标.ex5】 的mt5指标。
现在用中文,帮我写一个mt5 ea
【多头信号:】圆点指标.ex5 参数 last length 为6 slow length为14 出现  ptl trend start DodgerBlue 蓝色圆点。开多单。


【加仓】开单后,同时在顺势方向现价上方每隔1000点处挂1笔buy stop突破单。(挂20单)
如果价格上涨 buy stop成交, 如果价格下跌 超过1000点,则之前挂单不取消。然后在现价的上方1000点,重新挂1笔(B订单buy订单)订单,
如果价格继续下跌超过1000点,则继续在现价上方挂一笔(B订单:buy订单)订单。
相当于,只要是多头信号,那么。订单始终跟着现价上方1000点,挂单,反复跟着现价,每次超过1000点移动一次。直到成交,或者是反转。
【空头信号】:圆点指标.ex5 参数 last length 为6 slow length为14 出现  ptl trend start  Crimson 红色圆点。开空单。
【空单加仓和多单方向相反即可】


【如果多信号或者空信号 没盈利出局,出现了反转,那么启动第二个拐点策略。】第二个拐点策略:趋势 空转多,多转空
当趋势从多头转空头,计算持仓buy订单和sell订单的差,反向加倍下现价成交单,然后重复上面的突破挂单多转空的下单手数计算公式:(10手buy-5手sell)的差*2,下单10手sell现价成交单,此时仓位应该是10手buy和5手sell+10手sell订单,行情每次反转,都是如此处理反转。

获利了结,采用的是整体止盈,盈利超过5000点(5美元)回撤3000点,整体平仓。不管是1单还是100单,都是相同止盈策略

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

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

使用道具 举报

1657

主题

1896

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
11950

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

QQ
 楼主| 侦云取势 发表于 2025-6-18 23:57:41 | 显示全部楼层
//+------------------------------------------------------------------+
//|                                             Grid_Reversal_EA.mq5 |
//|                                  Copyright 2024, GPT-4 for MQL5 |
//|                                             https://www.google.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, GPT-4 for MQL5"
#property link      "https://www.google.com"
#property version   "1.40"
#property description "带时间控制和整体止损的圆点指标EA"

#include <Trade/Trade.mqh>

//--- EA 输入参数
input group             "指标参数"
input int               inpFastLength   = 6;            // 圆点指标 - Fast Length
input int               inpSlowLength   = 14;           // 圆点指标 - Slow Length
input string            indicator_name  = "圆点指标";   // 指标文件名称

input group             "订单参数"
input double            initial_lots    = 0.01;         // 初始/加仓订单手数
input ulong             magic_number    = 12345;        // EA魔术数字
input double            reversal_multiplier = 2.0;      // 反转加倍乘数

input group             "顺势加仓参数"
input int               grid_distance_points = 1000;    // 挂单间隔 (点)
input int               max_pending_orders   = 20;      // 最大挂单数量

input group             "盈利管理参数"
input double            profit_target_usd   = 5.0;      // 整体盈利目标(美元)
input double            profit_drawdown_usd = 3.0;      // 盈利回撤(美元)

input group             "【新】亏损管理参数"
input bool              EnableBasketStopLoss = true;    // 启用整体止损
input double            BasketStopLossUSD    = -200.0;  // 整体止损金额 (美元, 请使用负数)

input group             "时间控制参数"
input int               StartHour       = 0;            // 开单开始时间 (小时)
input int               EndHour         = 14;           // 开单结束时间 (小时, 14点代表0:00-13:59)
input bool              EnableDailyClose= true;         // 启用每日清仓
input int               CloseHour       = 14;           // 每日清仓时间 (小时)
input bool              Monday          = true;         // 周一开单
input bool              Tuesday         = true;         // 周二开单
input bool              Wednesday       = true;         // 周三开单
input bool              Thursday        = true;         // 周四开单
input bool              Friday          = true;         // 周五开单
input bool              Saturday        = true;         // 周六开单
input bool              Sunday          = true;         // 周日开单


//--- 全局变量
CTrade trade;
int    indicator_handle;
string ea_comment = "PyramidEA_TS";

//--- 用于跟踪状态的静态变量
enum TrendDirection
{
    NONE,
    UP,
    DOWN
};
static TrendDirection current_trend = NONE;
static double max_profit = 0.0;
static datetime last_close_time = 0; // 用于跟踪每日清仓

//+------------------------------------------------------------------+
//| EA初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
    trade.SetExpertMagicNumber(magic_number);
    trade.SetMarginMode();
    trade.SetTypeFillingBySymbol(_Symbol);

    indicator_handle = iCustom(_Symbol, _Period, indicator_name, inpFastLength, inpSlowLength);
    if(indicator_handle == INVALID_HANDLE)
    {
        Alert("错误: 无法加载圆点指标. 请确保 '", indicator_name, ".ex5' 在 MQL5/Indicators 文件夹中。");
        return(INIT_FAILED);
    }
    InitializeTrendState();
    Print("EA初始化成功. 魔术数字: ", magic_number, ". 风险控制已启用.");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA启动时,检查现有仓位以确定当前趋势状态                         |
//+------------------------------------------------------------------+
void InitializeTrendState()
{
    int buys = 0;
    int sells = 0;

    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == magic_number)
        {
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                buys++;
            else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                sells++;
        }
    }
    if(buys > 0 && sells == 0) current_trend = UP;
    else if(sells > 0 && buys == 0) current_trend = DOWN;
    else current_trend = NONE;
    Print("EA启动,检测到当前趋势状态: ", EnumToString(current_trend));
}

//+------------------------------------------------------------------+
//| EA去初始化函数                                                     |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    if(indicator_handle != INVALID_HANDLE) IndicatorRelease(indicator_handle);
    Print("EA已停止。原因代码: ", reason);
}

//+------------------------------------------------------------------+
//| EA核心逻辑 - OnTick                                              |
//+------------------------------------------------------------------+
void OnTick()
{
    // 盈利平仓检查
    if(CheckBasketProfitClosure()) return;

    // 【新】亏损平仓检查
    if(CheckBasketStopLoss()) return;

    // 每日定时清仓检查
    CheckDailyClose();

    // 新K线信号检查
    if(IsNewBar())
    {
        CheckSignal();
    }
}

//+------------------------------------------------------------------+
//| 每日定时清仓                                                     |
//+------------------------------------------------------------------+
void CheckDailyClose()
{
    if(!EnableDailyClose) return;
    MqlDateTime dt;
    TimeCurrent(dt);
    if(dt.hour == CloseHour)
    {
        MqlDateTime last_dt;
        TimeToStruct(last_close_time, last_dt);
        if(last_dt.day_of_year != dt.day_of_year || last_dt.year != dt.year)
        {
            Print("每日清仓时间到达 (", IntegerToString(CloseHour), ":00). 平仓所有订单...");
            CloseAllTrades();
            last_close_time = TimeCurrent(dt);
        }
    }
}

//+------------------------------------------------------------------+
//| 检查是否在允许的交易时间内                                       |
//+------------------------------------------------------------------+
bool IsTradingAllowed()
{
    MqlDateTime dt;
    TimeCurrent(dt);
    bool day_allowed = false;
    switch(dt.day_of_week)
    {
        case 0: day_allowed = Sunday;    break;
        case 1: day_allowed = Monday;    break;
        case 2: day_allowed = Tuesday;   break;
        case 3: day_allowed = Wednesday; break;
        case 4: day_allowed = Thursday;  break;
        case 5: day_allowed = Friday;    break;
        case 6: day_allowed = Saturday;  break;
    }
    bool hour_allowed = (dt.hour >= StartHour && dt.hour < EndHour);
    return day_allowed && hour_allowed;
}

//+------------------------------------------------------------------+
//| 检查新K线                                                        |
//+------------------------------------------------------------------+
bool IsNewBar()
{
    static datetime last_bar_time = 0;
    datetime current_bar_time = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
    if(last_bar_time != current_bar_time)
    {
        last_bar_time = current_bar_time;
        return true;
    }
    return false;
}

//+------------------------------------------------------------------+
//| 检查指标信号                                                     |
//+------------------------------------------------------------------+
void CheckSignal()
{
    if(!IsTradingAllowed()) return;

    double arrow_price_buffer[], arrow_color_buffer[];
    if(CopyBuffer(indicator_handle, 7, 1, 2, arrow_price_buffer) < 2 ||
       CopyBuffer(indicator_handle, 8, 1, 2, arrow_color_buffer) < 2)
    {
        Print("错误: 无法从指标复制数据. Error code: ", GetLastError());
        return;
    }
    double arrow_value = arrow_price_buffer[0], color_value = arrow_color_buffer[0];
    if(arrow_value != EMPTY_VALUE)
    {
        if(color_value == 0) // 多头信号
        {
            if(current_trend == DOWN) HandleReversal(UP);
            else if(current_trend == NONE)
            {
                if(trade.Buy(initial_lots, _Symbol, 0, 0, 0, ea_comment))
                {
                   current_trend = UP;
                   PlacePyramidGrid(UP);
                }
            }
        }
        else if(color_value == 1) // 空头信号
        {
            if(current_trend == UP) HandleReversal(DOWN);
            else if(current_trend == NONE)
            {
                if(trade.Sell(initial_lots, _Symbol, 0, 0, 0, ea_comment))
                {
                   current_trend = DOWN;
                   PlacePyramidGrid(DOWN);
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 处理反转逻辑                                                     |
//+------------------------------------------------------------------+
void HandleReversal(TrendDirection new_trend)
{
    double buy_lots = 0, sell_lots = 0;
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == magic_number)
        {
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) buy_lots += PositionGetDouble(POSITION_VOLUME);
            else sell_lots += PositionGetDouble(POSITION_VOLUME);
        }
    }
    double lot_diff = MathAbs(buy_lots - sell_lots);
    double new_trade_lots = NormalizeDouble(lot_diff * reversal_multiplier, 2);
    double min_lots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    if(new_trade_lots < min_lots) new_trade_lots = min_lots;

    if(new_trend == UP)
    {
        DeleteAllPendingSells();
        if(trade.Buy(new_trade_lots, _Symbol, 0, 0, 0, ea_comment))
        {
           current_trend = UP;
           PlacePyramidGrid(UP);
        }
    }
    else if(new_trend == DOWN)
    {
        DeleteAllPendingBuys();
        if(trade.Sell(new_trade_lots, _Symbol, 0, 0, 0, ea_comment))
        {
           current_trend = DOWN;
           PlacePyramidGrid(DOWN);
        }
    }
}

//+------------------------------------------------------------------+
//| 信号出现后,一次性挂出顺势的突破单网格                           |
//+------------------------------------------------------------------+
void PlacePyramidGrid(TrendDirection trend)
{
    if(trend == NONE) return;
    if(trend == UP)
    {
        double current_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        for(int i = 1; i <= max_pending_orders; i++)
        {
            double stop_price = current_ask + (i * grid_distance_points * _Point);
            stop_price = NormalizeDouble(stop_price, _Digits);
            trade.BuyStop(initial_lots, stop_price, _Symbol, 0, 0, ORDER_TIME_GTC, 0, ea_comment);
        }
    }
    else if(trend == DOWN)
    {
        double current_bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        for(int i = 1; i <= max_pending_orders; i++)
        {
            double stop_price = current_bid - (i * grid_distance_points * _Point);
            stop_price = NormalizeDouble(stop_price, _Digits);
            trade.SellStop(initial_lots, stop_price, _Symbol, 0, 0, ORDER_TIME_GTC, 0, ea_comment);
        }
    }
}

//+------------------------------------------------------------------+
//| 检查整体盈利平仓条件                                               |
//+------------------------------------------------------------------+
bool CheckBasketProfitClosure()
{
    double current_profit = GetTotalFloatingProfit();
    if(current_profit <= 0)
    {
        max_profit = 0;
        return false;
    }
    if(current_profit > max_profit) max_profit = current_profit;
    if(max_profit >= profit_target_usd && current_profit <= max_profit - profit_drawdown_usd)
    {
        Print("盈利平仓条件触发. Max Profit: ", DoubleToString(max_profit,2), " USD. 平仓所有订单.");
        CloseAllTrades();
        return true;
    }
    return false;
}

//+------------------------------------------------------------------+
//| 【新】检查整体亏损平仓条件                                       |
//+------------------------------------------------------------------+
bool CheckBasketStopLoss()
{
    if (!EnableBasketStopLoss) return false;

    double current_profit = GetTotalFloatingProfit();

    if (current_profit <= BasketStopLossUSD)
    {
        Print("整体止损触发. 当前亏损: ", DoubleToString(current_profit, 2), " USD. 止损线: ", DoubleToString(BasketStopLossUSD, 2), " USD. 平仓所有订单.");
        CloseAllTrades();
        return true;
    }
    return false;
}


//+------------------------------------------------------------------+
//| 计算当前交易品种和魔术数字的总浮动盈亏                             |
//+------------------------------------------------------------------+
double GetTotalFloatingProfit()
{
    double total_profit = 0;
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == magic_number)
        {
            total_profit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
        }
    }
    return total_profit;
}

//+------------------------------------------------------------------+
//| 关闭所有持仓单和挂单                                               |
//+------------------------------------------------------------------+
void CloseAllTrades()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == magic_number)
            trade.PositionClose(PositionGetTicket(i));
    }
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        ulong ticket = OrderGetTicket(i);
        if(ticket > 0)
        {
          if(OrderGetString(ORDER_SYMBOL) == _Symbol && OrderGetInteger(ORDER_MAGIC) == magic_number)
              trade.OrderDelete(ticket);
        }
    }
    current_trend = NONE;
    max_profit = 0.0;
    Print("所有仓位已清理完毕。");
}

//+------------------------------------------------------------------+
//| Helper Functions (辅助函数)                                      |
//+------------------------------------------------------------------+
void DeleteAllPendingBuys()
{
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        ulong ticket = OrderGetTicket(i);
        if(ticket > 0)
        {
           if(OrderGetString(ORDER_SYMBOL) == _Symbol &&
              OrderGetInteger(ORDER_MAGIC) == magic_number &&
              OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
           {
               trade.OrderDelete(ticket);
           }
        }
    }
}

void DeleteAllPendingSells()
{
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
       ulong ticket = OrderGetTicket(i);
       if(ticket > 0)
       {
          if(OrderGetString(ORDER_SYMBOL) == _Symbol &&
             OrderGetInteger(ORDER_MAGIC) == magic_number &&
             OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
          {
              trade.OrderDelete(ticket);
          }
       }
    }
}

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

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

使用道具 举报

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

本版积分规则

关闭

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

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

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

GMT+8, 2025-8-1 15:55 , Processed in 0.024821 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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