设为首页 收藏本站 切换语言
| 发表于 2025-8-23 15:49:28 | 显示全部楼层 |复制链接
© 本贴为 henrylin9999 首发,严禁抄袭!
image.png

image.png
NVDA跑今年的数据,日线,模拟盘1万本金,160%收益
#property description "动态网格策略 - Dynamic Grid Trading Strategy"

#include <Trade\Trade.mqh>

//--- 输入参数
input group "=== 基础参数 ==="
input double   InpLotSize = 0.0001;        // 基础手数
input int      InpMagicNumber = 12349;     // 魔术数字
input double   InpTotalRisk = 0.05;        // 总风险比例

input group "=== 动态网格参数 ==="
input int      InpBaseGridStep = 200;      // 基础网格间距(点)
input int      InpMaxGridLevels = 2;       // 最大网格层数
input double   InpATRMultiplier = 1.5;     // ATR倍数
input int      InpATRPeriod = 14;          // ATR周期
input bool     InpUseATRSpacing = false;   // 使用ATR动态间距

input group "=== 网格管理 ==="
input double   InpGridVolumeMultiplier = 1.0; // 网格手数倍数
input bool     InpUseMartingale = false;   // 使用马丁格尔
input double   InpMartingaleMultiplier = 2.0; // 马丁格尔倍数
input int      InpMaxPositions = 5;        // 最大持仓数量

input group "=== 市场条件 ==="
input bool     InpUseVolatilityFilter = true; // 使用波动率过滤
input double   InpMinVolatility = 0.0001;  // 最小波动率
input double   InpMaxVolatility = 0.005;   // 最大波动率
input bool     InpUseTrendFilter = false;  // 使用趋势过滤
input int      InpTrendPeriod = 50;        // 趋势判断周期

input group "=== 动态调整 ==="
input bool     InpDynamicLotSize = true;   // 动态手数调整
input bool     InpDynamicSpacing = false;  // 动态间距调整
input int      InpVolatilityCheckPeriod = 100; // 波动率检查周期
input double   InpVolatilityThreshold = 1.5; // 波动率变化阈值

input group "=== 风险控制 ==="
input double   InpMaxDrawdown = 0.01;      // 最大回撤比例
input double   InpDailyLossLimit = 0.005;  // 日损失限制
input bool     InpUseEquityStop = true;    // 使用净值止损
input double   InpEquityStopPercent = 0.15; // 净值止损百分比

//--- 全局变量
CTrade         g_trade;                    // 交易对象
double         g_point_value;              // 点值
datetime       g_last_grid_update;         // 上次网格更新时间
double         g_account_start_balance;    // 账户起始余额
double         g_daily_start_balance;      // 日起始余额
datetime       g_daily_reset_time;         // 日重置时间

//--- 动态网格策略特定变量
int            g_atr_handle;               // ATR句柄
int            g_trend_ma_handle;          // 趋势MA句柄
double         g_atr_values[];             // ATR值缓冲区
double         g_trend_ma[];               // 趋势MA缓冲区

// 网格状态结构
struct GridLevel
{
    double   price;         // 网格价格
    ulong    buy_ticket;    // 买单票据
    ulong    sell_ticket;   // 卖单票据
    double   lot_size;      // 手数
    datetime create_time;   // 创建时间
    bool     is_active;     // 是否激活
};

GridLevel      g_grid_levels[];            // 网格层级数组
double         g_current_grid_spacing;     // 当前网格间距
double         g_base_price;               // 网格基准价格
bool           g_grid_active;              // 网格是否激活
int            g_active_grid_count;        // 激活的网格数量

//--- 市场状态枚举
enum ENUM_MARKET_STATE
{
    MARKET_RANGING,     // 震荡市
    MARKET_TRENDING_UP, // 上升趋势
    MARKET_TRENDING_DOWN, // 下降趋势
    MARKET_HIGH_VOLATILITY, // 高波动
    MARKET_LOW_VOLATILITY   // 低波动
};

