找这款ea源码 mt5的
任务需求: 有的可以联系我吞金EA源代码
#property copyright "Copyright 2026"
#property link "https://www.mql5.com"
#property version "3.2"
#property strict
//+------------------------------------------------------------------+
input group"======= 【EA 启动开关】======="
input bool 启动开关 = true;
// 移动平均线参数
input group"======= 【移动平均线参数】======="
input int 移动周期 = 10;
input ENUM_MA_METHOD 移动方法 = MODE_SMA;
input ENUM_APPLIED_PRICE 移动应用价格 = PRICE_CLOSE;
// 多单设置
input int 多单加仓间隔 = 120; // 多单加仓间隔(点数)
input double 多单加仓倍数 = 1.3; // 多单加仓倍数
input double 多单初始开仓仓位 = 0.01; // 多单初始开仓仓位
input double 多单仓位止盈点数 = 50.0; // 多单仓位止盈点数
input int 多单加仓次数 = 19; // 多单加仓次数
input int 多单加仓间隔2 = 120; // 多单加仓间隔【2】(点数)
input double 多单加仓倍数2 = 1.3; // 多单加仓倍数【2】
input double 多单仓位止盈点数2 = 50.0; // 多单仓位止盈点数【2】
input int 多单加仓次数2 = 1; // 多单加仓次数【2】
// 空单设置
input int 空单加仓间隔 = 120; // 空单加仓间隔(点数)
input double 空单加仓倍数 = 1.3; // 空单加仓倍数
input double 空单初始开仓仓位 = 0.01; // 空单初始开仓仓位
input double 空单仓位止盈点数 = 50.0; // 空单仓位止盈点数
input int 空单加仓次数 = 19; // 空单加仓次数
input int 空单加仓间隔2 = 120; // 空单加仓间隔【2】(点数)
input double 空单加仓倍数2 = 1.3; // 空单加仓倍数【2】
input double 空单仓位止盈点数2 = 50.0; // 空单仓位止盈点数【2】
input int 空单加仓次数2 = 1; // 空单加仓次数【2】
// 风控设置
input double 整体盈利全平 = 0.0; // 整体盈利全平(美元)
input double 整体亏损全平 = 0.0; // 整体亏损全平(美元)
input int 最大浮点数 = 10; // 最大浮点数(备用)
input double 盈利多少后今天停止 = 9999.0; // 盈利多少后今天停止(美元)
input double 亏损多少后今天停止 = 9999999.0; // 亏损多少后今天停止(美元)
input int 字体大小 = 12; // 字体大小
// 辅助参数(非图片参数)
input int 交易滑点 = 10; // 交易滑点
input int 加仓冷却秒 = 5; // 加仓冷却秒
//+------------------------------------------------------------------+
//| 全局变量 |
//+------------------------------------------------------------------+
double g_point = 0.0;
int g_digits = 0;
bool g_activated = false;
string g_auth_tip = "未启动";
bool g_is_tester = false;
int ma_handle = -1;
int trend_dir = 0; // 1:上涨 -1:下跌 0:震荡
datetime g_last_buy_time= 0;
datetime g_last_sell_time = 0;
double g_today_start_balance = 0.0;
bool g_today_stop = false;
datetime g_last_day_check = 0;
// 合并后的最大加仓次数
int max_buy_additions;
int max_sell_additions;
double buy_add_spacing;
double sell_add_spacing;
double buy_add_mult;
double sell_add_mult;
// 按钮名称
#define BUTTON_CLOSE_ALL "Btn_CloseAll"
#define BUTTON_CLOSE_BUY "Btn_CloseBuy"
#define BUTTON_CLOSE_SELL"Btn_CloseSell"
//+------------------------------------------------------------------+
//| 工具函数 |
//+------------------------------------------------------------------+
int GetBuyCount() {
int c = 0;
for(int i = 0; i < PositionsTotal(); i++) {
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t) && PositionGetInteger(POSITION_MAGIC) == 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
c++;
}
return c;
}
int GetSellCount() {
int c = 0;
for(int i = 0; i < PositionsTotal(); i++) {
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t) && PositionGetInteger(POSITION_MAGIC) == 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
c++;
}
return c;
}
double GetTotalProfitUSD() {
double p = 0;
for(int i = 0; i < PositionsTotal(); i++) {
ulong t = PositionGetTicket(i);
if(!PositionSelectByTicket(t)) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != 0) continue;
p += PositionGetDouble(POSITION_PROFIT);
}
return p;
}
double GetLastBuyPrice() {
double p = 0;
datetime t = 0;
for(int i = 0; i < PositionsTotal(); i++) {
ulong tk = PositionGetTicket(i);
if(PositionSelectByTicket(tk) && PositionGetInteger(POSITION_MAGIC) == 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
datetime ot = (datetime)PositionGetInteger(POSITION_TIME);
if(ot > t) {
t = ot;
p = PositionGetDouble(POSITION_PRICE_OPEN);
}
}
}
return p;
}
double GetLastSellPrice() {
double p = 0;
datetime t = 0;
for(int i = 0; i < PositionsTotal(); i++) {
ulong tk = PositionGetTicket(i);
if(PositionSelectByTicket(tk) && PositionGetInteger(POSITION_MAGIC) == 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {
datetime ot = (datetime)PositionGetInteger(POSITION_TIME);
if(ot > t) {
t = ot;
p = PositionGetDouble(POSITION_PRICE_OPEN);
}
}
}
return p;
}
double CalcLot(int level, double init_lot, double mult) {
double lot = init_lot;
for(int i = 2; i <= level; i++) lot *= mult;
double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
lot = MathMax(min_lot, MathMin(max_lot, lot));
return NormalizeDouble(lot, 2);
}
//+------------------------------------------------------------------+
//| 移动平均线趋势 |
//+------------------------------------------------------------------+
void AnalyzeTrend() {
double ma;
if(CopyBuffer(ma_handle, 0, 0, 3, ma) < 3) return;
if(ma > ma && ma > ma) trend_dir = 1;
else if(ma < ma && ma < ma) trend_dir = -1;
else trend_dir = 0;
}
//+------------------------------------------------------------------+
//| 创建按钮 |
//+------------------------------------------------------------------+
void CreateButton(string name, int x, int y, int width, int height, string text, color bgColor, color textColor, int fontSize) {
if(ObjectFind(0, name) == -1) {
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bgColor);
ObjectSetInteger(0, name, OBJPROP_COLOR, textColor);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontSize);
ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrBlack);
ObjectSetInteger(0, name, OBJPROP_STATE, false);
}
}
//+------------------------------------------------------------------+
//| 面板显示(含按钮) |
//+------------------------------------------------------------------+
void CreateLabel(long chartID, int x, int y, string text, color clr, int fontSize) {
string labelName = "PANEL_" + IntegerToString(x) + "_" + IntegerToString(y);
if(ObjectFind(chartID, labelName) != -1) ObjectDelete(chartID, labelName);
ObjectCreate(chartID, labelName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(chartID, labelName, OBJPROP_XDISTANCE, x);
ObjectSetInteger(chartID, labelName, OBJPROP_YDISTANCE, y);
ObjectSetString(chartID, labelName, OBJPROP_TEXT, text);
ObjectSetInteger(chartID, labelName, OBJPROP_COLOR, clr);
ObjectSetInteger(chartID, labelName, OBJPROP_FONTSIZE, fontSize);
ObjectSetInteger(chartID, labelName, OBJPROP_BACK, true);
}
void DrawPanel() {
int x = 140;
int y = 70;
int line = 18;
CreateLabel(0, x, y, "", clrGold, 14);
y += line + 5;
CreateLabel(0, x, y, "运行状态 : " + g_auth_tip, clrLime, 字体大小);
y += line;
double profit = GetTotalProfitUSD();
color pColor = (profit >= 0) ? clrGreen : clrRed;
CreateLabel(0, x, y, "当前浮盈 : " + DoubleToString(profit, 2), pColor, 字体大小);
y += line;
int b = GetBuyCount(), s = GetSellCount();
CreateLabel(0, x, y, "多单数量 : " + (string)b, clrBlue, 字体大小);
y += line;
CreateLabel(0, x, y, "空单数量 : " + (string)s, clrRed, 字体大小);
y += line;
CreateLabel(0, x, y, "多单加仓间隔 : " + DoubleToString(多单加仓间隔, 0) + "点", clrYellow, 字体大小);
y += line;
CreateLabel(0, x, y, "空单加仓间隔 : " + DoubleToString(空单加仓间隔, 0) + "点", clrYellow, 字体大小);
y += line;
string trend_str = trend_dir == 1 ? "上涨" : (trend_dir == -1 ? "下跌" : "震荡");
CreateLabel(0, x, y, "当前趋势 : " + trend_str, clrCyan, 字体大小);
y += line;
double today_pnl = AccountInfoDouble(ACCOUNT_BALANCE) - g_today_start_balance;
CreateLabel(0, x, y, "今日盈亏 : " + DoubleToString(today_pnl, 2), clrWhite, 字体大小);
y += line + 8;
// 创建三个按钮(位于面板下方)
int btnWidth = 70, btnHeight = 25;
CreateButton(BUTTON_CLOSE_BUY,x, y, btnWidth, btnHeight, "多单全平", clrBlue, clrWhite, 10);
CreateButton(BUTTON_CLOSE_SELL, x + btnWidth+5,y, btnWidth, btnHeight, "空单全平", clrRed, clrWhite, 10);
CreateButton(BUTTON_CLOSE_ALL,x + 2*(btnWidth+5), y, btnWidth, btnHeight, "全平", clrDarkGray, clrWhite, 10);
}
//+------------------------------------------------------------------+
//| 平仓函数 |
//+------------------------------------------------------------------+
void ClosePos(ulong tk) {
if(!PositionSelectByTicket(tk)) return;
MqlTradeRequest r;
MqlTradeResult res;
ZeroMemory(r);
r.action = TRADE_ACTION_DEAL;
r.symbol = _Symbol;
r.position = tk;
r.magic = 0;
r.volume = PositionGetDouble(POSITION_VOLUME);
r.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
r.price = (r.type == ORDER_TYPE_SELL) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
r.deviation = 交易滑点;
Exec(r, res);
}
void CloseAll() {
for(int i = PositionsTotal() - 1; i >= 0; i--) {
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t) && PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == 0)
ClosePos(t);
}
}
void CloseBuyAll() {
for(int i = PositionsTotal() - 1; i >= 0; i--) {
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t) && PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == 0) {
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
ClosePos(t);
}
}
}
void CloseSellAll() {
for(int i = PositionsTotal() - 1; i >= 0; i--) {
ulong t = PositionGetTicket(i);
if(PositionSelectByTicket(t) && PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == 0) {
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
ClosePos(t);
}
}
}
//+------------------------------------------------------------------+
//| 授权检查(取消账户限制) |
//+------------------------------------------------------------------+
void CheckLicense() {
g_is_tester = (bool)MQLInfoInteger(MQL_TESTER);
if(g_is_tester) {
g_activated = true;
g_auth_tip = "回测模式";
return;
}
if(!启动开关) {
g_activated = false;
g_auth_tip = "已停止";
return;
}
// 无账户限制,直接激活
g_activated = true;
g_auth_tip = "正常运行";
}
//+------------------------------------------------------------------+
//| 交易执行 |
//+------------------------------------------------------------------+
bool Exec(MqlTradeRequest &r, MqlTradeResult &res) {
ZeroMemory(res);
bool sent = OrderSend(r, res);
if(!sent || res.retcode != TRADE_RETCODE_DONE) {
Print("订单失败:", res.comment);
return false;
}
return true;
}
bool OpenBuy(double lot) {
if(!g_activated) return false;
if(TimeCurrent() - g_last_buy_time < 加仓冷却秒) return false;
MqlTradeRequest r;
MqlTradeResult res;
ZeroMemory(r);
r.action = TRADE_ACTION_DEAL;
r.symbol = _Symbol;
r.volume = NormalizeDouble(lot, 2);
r.type = ORDER_TYPE_BUY;
r.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
r.deviation = 交易滑点;
r.type_filling = ORDER_FILLING_IOC;
r.magic = 0;
bool ok = Exec(r, res);
if(ok) g_last_buy_time = TimeCurrent();
return ok;
}
bool OpenSell(double lot) {
if(!g_activated) return false;
if(TimeCurrent() - g_last_sell_time < 加仓冷却秒) return false;
MqlTradeRequest r;
MqlTradeResult res;
ZeroMemory(r);
r.action = TRADE_ACTION_DEAL;
r.symbol = _Symbol;
r.volume = NormalizeDouble(lot, 2);
r.type = ORDER_TYPE_SELL;
r.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
r.deviation = 交易滑点;
r.type_filling = ORDER_FILLING_IOC;
r.magic = 0;
bool ok = Exec(r, res);
if(ok) g_last_sell_time = TimeCurrent();
return ok;
}
//+------------------------------------------------------------------+
//| 独立仓位止盈 |
//+------------------------------------------------------------------+
void CheckSingleTP() {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
for(int i = PositionsTotal() - 1; i >= 0; i--) {
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket)) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != 0) continue;
double open_price = PositionGetDouble(POSITION_PRICE_OPEN);
double points;
double tp_points;
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
points = (bid - open_price) / g_point;
tp_points = 多单仓位止盈点数;
} else {
points = (open_price - ask) / g_point;
tp_points = 空单仓位止盈点数;
}
if(points >= tp_points && tp_points > 0) {
ClosePos(ticket);
Print("独立止盈触发, 盈利点数: ", points);
}
}
}
//+------------------------------------------------------------------+
//| 整体盈利/亏损全平 |
//+------------------------------------------------------------------+
void CheckGlobalPLClose() {
double profit = GetTotalProfitUSD();
if(整体盈利全平 > 0 && profit >= 整体盈利全平) {
CloseAll();
Print("整体盈利全平: ", profit);
}
if(整体亏损全平 > 0 && -profit >= 整体亏损全平) {
CloseAll();
Print("整体亏损全平: ", -profit);
}
}
//+------------------------------------------------------------------+
//| 今日停止逻辑(修复日期比较) |
//+------------------------------------------------------------------+
bool IsNewDay() {
MqlDateTime tmNow, tmLast;
datetime now = TimeCurrent();
TimeToStruct(now, tmNow);
TimeToStruct(g_last_day_check, tmLast);
if(tmNow.year != tmLast.year || tmNow.mon != tmLast.mon || tmNow.day != tmLast.day) {
g_last_day_check = now;
return true;
}
return false;
}
void UpdateDailyStop() {
if(IsNewDay()) {
g_today_start_balance = AccountInfoDouble(ACCOUNT_BALANCE);
g_today_stop = false;
}
if(g_today_stop) return;
double today_pnl = AccountInfoDouble(ACCOUNT_BALANCE) - g_today_start_balance;
if(盈利多少后今天停止 > 0 && today_pnl >= 盈利多少后今天停止) {
g_today_stop = true;
Print("今日盈利达标,停止交易。");
}
if(亏损多少后今天停止 > 0 && -today_pnl >= 亏损多少后今天停止) {
g_today_stop = true;
Print("今日亏损达标,停止交易。");
}
}
//+------------------------------------------------------------------+
//| 首单开仓(依据趋势) |
//+------------------------------------------------------------------+
void OpenFirstOrder() {
if(GetBuyCount() > 0 || GetSellCount() > 0) return;
if(trend_dir == 1) {
OpenBuy(多单初始开仓仓位);
} else if(trend_dir == -1) {
OpenSell(空单初始开仓仓位);
}
}
//+------------------------------------------------------------------+
//| 同向加仓 |
//+------------------------------------------------------------------+
void AddPositionSameDirection() {
int b = GetBuyCount();
int s = GetSellCount();
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(trend_dir == 1 && s == 0 && b > 0 && b <= max_buy_additions) {
double last = GetLastBuyPrice();
if(last <= 0) return;
double drop = (last - ask) / g_point;
if(drop >= buy_add_spacing) {
double lot = CalcLot(b + 1, 多单初始开仓仓位, buy_add_mult);
if(OpenBuy(lot))
Print("多单加仓第", b+1, "层");
}
}
if(trend_dir == -1 && b == 0 && s > 0 && s <= max_sell_additions) {
double last = GetLastSellPrice();
if(last <= 0) return;
double rise = (bid - last) / g_point;
if(rise >= sell_add_spacing) {
double lot = CalcLot(s + 1, 空单初始开仓仓位, sell_add_mult);
if(OpenSell(lot))
Print("空单加仓第", s+1, "层");
}
}
}
//+------------------------------------------------------------------+
//| 趋势反转处理 |
//+------------------------------------------------------------------+
void HandleTrendReversal() {
int b = GetBuyCount();
int s = GetSellCount();
if(trend_dir == 1 && s > 0) {
CloseAll();
if(GetBuyCount() == 0 && GetSellCount() == 0)
OpenFirstOrder();
}
else if(trend_dir == -1 && b > 0) {
CloseAll();
if(GetBuyCount() == 0 && GetSellCount() == 0)
OpenFirstOrder();
}
else if(trend_dir == 0 && (b > 0 || s > 0)) {
CloseAll();
}
}
//+------------------------------------------------------------------+
//| 主策略 |
//+------------------------------------------------------------------+
void RunStrategy() {
UpdateDailyStop();
if(g_today_stop) return;
CheckSingleTP();
CheckGlobalPLClose();
HandleTrendReversal();
if(GetBuyCount() == 0 && GetSellCount() == 0)
OpenFirstOrder();
else
AddPositionSameDirection();
}
//+------------------------------------------------------------------+
//| 图表事件处理(按钮点击) |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
if(id == CHARTEVENT_OBJECT_CLICK) {
if(sparam == BUTTON_CLOSE_ALL) {
CloseAll();
Print("用户点击【全平】按钮");
}
else if(sparam == BUTTON_CLOSE_BUY) {
CloseBuyAll();
Print("用户点击【多单全平】按钮");
}
else if(sparam == BUTTON_CLOSE_SELL) {
CloseSellAll();
Print("用户点击【空单全平】按钮");
}
}
}
//+------------------------------------------------------------------+
//| 初始化 |
//+------------------------------------------------------------------+
int OnInit() {
CheckLicense();
g_point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(_Symbol == "XAUUSD" || _Symbol == "XAUUSDC") g_point = 0.00001;
g_digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
ma_handle = iMA(_Symbol, Period(), 移动周期, 0, 移动方法, 移动应用价格);
if(ma_handle == INVALID_HANDLE) return INIT_FAILED;
// 合并加仓次数
max_buy_additions= 多单加仓次数 + 多单加仓次数2;
max_sell_additions = 空单加仓次数 + 空单加仓次数2;
buy_add_spacing = 多单加仓间隔;
sell_add_spacing= 空单加仓间隔;
buy_add_mult = 多单加仓倍数;
sell_add_mult = 空单加仓倍数;
g_today_start_balance = AccountInfoDouble(ACCOUNT_BALANCE);
g_today_stop = false;
g_last_day_check = TimeCurrent();
ObjectsDeleteAll(0);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
ObjectsDeleteAll(0);
if(ma_handle != -1) IndicatorRelease(ma_handle);
}
//+------------------------------------------------------------------+
//| 逐Tick运行 |
//+------------------------------------------------------------------+
void OnTick() {
CheckLicense();
AnalyzeTrend();
DrawPanel();
if(!g_activated) return;
RunStrategy();
}
//+------------------------------------------------------------------+ 吞金兽t5源码
页:
[1]