寻求一个简单的挂单ea的编写
版本 MT4参数设置
手数
平仓方式可选 1:每单单独止盈止损
2:任意一单止盈则全部平仓
止盈点数 50
止损点数 50
挂单间隔点数 250
开仓说明
多单 即时价格之上间隔X点挂多单,成交后以成交价格为基础继续间隔X点之上挂多单 举例:即时价格为2900,在2900之上间隔250点也就是2902.5挂多单,如果成交就继续在2905挂多单
空单 即时价格之下间隔X点挂空单,成交后以成交价格为基础继续间隔X点之下挂空单
平仓说明 1:每单单独止盈止损 如选择该种平仓方式,则任一成交单止盈后,删除全部挂单,重新开始挂多空双向的单子,保留的单子设好止盈后保留即可,等待成交不用管它了 这里可能有两种情况,一种是,某个方向的单子成交后直接走向止盈,另一种是没有触达止盈而是向着相反的方向走去,从而使得反向单成交,反向单成交后,两个单子最终会有一个止盈,止盈后就删掉挂单重新开始新的挂单,保留的那个单子按照止盈止损设置好不用管了就,一直等到他止盈或者止损
2:任意一单止盈则全部平仓 如果选择这种平仓方式,则任一单止盈后,平掉所有持仓单及挂单,然后重新开始挂单 咋联系
这样也行吧,需要的下载 /*
EA名称:PendingOrderEA.mq4
版本:MT4
参数说明:
Lots - 交易手数
CloseMode - 平仓方式:1为“每单单独止盈止损”,2为“任一单止盈则全部平仓”
TakeProfitPoints - 止盈点数(例如50点)
StopLossPoints - 止损点数(例如50点)
PendingDistancePoints - 挂单间隔点数(例如250点)
开仓说明:
多单:以当前 g_longBase 为基准,在其上加上 PendingDistancePoints 换算后的价格间隔挂 Buy Stop 单,
成交后以成交价格更新 g_longBase,再继续挂出下一单。
空单:以当前 g_shortBase 为基准,在其下减去价格间隔挂 Sell Stop 单,
成交后以成交价格更新 g_shortBase,再继续挂出下一单。
平仓说明:
若 CloseMode = 1(每单单独止盈止损):任一挂单成交且止盈(检测历史订单近5秒内盈利)时,仅取消所有挂单,
重新挂出多空挂单(已成交订单保留,后续由各自的 TP/SL 自动平仓)。
若 CloseMode = 2(任一单止盈则全部平仓):任一挂单止盈后,关闭所有持仓及挂单,然后重新挂单。
注意:代码中采用 PendingDistancePoints、TakeProfitPoints、StopLossPoints 与价格之间的换算因子 PointFactor,
此处默认1点 = 0.01价格单位,请根据品种实际小数位调整。
*/
#property strict
extern double Lots = 0.1;
extern int CloseMode = 1; // 1:每单单独止盈止损,2:任一单止盈则全部平仓
extern int TakeProfitPoints = 50; // 止盈点数
extern int StopLossPoints = 50; // 止损点数
extern int PendingDistancePoints = 250;// 挂单间隔点数
int MagicNumber = 123456; // 魔术数字
// 用于计算挂单价格的换算因子(根据品种小数位调整)
double PointFactor = 0.01;
// 多单和空单的基准价
double g_longBase = 0;
double g_shortBase = 0;
// 取消所有挂单(Buy Stop 和 Sell Stop)
void CancelPendingOrders()
{
for (int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber &&
(OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP))
{
if(!OrderDelete(OrderTicket()))
Print("删除挂单失败, Error:", GetLastError());
}
}
}
}
// 挂出挂单:多单挂 Buy Stop,空单挂 Sell Stop
void PlacePendingOrders()
{
double offset = PendingDistancePoints * PointFactor;
// 挂多单:价格 = g_longBase + offset
double buyPrice = NormalizeDouble(g_longBase + offset, Digits);
double tpLong = NormalizeDouble(buyPrice + TakeProfitPoints * PointFactor, Digits);
double slLong = NormalizeDouble(buyPrice - StopLossPoints * PointFactor, Digits);
int ticket = OrderSend(Symbol(), OP_BUYSTOP, Lots, buyPrice, 3, slLong, tpLong, "Buy Pending", MagicNumber, 0, Blue);
if(ticket < 0)
Print("挂Buy Stop失败, Error:", GetLastError());
// 挂空单:价格 = g_shortBase - offset
double sellPrice = NormalizeDouble(g_shortBase - offset, Digits);
double tpShort = NormalizeDouble(sellPrice - TakeProfitPoints * PointFactor, Digits);
double slShort = NormalizeDouble(sellPrice + StopLossPoints * PointFactor, Digits);
ticket = OrderSend(Symbol(), OP_SELLSTOP, Lots, sellPrice, 3, slShort, tpShort, "Sell Pending", MagicNumber, 0, Red);
if(ticket < 0)
Print("挂Sell Stop失败, Error:", GetLastError());
}
// 重置挂单:取消挂单、更新基准价(当无持仓时更新为当前市场价)并重新挂单
void ResetPendingOrders()
{
CancelPendingOrders();
bool hasPosition = false;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && (OrderType() == OP_BUY || OrderType() == OP_SELL))
{
hasPosition = true;
break;
}
}
}
if(!hasPosition)
{
g_longBase = Ask;
g_shortBase = Bid;
}
PlacePendingOrders();
}
// 检查是否有止盈成交:检测历史订单中近5秒内盈利的订单
bool CheckTPHit()
{
bool tpHit = false;
int totalHist = OrdersHistoryTotal();
for (int i = totalHist - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderMagicNumber() == MagicNumber)
{
datetime closeTime = OrderCloseTime();
if(closeTime > TimeCurrent() - 5 && OrderProfit() > 0)
{
tpHit = true;
break;
}
}
}
}
return tpHit;
}
// 检查是否有新成交挂单,若有则更新相应方向的基准价,并重挂挂单
void UpdatePendingAfterExecution()
{
bool updateLong = false;
bool updateShort = false;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber)
{
if(OrderType() == OP_BUY)
{
if(OrderOpenPrice() > g_longBase)
{
g_longBase = OrderOpenPrice();
updateLong = true;
}
}
else if(OrderType() == OP_SELL)
{
if(OrderOpenPrice() < g_shortBase)
{
g_shortBase = OrderOpenPrice();
updateShort = true;
}
}
}
}
}
if(updateLong || updateShort)
{
CancelPendingOrders();
PlacePendingOrders();
}
}
// 关闭所有持仓(用于平仓方式2)
void CloseAllOrders()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && (OrderType() == OP_BUY || OrderType() == OP_SELL))
{
double price = (OrderType() == OP_BUY) ? Bid : Ask;
if(!OrderClose(OrderTicket(), OrderLots(), price, 3, clrYellow))
Print("平仓失败, Error:", GetLastError());
}
}
}
}
// 主程序入口
int start()
{
// 初次启动时初始化基准价并挂出挂单
if(g_longBase == 0 || g_shortBase == 0)
{
g_longBase = Ask;
g_shortBase = Bid;
PlacePendingOrders();
}
// 检查挂单数量,若没有挂单则重新挂出
int pendingCount = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber &&
(OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP))
pendingCount++;
}
}
if(pendingCount == 0)
PlacePendingOrders();
// 检查是否有新成交挂单,更新基准价并重挂挂单
UpdatePendingAfterExecution();
// 检查是否有止盈成交触发
if(CheckTPHit())
{
if(CloseMode == 1)
{
// 模式1:取消所有挂单,重新挂单(持仓保留,由各自TP/SL自动平仓)
ResetPendingOrders();
}
else if(CloseMode == 2)
{
// 模式2:平掉所有持仓和挂单,再重新挂单
CloseAllOrders();
CancelPendingOrders();
g_longBase = Ask;
g_shortBase = Bid;
PlacePendingOrders();
}
}
return(0);
}
页:
[1]