ENUM_MARKET_STATE g_market_state = MARKET_RANGING;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 基础初始化
    if(!BaseInitialization())
        return INIT_FAILED;

    // 策略特定初始化
    if(!StrategyInitialization())
        return INIT_FAILED;

    Print("动态网格策略初始化成功: ", _Symbol);
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 策略特定清理
    StrategyDeinitialization();

    // 基础清理
    BaseDeinitialization();

    Print("动态网格策略已停止运行");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // 基础检查
    if(!BaseChecks())
        return;

    // 更新市场状态
    UpdateMarketState();

    // 检查风险控制
    if(!CheckRiskLimits())
    {
        if(g_grid_active)
        {
            Print("触发风险限制,暂停网格交易");
            g_grid_active = false;
        }
        return;
    }

    // 动态调整网格参数
    if(TimeCurrent() - g_last_grid_update >= InpVolatilityCheckPeriod)
    {
        UpdateDynamicParameters();
        g_last_grid_update = TimeCurrent();
    }

    // 网格管理
    ManageGrid();

    // 管理现有持仓
    ManagePositions();
}

//+------------------------------------------------------------------+
//| 基础初始化                                                        |
//+------------------------------------------------------------------+
bool BaseInitialization()
{
    // 获取点值
    g_point_value = _Point;
    if(_Digits == 5 || _Digits == 3)
        g_point_value = _Point * 10;

    // 初始化账户信息
    g_account_start_balance = AccountInfoDouble(ACCOUNT_BALANCE);
    g_daily_start_balance = AccountInfoDouble(ACCOUNT_BALANCE);
    g_daily_reset_time = TimeCurrent() - (TimeCurrent() % 86400); // 当日0点

    // 初始化CTrade对象
    g_trade.SetExpertMagicNumber(InpMagicNumber);
    g_trade.SetMarginMode();
    g_trade.SetTypeFillingBySymbol(_Symbol);
    g_trade.SetDeviationInPoints(10);

    // 验证输入参数
    if(InpLotSize <= 0)
    {
        Print("错误: 手数必须大于0");
        return false;
    }

    if(InpMagicNumber <= 0)
    {
        Print("错误: 魔术数字必须大于0");
        return false;
    }

    if(InpMaxGridLevels <= 0 || InpMaxGridLevels > 50)
    {
        Print("错误: 最大网格层数必须在1-50之间");
        return false;
    }

    // 初始化网格变量
    g_current_grid_spacing = InpBaseGridStep * g_point_value;
    g_base_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    g_grid_active = true;
    g_active_grid_count = 0;
    g_last_grid_update = TimeCurrent();

    return true;
}

//+------------------------------------------------------------------+
//| 动态网格策略初始化                                                 |
//+------------------------------------------------------------------+
bool StrategyInitialization()
{
    // 创建ATR指标句柄
    if(InpUseATRSpacing)
    {
        g_atr_handle = iATR(_Symbol, PERIOD_CURRENT, InpATRPeriod);

        if(g_atr_handle == INVALID_HANDLE)
        {
            Print("创建ATR指标失败");
            return false;
        }
    }

    // 创建趋势MA句柄
    if(InpUseTrendFilter)
    {
        g_trend_ma_handle = iMA(_Symbol, PERIOD_CURRENT,
                               InpTrendPeriod, 0, MODE_EMA, PRICE_CLOSE);

        if(g_trend_ma_handle == INVALID_HANDLE)
        {
            Print("创建趋势MA指标失败");
            return false;
        }
    }

    // 设置缓冲区为时间序列
    ArraySetAsSeries(g_atr_values, true);
    ArraySetAsSeries(g_trend_ma, true);

    // 初始化网格数组
    ArrayResize(g_grid_levels, InpMaxGridLevels * 2); // 买卖各一半

    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        g_grid_levels.price = 0;
        g_grid_levels.buy_ticket = 0;
        g_grid_levels.sell_ticket = 0;
        g_grid_levels.lot_size = InpLotSize;
        g_grid_levels.create_time = 0;
        g_grid_levels.is_active = false;
    }

    // 验证参数
    if(InpATRMultiplier <= 0 || InpATRMultiplier > 10)
    {
        Print("错误: ATR倍数必须在0-10之间");
        return false;
    }

    if(InpGridVolumeMultiplier < 1.0 || InpGridVolumeMultiplier > 5.0)
    {
        Print("错误: 网格手数倍数必须在1.0-5.0之间");
        return false;
    }

    if(InpMaxDrawdown <= 0 || InpMaxDrawdown > 1.0)
    {
        Print("错误: 最大回撤比例必须在0-1之间");
        return false;
    }

    Print("动态网格策略初始化成功");
    Print("基础网格间距: ", InpBaseGridStep, "点");
    Print("最大网格层数: ", InpMaxGridLevels);
    Print("ATR动态间距: ", InpUseATRSpacing ? "启用" : "禁用");
    Print("波动率过滤: ", InpUseVolatilityFilter ? "启用" : "禁用");
    Print("趋势过滤: ", InpUseTrendFilter ? "启用" : "禁用");

    return true;
}

