监控平仓面版--源码
优化目标
//+------------------------------------------------------------------+
//| 交易面板系统.mq4 |
//| 版权 © 2023-2025, AI编程zblog |
//| http://www.eawalk.com|
//+------------------------------------------------------------------+
#propertycopyright "Copyright 2024, eawalk.com"
#propertylink "http://www.eawalk.com"
stringver = "篮子1.1"; // 交易面板系统.mq4
#propertyversion "1.00"
#propertystrict
//---输入参数
inputdouble Profit = 50; // 盈利目标(单位:货币)
inputdouble TotalCloseValue = 10000; // 总亏损值(达到此值时平仓,单位:货币)
inputint MonitorTickInterval = 8; // 监测TICK间隔(单位:tick)
inputcolor TextColor = White; // 文字颜色
inputint TextSize = 12; // 文字体大小
inputint PanelWidth = 200; // 面板宽度(像素,用于定位)
inputint PanelHeight = 100; // 面板高度(像素,用于定位)
inputint PanelXOffset = 10; // 面板距离右侧的偏移量(像素)
inputint PanelYOffset = 10; // 面板距离顶部的偏移量(像素)
//---全局变量
datetimelastTickTime = 0;
intgMonitorTickInterval; // 存储 MonitorTickInterval 的可修改副本
intgPanelWidth; // 存储 PanelWidth 的可修改副本
intgPanelHeight; // 存储 PanelHeight 的可修改副本
intcloseCount = 0; // 记录批量平仓次数
intgPanelXOffset; // 存储PanelXOffset 的可修改副本
intgPanelYOffset; // 存储PanelYOffset 的可修改副本
//+------------------------------------------------------------------+
//|专家初始化函数 |
//+------------------------------------------------------------------+
intOnInit()
{
// 初始化时检查参数并赋值给全局变量
gMonitorTickInterval = MonitorTickInterval;
if (gMonitorTickInterval < 1) gMonitorTickInterval = 1; // 确保间隔有效
gPanelWidth = PanelWidth;
if (gPanelWidth < 100) gPanelWidth = 100; // 确保面板宽度有效
gPanelHeight = PanelHeight;
if (gPanelHeight < 50) gPanelHeight = 50; // 确保面板高度有效
gPanelXOffset = PanelXOffset;
if (gPanelXOffset < 0) gPanelXOffset = 0; // 确保偏移量有效
gPanelYOffset = PanelYOffset;
if (gPanelYOffset < 0) gPanelYOffset = 0; // 确保偏移量有效
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|专家反初始化函数 |
//+------------------------------------------------------------------+
voidOnDeinit(const int reason)
{
// 清理所有与面板相关的对象
ObjectsDeleteAll(0, "Panel_");
}
//+------------------------------------------------------------------+
//|每tick执行函数 |
//+------------------------------------------------------------------+
voidOnTick()
{
// 每隔gMonitorTickInterval 个 tick 执行一次
if (TimeCurrent() - lastTickTime < gMonitorTickInterval * Point)return;
lastTickTime = TimeCurrent();
// 绘制信息面板
DrawInfoPanel();
// 检查交易逻辑(盈利/亏损)
CheckTradingLogic();
}
//+------------------------------------------------------------------+
//|绘制信息面板(仅文字,无背景) |
//+------------------------------------------------------------------+
voidDrawInfoPanel()
{
// 获取图表宽度以动态定位到右上角
int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int panelX = chartWidth - gPanelWidth - gPanelXOffset; // 距离右侧偏移
// 显示盈利信息
if (!ObjectCreate(0, "Panel_Profit", OBJ_LABEL, 0, 0, 0))
return;
ObjectSetInteger(0, "Panel_Profit", OBJPROP_XDISTANCE, panelX +10);
ObjectSetInteger(0, "Panel_Profit", OBJPROP_YDISTANCE,gPanelYOffset + 20);
ObjectSetString(0, "Panel_Profit", OBJPROP_TEXT, "盈利: " + DoubleToString(Profit,2));
ObjectSetInteger(0, "Panel_Profit", OBJPROP_COLOR, TextColor);
ObjectSetInteger(0, "Panel_Profit", OBJPROP_FONTSIZE,TextSize);
// 显示总亏损值
if (!ObjectCreate(0, "Panel_TotalClose", OBJ_LABEL, 0, 0, 0))
return;
ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_XDISTANCE,panelX + 10);
ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_YDISTANCE,gPanelYOffset + 40);
ObjectSetString(0, "Panel_TotalClose", OBJPROP_TEXT, "总亏损值: " +DoubleToString(TotalCloseValue, 2));
ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_COLOR,TextColor);
ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_FONTSIZE,TextSize);
// 显示平仓次数
if (!ObjectCreate(0, "Panel_CloseCount", OBJ_LABEL, 0, 0, 0))
return;
ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_XDISTANCE,panelX + 10);
ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_YDISTANCE,gPanelYOffset + 60);
ObjectSetString(0, "Panel_CloseCount", OBJPROP_TEXT, "平仓次数: " +IntegerToString(closeCount));
ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_COLOR,TextColor);
ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_FONTSIZE,TextSize);
}
//+------------------------------------------------------------------+
//|检查交易逻辑 |
//+------------------------------------------------------------------+
voidCheckTradingLogic()
{
// 计算当前所有订单的总亏损
double totalLoss = 0;
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol())
{
double orderProfit = OrderProfit() +OrderSwap() + OrderCommission();
if (orderProfit < 0) // 只计算亏损订单
{
totalLoss += MathAbs(orderProfit);// 累计亏损值(取绝对值)
}
}
}
}
// 当总亏损达到 TotalCloseValue 时平仓所有订单
if (totalLoss >= TotalCloseValue)
{
bool batchClosed = false; // 标记是否发生批量平仓
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol())
{
bool closed =OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrRed);
if (closed)
{
batchClosed = true; // 只要有一笔订单成功平仓,标记为批量平仓
Print("因总亏损平仓: ",totalLoss);
}
else
{
Print("平仓失败,错误代码 #",GetLastError());
}
}
}
}
if (batchClosed)
{
closeCount++; // 批量平仓成功后,计数加1
Print("批量平仓完成,总平仓次数: ", closeCount);
}
}
// 基于盈利的平仓条件
double currentProfit = AccountProfit();
if (currentProfit >= Profit)
{
bool batchClosed = false; // 标记是否发生批量平仓
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol())
{
bool closed = OrderClose(OrderTicket(),OrderLots(), OrderClosePrice(), 3, clrRed);
if (closed)
{
batchClosed = true; // 只要有一笔订单成功平仓,标记为批量平仓
Print("因盈利平仓: ",currentProfit);
}
else
{
Print("平仓失败,错误代码 #",GetLastError());
}
}
}
}
if (batchClosed)
{
closeCount++; // 批量平仓成功后,计数加1
Print("批量平仓完成,总平仓次数: ", closeCount);
}
}
}
//+------------------------------------------------------------------+