530343609 发表于 2026-1-14 03:36:09

求一款马丁ea

这款马丁ea是基于插针后再开单的,比如3秒钟插针5个点的行情再开单,下图这样的行情开单,要插针后开单

江苏宇桐科技 发表于 2026-1-15 15:06:39

兄弟 ,愿意给人民币吗

芭比qle 发表于 2026-1-17 21:23:59

//+------------------------------------------------------------------+
//|                                                Martin_EA.mq4 |
//|                        Copyright 2025, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// 策略核心参数(可在MT4参数面板调整)
input double    InitialLot = 0.1;      // 初始手数
input int       AddMultiplier = 2;      // 加仓倍数(亏损后下单一倍)
input double    AddDistance = 50;         // 加仓间距(点)
input double    TakeProfit = 30;          // 止盈(点)
input double    StopLoss = 100;         // 单笔止损(点,0为禁用)
input int       MaxOrders = 10;         // 最大开仓订单数
input int       MagicNumber = 12345;      // 魔术号(区分不同EA)
input string    SymbolName = NULL;      // 交易品种(NULL为当前图表品种)

// 全局变量
doublecurrentLot;       // 当前开仓手数
int   orderCount;       // 已开仓订单数

//+------------------------------------------------------------------+
//| Expert initialization function                                 |
//+------------------------------------------------------------------+
int OnInit()
{
    // 初始化参数校验
    if(InitialLot <= 0 || AddMultiplier < 1 || AddDistance <= 0 || MaxOrders < 1)
    {
      Print("参数错误:初始手数/加仓倍数/间距/最大订单数需大于0");
      return(INIT_PARAMETERS_INCORRECT);
    }
    currentLot = InitialLot;
    orderCount = 0;
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 无需额外操作,仅释放资源
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // 确定交易品种
    string symbol = (SymbolName == NULL) ? _Symbol : SymbolName;
    if(!SymbolSelect(symbol, true))
    {
      Print("品种选择失败:", symbol);
      return;
    }

    // 更新当前订单数
    orderCount = GetOpenOrderCount(symbol);

    // 无订单时,开首单
    if(orderCount == 0)
    {
      OpenFirstOrder(symbol);
      return;
    }

    // 订单数未达上限,且满足加仓条件时,加仓
    if(orderCount < MaxOrders && NeedAddOrder(symbol))
    {
      OpenAddOrder(symbol);
      return;
    }
}

//+------------------------------------------------------------------+
//| 获取当前品种未平仓订单数                                       |
//+------------------------------------------------------------------+
int GetOpenOrderCount(string symbol)
{
    int count = 0;
    for(int i = 0; i < OrdersTotal(); i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
            if(OrderSymbol() == symbol && OrderMagicNumber() == MagicNumber && OrderState() == ORDER_STATE_OPEN)
            {
                count++;
            }
      }
    }
    return count;
}

//+------------------------------------------------------------------+
//| 开首单(默认做多,可修改为做空或加入指标触发)                   |
//+------------------------------------------------------------------+
void OpenFirstOrder(string symbol)
{
    MqlTradeRequest request = {0};
    MqlTradeResult result = {0};

    request.action = TRADE_ACTION_DEAL;
    request.symbol = symbol;
    request.volume = NormalizeDouble(currentLot, 2);
    request.type = ORDER_TYPE_BUY;          // 做多(改为ORDER_TYPE_SELL可做空)
    request.price = SymbolInfoDouble(symbol, SYMBOL_ASK);
    request.deviation = 3;                  // 允许滑点(点)
    request.magic = MagicNumber;
    request.type_filling = ORDER_FILLING_FOK;

    // 设置止损止盈
    if(StopLoss > 0)
    {
      request.sl = NormalizeDouble(request.price - StopLoss * Point * SymbolInfoInteger(symbol, SYMBOL_DIGITS), SymbolInfoInteger(symbol, SYMBOL_DIGITS));
    }
    request.tp = NormalizeDouble(request.price + TakeProfit * Point * SymbolInfoInteger(symbol, SYMBOL_DIGITS), SymbolInfoInteger(symbol, SYMBOL_DIGITS));

    if(!OrderSend(request, result))
    {
      Print("首单开仓失败,错误码:", result.retcode);
    }
    else
    {
      Print("首单开仓成功,手数:", currentLot, ",价格:", request.price);
    }
}

//+------------------------------------------------------------------+
//| 判断是否需要加仓(基于首单价格与当前价格的价差)               |
//+------------------------------------------------------------------+
bool NeedAddOrder(string symbol)
{
    // 获取首单开仓价格
    double firstOrderPrice = 0.0;
    for(int i = 0; i < OrdersTotal(); i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
            if(OrderSymbol() == symbol && OrderMagicNumber() == MagicNumber && OrderState() == ORDER_STATE_OPEN)
            {
                firstOrderPrice = OrderOpenPrice();
                break;
            }
      }
    }

    // 做多时,价格下跌达到加仓间距则加仓
    double currentPrice = SymbolInfoDouble(symbol, SYMBOL_BID);
    double priceDiff = NormalizeDouble(firstOrderPrice - currentPrice, SymbolInfoInteger(symbol, SYMBOL_DIGITS));
    double distancePoint = AddDistance * Point * SymbolInfoInteger(symbol, SYMBOL_DIGITS);

    return (priceDiff >= distancePoint);
}

//+------------------------------------------------------------------+
//| 开加仓订单                                                       |
//+------------------------------------------------------------------+
void OpenAddOrder(string symbol)
{
    // 计算加仓手数(上一笔手数 * 加仓倍数)
    double lastLot = GetLastOrderLot(symbol);
    currentLot = NormalizeDouble(lastLot * AddMultiplier, 2);

    MqlTradeRequest request = {0};
    MqlTradeResult result = {0};

    request.action = TRADE_ACTION_DEAL;
    request.symbol = symbol;
    request.volume = currentLot;
    request.type = ORDER_TYPE_BUY;          // 加仓方向与首单一致
    request.price = SymbolInfoDouble(symbol, SYMBOL_ASK);
    request.deviation = 3;
    request.magic = MagicNumber;
    request.type_filling = ORDER_FILLING_FOK;

    // 加仓单止盈与首单一致,止损可选(此处复用首单止损逻辑)
    if(StopLoss > 0)
    {
      request.sl = NormalizeDouble(request.price - StopLoss * Point * SymbolInfoInteger(symbol, SYMBOL_DIGITS), SymbolInfoInteger(symbol, SYMBOL_DIGITS));
    }
    request.tp = NormalizeDouble(GetFirstOrderTP(symbol), SymbolInfoInteger(symbol, SYMBOL_DIGITS));

    if(!OrderSend(request, result))
    {
      Print("加仓失败,错误码:", result.retcode, ",手数:", currentLot);
    }
    else
    {
      Print("加仓成功,手数:", currentLot, ",价格:", request.price);
    }
}

//+------------------------------------------------------------------+
//| 获取上一笔开仓订单的手数                                       |
//+------------------------------------------------------------------+
double GetLastOrderLot(string symbol)
{
    double lot = InitialLot;
    datetime lastOpenTime = 0;
    for(int i = 0; i < OrdersTotal(); i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)
页: [1]
查看完整版本: 求一款马丁ea