//+------------------------------------------------------------------+
//| 基础清理                                                          |
//+------------------------------------------------------------------+
void BaseDeinitialization()
{
    // 基础清理工作
}

//+------------------------------------------------------------------+
//| 动态网格策略清理                                                   |
//+------------------------------------------------------------------+
void StrategyDeinitialization()
{
    // 释放ATR指标句柄
    if(InpUseATRSpacing && g_atr_handle != INVALID_HANDLE)
    {
        IndicatorRelease(g_atr_handle);
        Print("ATR指标句柄已释放");
    }

    // 释放趋势MA句柄
    if(InpUseTrendFilter && g_trend_ma_handle != INVALID_HANDLE)
    {
        IndicatorRelease(g_trend_ma_handle);
        Print("趋势MA指标句柄已释放");
    }
}

//+------------------------------------------------------------------+
//| 基础检查                                                          |
//+------------------------------------------------------------------+
bool BaseChecks()
{
    // 检查市场状态
    if(!IsMarketOpen())
        return false;

    return true;
}

//+------------------------------------------------------------------+
//| 检查市场是否开放                                                   |
//+------------------------------------------------------------------+
bool IsMarketOpen()
{
    MqlTick tick;
    if(!SymbolInfoTick(_Symbol, tick))
        return false;

    return tick.time > 0;
}

//+------------------------------------------------------------------+
//| 更新市场状态                                                       |
//+------------------------------------------------------------------+
void UpdateMarketState()
{
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    // 获取ATR值用于波动率判断
    if(InpUseATRSpacing && CopyBuffer(g_atr_handle, 0, 0, 5, g_atr_values) >= 5)
    {
        double current_atr = g_atr_values[0];
        double avg_atr = (g_atr_values[0] + g_atr_values[1] + g_atr_values[2] +
                         g_atr_values[3] + g_atr_values[4]) / 5.0;

        // 判断波动率状态
        if(current_atr > avg_atr * InpVolatilityThreshold)
        {
            g_market_state = MARKET_HIGH_VOLATILITY;
        }
        else if(current_atr < avg_atr / InpVolatilityThreshold)
        {
            g_market_state = MARKET_LOW_VOLATILITY;
        }
    }

    // 获取趋势状态 - 增强趋势识别
    if(InpUseTrendFilter && CopyBuffer(g_trend_ma_handle, 0, 0, 10, g_trend_ma) >= 10)
    {
        double price_vs_ma = (current_price - g_trend_ma[0]) / g_trend_ma[0];
        double ma_trend = (g_trend_ma[0] - g_trend_ma[9]) / g_trend_ma[9];

        // 更严格的趋势判断
        if(price_vs_ma > 0.01 && ma_trend > 0.005) // 价格高于MA 1%且MA上升0.5%
        {
            if(g_market_state != MARKET_HIGH_VOLATILITY && g_market_state != MARKET_LOW_VOLATILITY)
                g_market_state = MARKET_TRENDING_UP;
        }
        else if(price_vs_ma < -0.01 && ma_trend < -0.005) // 价格低于MA 1%且MA下降0.5%
        {
            if(g_market_state != MARKET_HIGH_VOLATILITY && g_market_state != MARKET_LOW_VOLATILITY)
                g_market_state = MARKET_TRENDING_DOWN;
        }
        else
        {
            if(g_market_state != MARKET_HIGH_VOLATILITY && g_market_state != MARKET_LOW_VOLATILITY)
                g_market_state = MARKET_RANGING;
        }
    }
}

