求一款马丁ea
这款马丁ea是基于插针后再开单的,比如3秒钟插针5个点的行情再开单,下图这样的行情开单,要插针后开单 兄弟 ,愿意给人民币吗 //+------------------------------------------------------------------+//| 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]