//+------------------------------------------------------------------+
//| 检查风险限制                                                       |
//+------------------------------------------------------------------+
bool CheckRiskLimits()
{
    double current_balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double current_equity = AccountInfoDouble(ACCOUNT_EQUITY);

    // 检查日损失限制
    datetime current_day = TimeCurrent() - (TimeCurrent() % 86400);
    if(current_day != g_daily_reset_time)
    {
        g_daily_reset_time = current_day;
        g_daily_start_balance = current_balance;
    }

    double daily_loss = (g_daily_start_balance - current_balance) / g_daily_start_balance;
    if(daily_loss > InpDailyLossLimit)
    {
        Print("达到日损失限制: ", DoubleToString(daily_loss * 100, 2), "%");
        return false;
    }

    // 检查最大回撤
    double drawdown = (g_account_start_balance - current_balance) / g_account_start_balance;
    if(drawdown > InpMaxDrawdown)
    {
        Print("达到最大回撤限制: ", DoubleToString(drawdown * 100, 2), "%");
        return false;
    }

    // 检查净值止损
    if(InpUseEquityStop)
    {
        double equity_loss = (current_balance - current_equity) / current_balance;
        if(equity_loss > InpEquityStopPercent)
        {
            Print("触发净值止损: ", DoubleToString(equity_loss * 100, 2), "%");
            return false;
        }
    }

    return true;
}

//+------------------------------------------------------------------+
//| 更新动态参数                                                       |
//+------------------------------------------------------------------+
void UpdateDynamicParameters()
{
    // 禁用动态间距调整,使用固定间距
    /*
    // 动态间距调整
    if(InpDynamicSpacing && InpUseATRSpacing)
    {
        if(CopyBuffer(g_atr_handle, 0, 0, 1, g_atr_values) >= 1)
        {
            double new_spacing = g_atr_values[0] * InpATRMultiplier;

            // 限制间距在合理范围内
            double min_spacing = InpBaseGridStep * g_point_value * 0.5;
            double max_spacing = InpBaseGridStep * g_point_value * 3.0;

            new_spacing = MathMax(min_spacing, MathMin(max_spacing, new_spacing));

            if(MathAbs(new_spacing - g_current_grid_spacing) / g_current_grid_spacing > 0.5)
            {
                g_current_grid_spacing = new_spacing;
                Print("动态调整网格间距: ", DoubleToString(g_current_grid_spacing / g_point_value, 1), "点");

                // 减少频繁重新计算,避免过多canceled订单
                // RecalculateGridLevels();
            }
        }
    }
    */

    // 动态手数调整
    if(InpDynamicLotSize)
    {
        UpdateDynamicLotSizes();
    }
}

//+------------------------------------------------------------------+
//| 重新计算网格层级                                                   |
//+------------------------------------------------------------------+
void RecalculateGridLevels()
{
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    g_base_price = current_price;

    // 重新计算所有网格价格
    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        if(g_grid_levels.is_active)
        {
            // 暂时禁用旧网格,等待新价格计算
            g_grid_levels.is_active = false;
        }
    }

    // 根据新间距重新设置网格
    SetupInitialGrid();
}

//+------------------------------------------------------------------+
//| 更新动态手数                                                       |
//+------------------------------------------------------------------+
void UpdateDynamicLotSizes()
{
    double account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double risk_amount = account_balance * InpTotalRisk;

    // 根据当前激活的网格数量调整手数
    int active_grids = CountActiveGrids();
    if(active_grids > 0)
    {
        double new_lot_size = risk_amount / (active_grids * 1000 * g_current_grid_spacing / g_point_value);
        new_lot_size = NormalizeLotSize(new_lot_size);

        // 更新未激活网格的手数
        for(int i = 0; i < ArraySize(g_grid_levels); i++)
        {
            if(!g_grid_levels.is_active)
            {
                g_grid_levels.lot_size = new_lot_size;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 网格管理                                                           |
//+------------------------------------------------------------------+
void ManageGrid()
{
    if(!g_grid_active)
        return;

    // 检查是否需要初始化网格
    if(g_active_grid_count == 0)
    {
        SetupInitialGrid();
    }

    // 检查网格触发
    CheckGridTriggers();

    // 清理已完成的网格订单
    CleanupCompletedGrids();
}

//+------------------------------------------------------------------+
//| 设置初始网格                                                       |
//+------------------------------------------------------------------+
void SetupInitialGrid()
{
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    g_base_price = current_price;

    // 根据市场状态调整网格设置
    int buy_levels = InpMaxGridLevels / 2;
    int sell_levels = InpMaxGridLevels / 2;

    switch(g_market_state)
    {
        case MARKET_TRENDING_UP:
            // 上涨趋势只做买入网格,禁止卖出
            buy_levels = InpMaxGridLevels;
            sell_levels = 0;
            break;
        case MARKET_TRENDING_DOWN:
            // 下跌趋势只做卖出网格,禁止买入
            buy_levels = 0;
            sell_levels = InpMaxGridLevels;
            break;
        case MARKET_HIGH_VOLATILITY:
        case MARKET_LOW_VOLATILITY:
            // 高波动和低波动时都暂停网格交易
            buy_levels = 0;
            sell_levels = 0;
            g_grid_active = false;
            Print("波动异常市场,暂停网格交易");
            return;
        default:
            // 震荡市允许双向网格
            buy_levels = InpMaxGridLevels / 2;
            sell_levels = InpMaxGridLevels / 2;
            if(buy_levels == 0) buy_levels = 1;
            if(sell_levels == 0) sell_levels = 1;
            break;
    }

    // 设置买入网格
    for(int i = 0; i < buy_levels; i++)
    {
        double grid_price = current_price - (i + 1) * g_current_grid_spacing;
        SetupGridLevel(i, grid_price, ORDER_TYPE_BUY_LIMIT);
    }

    // 设置卖出网格
    for(int i = 0; i < sell_levels; i++)
    {
        double grid_price = current_price + (i + 1) * g_current_grid_spacing;
        SetupGridLevel(buy_levels + i, grid_price, ORDER_TYPE_SELL_LIMIT);
    }

    Print("初始网格设置完成 - 买入层级: ", buy_levels, " 卖出层级: ", sell_levels);
}

//+------------------------------------------------------------------+
//| 设置网格层级                                                       |
//+------------------------------------------------------------------+
void SetupGridLevel(int index, double price, ENUM_ORDER_TYPE order_type)
{
    if(index >= ArraySize(g_grid_levels))
        return;

    double lot_size = CalculateGridLotSize(index);
    lot_size = NormalizeLotSize(lot_size);

    string comment = StringFormat("Grid_%d_%s", index, order_type == ORDER_TYPE_BUY_LIMIT ? "BUY" : "SELL");

    bool trade_result = false;

    if(order_type == ORDER_TYPE_BUY_LIMIT)
    {
        trade_result = g_trade.BuyLimit(lot_size, price, _Symbol, 0, 0, ORDER_TIME_GTC, 0, comment);
    }
    else if(order_type == ORDER_TYPE_SELL_LIMIT)
    {
        trade_result = g_trade.SellLimit(lot_size, price, _Symbol, 0, 0, ORDER_TIME_GTC, 0, comment);
    }

    if(trade_result)
    {
        ulong ticket = g_trade.ResultOrder();
        if(ticket > 0)
        {
            g_grid_levels[index].price = price;
            g_grid_levels[index].lot_size = lot_size;
            g_grid_levels[index].create_time = TimeCurrent();
            g_grid_levels[index].is_active = true;

            if(order_type == ORDER_TYPE_BUY_LIMIT)
                g_grid_levels[index].buy_ticket = ticket;
            else
                g_grid_levels[index].sell_ticket = ticket;

            g_active_grid_count++;
        }
    }
    else
    {
        Print("网格订单创建失败: ", g_trade.ResultRetcode(), " - ", g_trade.ResultComment());
    }
}

//+------------------------------------------------------------------+
//| 计算网格手数                                                       |
//+------------------------------------------------------------------+
double CalculateGridLotSize(int level)
{
    // 固定手数,不再递增
    double base_lot = InpLotSize;

    // 禁用马丁格尔和手数递增,避免快速亏损
    /*
    if(InpUseMartingale)
    {
        // 马丁格尔递增
        base_lot = InpLotSize * MathPow(InpMartingaleMultiplier, level / 2);
    }
    else
    {
        // 普通递增
        base_lot = InpLotSize * MathPow(InpGridVolumeMultiplier, level / 2);
    }
    */

    return NormalizeLotSize(base_lot);
}

//+------------------------------------------------------------------+
//| 标准化手数                                                         |
//+------------------------------------------------------------------+
double NormalizeLotSize(double volume)
{
    double min_vol = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double max_vol = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    double vol_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

    // 检查保证金需求,确保账户有足够资金
    double margin_required = 0;
    if(!OrderCalcMargin(ORDER_TYPE_BUY, _Symbol, volume, SymbolInfoDouble(_Symbol, SYMBOL_ASK), margin_required))
    {
        Print("无法计算保证金需求");
        return 0;
    }

    double free_margin = AccountInfoDouble(ACCOUNT_FREEMARGIN);
    if(margin_required > free_margin * 0.1) // 保留90%安全边际,极度保守
    {
        volume = volume * (free_margin * 0.1) / margin_required;
        Print("调整手数以适应保证金: ", volume);
    }

    // 外汇杠杆风险控制:限制单笔交易最大手数
    double max_single_lot = AccountInfoDouble(ACCOUNT_BALANCE) / 100000.0; // 每10万余额限制1手
    if(volume > max_single_lot)
    {
        volume = max_single_lot;
        Print("限制最大手数防止杠杆风险: ", volume);
    }

    // 确保音量符合要求
    volume = MathMax(volume, min_vol);
    volume = MathMin(volume, max_vol);
    volume = MathRound(volume / vol_step) * vol_step;

    Print("交易量信息: 输入=", volume, " 最小=", min_vol, " 最大=", max_vol, " 步长=", vol_step, " 最终=", volume);
    Print("保证金需求: ", margin_required, " 自由保证金: ", free_margin);

    return volume;
}

//+------------------------------------------------------------------+
//| 检查网格触发                                                       |
//+------------------------------------------------------------------+
void CheckGridTriggers()
{
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        if(!g_grid_levels.is_active)
            continue;

        // 检查订单是否已执行
        if(g_grid_levels.buy_ticket > 0)
        {
            if(!OrderSelect(g_grid_levels.buy_ticket))
            {
                // 买单已执行,设置对应的卖出订单
                SetupCounterOrder(i, ORDER_TYPE_SELL_LIMIT);
                g_grid_levels.buy_ticket = 0;
            }
        }

        if(g_grid_levels.sell_ticket > 0)
        {
            if(!OrderSelect(g_grid_levels.sell_ticket))
            {
                // 卖单已执行,设置对应的买入订单
                SetupCounterOrder(i, ORDER_TYPE_BUY_LIMIT);
                g_grid_levels.sell_ticket = 0;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 设置反向订单                                                       |
//+------------------------------------------------------------------+
void SetupCounterOrder(int grid_index, ENUM_ORDER_TYPE order_type)
{
    double grid_price = g_grid_levels[grid_index].price;
    double counter_price;

    if(order_type == ORDER_TYPE_BUY_LIMIT)
    {
        counter_price = grid_price - g_current_grid_spacing;
    }
    else
    {
        counter_price = grid_price + g_current_grid_spacing;
    }

    // 寻找空闲的网格位置
    int free_index = FindFreeGridIndex();
    if(free_index >= 0)
    {
        SetupGridLevel(free_index, counter_price, order_type);
    }
}

//+------------------------------------------------------------------+
//| 查找空闲网格索引                                                   |
//+------------------------------------------------------------------+
int FindFreeGridIndex()
{
    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        if(!g_grid_levels.is_active)
            return i;
    }
    return -1;
}

//+------------------------------------------------------------------+
//| 清理已完成的网格                                                   |
//+------------------------------------------------------------------+
void CleanupCompletedGrids()
{
    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        if(!g_grid_levels.is_active)
            continue;

        bool should_remove = false;

        // 检查订单是否已被取消或过期
        if(g_grid_levels.buy_ticket > 0)
        {
            if(!OrderSelect(g_grid_levels.buy_ticket))
                should_remove = true;
        }

        if(g_grid_levels.sell_ticket > 0)
        {
            if(!OrderSelect(g_grid_levels.sell_ticket))
                should_remove = true;
        }

        if(should_remove)
        {
            g_grid_levels.is_active = false;
            g_grid_levels.buy_ticket = 0;
            g_grid_levels.sell_ticket = 0;
            g_active_grid_count--;
        }
    }
}

//+------------------------------------------------------------------+
//| 统计激活网格数量                                                   |
//+------------------------------------------------------------------+
int CountActiveGrids()
{
    int count = 0;
    for(int i = 0; i < ArraySize(g_grid_levels); i++)
    {
        if(g_grid_levels.is_active)
            count++;
    }
    return count;
}

//+------------------------------------------------------------------+
//| 持仓管理                                                           |
//+------------------------------------------------------------------+
void ManagePositions()
{
    // 检查持仓数量限制
    int total_positions = CountPositions();
    if(total_positions >= InpMaxPositions)
    {
        Print("达到最大持仓数量限制: ", total_positions);
        g_grid_active = false;
        return;
    }

    // 检查是否需要重新激活网格
    if(!g_grid_active && total_positions < InpMaxPositions / 2)
    {
        if(CheckRiskLimits())
        {
            g_grid_active = true;
            Print("重新激活网格交易");
        }
    }
}

//+------------------------------------------------------------------+
//| 统计持仓数量                                                       |
//+------------------------------------------------------------------+
int CountPositions()
{
    int count = 0;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionGetTicket(i))
        {
            if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
               PositionGetInteger(POSITION_MAGIC) == InpMagicNumber)
            {
                count++;
            }
        }
    }
    return count;
}

//+------------------------------------------------------------------+
//| 交易事务函数                                                       |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                       const MqlTradeRequest& request,
                       const MqlTradeResult& result)
{
    if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
    {
        if(HistoryDealSelect(trans.deal))
        {
            string symbol = HistoryDealGetString(trans.deal, DEAL_SYMBOL);
            if(symbol == _Symbol)
            {
                long magic = HistoryDealGetInteger(trans.deal, DEAL_MAGIC);
                if(magic == InpMagicNumber)
                {
                    double profit = HistoryDealGetDouble(trans.deal, DEAL_PROFIT);
                    if(profit != 0.0)
                    {
                        Print("动态网格交易完成 - 盈亏: ", profit, " ", AccountInfoString(ACCOUNT_CURRENCY));

                        // 网格交易统计
                        static int grid_trades = 0;
                        static double grid_profit = 0;
                        grid_trades++;
                        grid_profit += profit;

                        if(grid_trades % 5 == 0)
                        {
                            Print("网格交易统计 - 总数: ", grid_trades, " 总盈亏: ", DoubleToString(grid_profit, 2));
                            Print("当前网格状态: ", g_market_state == MARKET_RANGING ? "震荡" :
                                  g_market_state == MARKET_TRENDING_UP ? "上涨" :
                                  g_market_state == MARKET_TRENDING_DOWN ? "下跌" : "高波动");
                        }
                    }
                }
            }
        }
    }
}
举报

评论 使用道具

精彩评论7

qiwen
C
| 发表于 2025-8-23 16:10:32 | 显示全部楼层
楼主直接发出代码,太伟大了
举报

点赞 评论 使用道具

henrylin9999
D
 楼主 | 发表于 2025-8-23 17:09:29 | 显示全部楼层
qiwen 发表于 2025-8-23 16:10
楼主直接发出代码,太伟大了

刚注册,请多多关照
举报

点赞 评论 使用道具

yiquanjun
D
| 发表于 2025-8-23 20:02:22 | 显示全部楼层
必须支持一下
举报

点赞 1 评论 使用道具

xzy881230
DD
| 发表于 2025-8-24 03:22:56 | 显示全部楼层
好样的
举报

点赞 评论 使用道具

shaohua
D
| 发表于 2025-8-25 17:37:21 | 显示全部楼层
楼主直接发出代码,太伟大了  自己写的吗
举报

点赞 评论 使用道具

786438024
D
| 发表于 2025-8-25 22:50:27 | 显示全部楼层
牛皮。支持
举报

点赞 评论 使用道具

dawenxi
D
| 发表于 2025-8-26 03:00:00 | 显示全部楼层
88888888888888888
举报

点赞 评论 使用道具

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

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