工作已完成
指定
witam wszystkich programistów prosze o ulepszenie do warunków realnych zeby bot działał na demo działa dobrze ale na warunkach prawdziwych juz nie
//+------------------------------------------------------------------+
//| GoldPendingEA_Professional_v17.1_PRO.mq4 |
//| Autor: Kamil |
//| XAU/USD: AutoLot skokowy + Cele USD ~ lot, Trailing, Panel |
//| BuyStop/SellStop, SL->profit, filtr spreadu, auto-reset |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
//=================== Parametry handlowe ===================//
input int DistancePoints = 100; // odległość pendingów od ceny (punkty)
input int SL_Points = 200; // SL w punktach
input int TP_Points = 200; // TP w punktach
input int Slippage = 10;
input int Magic = 777;
input int MaxAllowedSpread = 10; // max spread (punkty)
// Trailing
input int TrailingGap = 80; // odległość SL od ceny (punkty)
input int TrailingStep = 10; // minimalny krok aktualizacji (punkty)
// Przesunięcie SL w zysk po progu USD
input bool EnableMoveSLtoProfit = true;
input double MoveSLProfitTrigger = 50.0; // łączny zysk EA (USD), po którym SL idzie w zysk
input double MoveSL_OffsetPoints = 100; // o ile punktów ponad cenę wejścia (BUY) / poniżej (SELL)
//=================== AutoLot i cele USD ===================//
input bool EnableAutoLot = true;
input double LotStepUSDPer01 = 100.0; // co ile USD salda dodajemy 0.01 lot
input double MinLot = 0.01; // min lot
input double MaxLot = 50.0; // max lot
input double ProfitPerLotUSD = 240.0; // zysk docelowy na 1.00 lot
input double LossPerLotUSD = 30.0; // strata maks. na 1.00 lot
input bool RecalcTargetsOnTick = false;
//=================== Kolory panelu ===================//
input color PanelBackgroundColor = clrDarkSlateGray;
input color PanelTextColor = clrWhite;
input color PanelBorderColor = clrDimGray;
input color PanelTitleColor = clrGold;
//=================== Zmienne globalne ===================//
double gPoint, gStopLevel;
double gLot = 0.01;
double gCloseAtProfitUSD = 0.0;
double gCloseAtLossUSD = 0.0;
bool gSessionActive = false;
bool gMovedToProfit = false;
//=================== Deklaracje ===================//
void CalculateLotAndTargets();
void OpenPendings();
void ManageOrders();
void LiveTrailing();
bool MoveSLtoProfitZone();
bool CloseAllEAOrders(string reason);
void AutoResetIfAllClosed();
void DeletePending(int type);
void DeleteAllPendings();
double CurrentEAProfitUSD();
void CreatePanel();
void UpdatePanel();
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit()
{
gPoint = MarketInfo(Symbol(), MODE_POINT);
gStopLevel= MarketInfo(Symbol(), MODE_STOPLEVEL) * gPoint;
CalculateLotAndTargets();
OpenPendings();
gSessionActive = true;
CreatePanel();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick()
{
if(RecalcTargetsOnTick) CalculateLotAndTargets();
ManageOrders();
MoveSLtoProfitZone();
LiveTrailing();
double pnl = CurrentEAProfitUSD();
if(pnl >= gCloseAtProfitUSD)
{
if(CloseAllEAOrders("TargetProfit")) gSessionActive=false;
}
else if(pnl <= gCloseAtLossUSD)
{
if(CloseAllEAOrders("MaxLoss")) gSessionActive=false;
}
AutoResetIfAllClosed();
UpdatePanel();
}
//+------------------------------------------------------------------+
//| Obliczenia lota i celów USD |
//+------------------------------------------------------------------+
void CalculateLotAndTargets()
{
double balance = AccountBalance();
if(EnableAutoLot)
{
double steps = balance / MathMax(LotStepUSDPer01, 1.0);
gLot = 0.01 * MathFloor(steps + 1e-9);
if(gLot < MinLot) gLot = MinLot;
if(gLot > MaxLot) gLot = MaxLot;
gLot = NormalizeDouble(gLot, 2);
}
gCloseAtProfitUSD = NormalizeDouble(gLot * ProfitPerLotUSD, 2);
gCloseAtLossUSD = NormalizeDouble(-gLot * LossPerLotUSD, 2);
Print("AutoLot=", DoubleToString(gLot,2),
" | TargetProfit=", DoubleToString(gCloseAtProfitUSD,2),
" | MaxLoss=", DoubleToString(gCloseAtLossUSD,2));
}
//+------------------------------------------------------------------+
//| Aktualny P/L (USD) dla zleceń EA |
//+------------------------------------------------------------------+
double CurrentEAProfitUSD()
{
double sum=0;
for(int i=0;i<OrdersTotal();i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
int t=OrderType();
if(t==OP_BUY || t==OP_SELL)
sum += OrderProfit()+OrderSwap()+OrderCommission();
}
return(sum);
}
//+------------------------------------------------------------------+
//| Przesunięcie SL w zysk po progu USD |
//+------------------------------------------------------------------+
bool MoveSLtoProfitZone()
{
if(!EnableMoveSLtoProfit) return(false);
if(CurrentEAProfitUSD() < MoveSLProfitTrigger) return(false);
bool changed=false;
RefreshRates();
for(int i=0;i<OrdersTotal();i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
double open=OrderOpenPrice(), tp=OrderTakeProfit(), sl=OrderStopLoss();
double newSL;
if(OrderType()==OP_BUY)
{
newSL = NormalizeDouble(open + MoveSL_OffsetPoints*gPoint, Digits);
if(Bid>newSL && newSL>sl)
{
if(!OrderModify(OrderTicket(), open, newSL, tp, 0, clrAqua))
Print("OrderModify BUY error ", GetLastError());
else { changed=true; gMovedToProfit=true; }
}
}
else if(OrderType()==OP_SELL)
{
newSL = NormalizeDouble(open - MoveSL_OffsetPoints*gPoint, Digits);
if(Ask<newSL && (sl==0 || newSL<sl))
{
if(!OrderModify(OrderTicket(), open, newSL, tp, 0, clrAqua))
Print("OrderModify SELL error ", GetLastError());
else { changed=true; gMovedToProfit=true; }
}
}
}
return(changed);
}
//+------------------------------------------------------------------+
//| Otwieranie pendingów z filtrem spreadu |
//+------------------------------------------------------------------+
void OpenPendings()
{
RefreshRates();
double ask=MarketInfo(Symbol(), MODE_ASK);
double bid=MarketInfo(Symbol(), MODE_BID);
double spread=MarketInfo(Symbol(), MODE_SPREAD);
if(spread > MaxAllowedSpread)
{
Print("Spread zbyt wysoki (", spread, " pkt) – nie otwieram zleceń.");
return;
}
DeleteAllPendings();
double buyPrice = NormalizeDouble(ask + DistancePoints*gPoint, Digits);
double sellPrice = NormalizeDouble(bid - DistancePoints*gPoint, Digits);
double buySL = NormalizeDouble(buyPrice - SL_Points*gPoint, Digits);
double buyTP = NormalizeDouble(buyPrice + TP_Points*gPoint, Digits);
double sellSL = NormalizeDouble(sellPrice + SL_Points*gPoint, Digits);
double sellTP = NormalizeDouble(sellPrice - TP_Points*gPoint, Digits);
int bt = OrderSend(Symbol(), OP_BUYSTOP, gLot, buyPrice, Slippage, buySL, buyTP, "BuyStop", Magic, 0, clrBlue);
if(bt<0) Print("BuyStop error ", GetLastError());
int st = OrderSend(Symbol(), OP_SELLSTOP, gLot, sellPrice, Slippage, sellSL, sellTP, "SellStop", Magic, 0, clrRed);
if(st<0) Print("SellStop error ", GetLastError());
}
//+------------------------------------------------------------------+
//| Gdy aktywuje się BUY/SELL – usuń przeciwny pending |
//+------------------------------------------------------------------+
void ManageOrders()
{
bool hasBuy=false, hasSell=false;
for(int i=0;i<OrdersTotal();i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
if(OrderType()==OP_BUY) hasBuy=true;
if(OrderType()==OP_SELL) hasSell=true;
}
if(hasBuy) DeletePending(OP_SELLSTOP);
if(hasSell) DeletePending(OP_BUYSTOP);
}
//+------------------------------------------------------------------+
//| Trailing stop |
//+------------------------------------------------------------------+
void LiveTrailing()
{
RefreshRates();
for(int i=0;i<OrdersTotal();i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
double open=OrderOpenPrice(), sl=OrderStopLoss(), tp=OrderTakeProfit();
if(OrderType()==OP_BUY)
{
double newSL=NormalizeDouble(Bid - TrailingGap*gPoint, Digits);
if(Bid>open && newSL > sl + TrailingStep*gPoint)
{
if(!OrderModify(OrderTicket(), open, newSL, tp, 0, clrLime))
Print("Trailing BUY error ", GetLastError());
}
}
else if(OrderType()==OP_SELL)
{
double newSL=NormalizeDouble(Ask + TrailingGap*gPoint, Digits);
if(Ask<open && newSL < sl - TrailingStep*gPoint)
{
if(!OrderModify(OrderTicket(), open, newSL, tp, 0, clrLime))
Print("Trailing SELL error ", GetLastError());
}
}
}
}
//+------------------------------------------------------------------+
//| Zamknij wszystko |
//+------------------------------------------------------------------+
bool CloseAllEAOrders(string reason)
{
RefreshRates();
Print("CloseAll [", reason, "]");
bool okAll=true;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
bool ok=true;
int t=OrderType();
if(t==OP_BUY) ok=OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrRed);
if(t==OP_SELL) ok=OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrRed);
if(t==OP_BUYSTOP || t==OP_SELLSTOP) ok=OrderDelete(OrderTicket());
if(!ok){ Print("Close error ", GetLastError()); okAll=false; }
}
return(okAll);
}
//+------------------------------------------------------------------+
//| Auto reset po całkowitym zamknięciu |
//+------------------------------------------------------------------+
void AutoResetIfAllClosed()
{
int active=0;
for(int i=0;i<OrdersTotal();i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
active++;
}
if(active==0)
{
if(!gSessionActive)
{
CalculateLotAndTargets();
OpenPendings();
gSessionActive=true;
gMovedToProfit=false;
}
}
else
{
gSessionActive=false;
}
}
//+------------------------------------------------------------------+
//| Usuń pendingi danego typu |
//+------------------------------------------------------------------+
void DeletePending(int type)
{
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
if(OrderType()!=type) continue;
if(!OrderDelete(OrderTicket()))
Print("DeletePending error ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Usuń wszystkie pendingi EA |
//+------------------------------------------------------------------+
void DeleteAllPendings()
{
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
int t=OrderType();
if(t==OP_BUYSTOP || t==OP_SELLSTOP)
{
if(!OrderDelete(OrderTicket()))
Print("DeleteAll error ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| Stylowy panel informacyjny EA |
//+------------------------------------------------------------------+
void CreatePanel()
{
string bg="EA_BG";
if(ObjectFind(0,bg)==-1)
{
ObjectCreate(0,bg,OBJ_RECTANGLE_LABEL,0,0,0);
ObjectSet(bg,OBJPROP_CORNER,0);
ObjectSet(bg,OBJPROP_XDISTANCE,8);
ObjectSet(bg,OBJPROP_YDISTANCE,20);
ObjectSet(bg,OBJPROP_XSIZE,340);
ObjectSet(bg,OBJPROP_YSIZE,230);
ObjectSet(bg,OBJPROP_BGCOLOR,PanelBackgroundColor);
ObjectSet(bg,OBJPROP_COLOR,PanelBorderColor);
ObjectSetInteger(0,bg,OBJPROP_CORNER,CORNER_LEFT_UPPER);
ObjectSetInteger(0,bg,OBJPROP_BACK,true);
}
string lbls[]={"EA_Title","EA_Line1","EA_Line2","EA_Line3",
"EA_Line4","EA_Line5","EA_Line6","EA_Line7"};
for(int i=0;i<ArraySize(lbls);i++)
{
if(ObjectFind(0,lbls[i])==-1)
{
ObjectCreate(0,lbls[i],OBJ_LABEL,0,0,0);
ObjectSet(lbls[i],OBJPROP_CORNER,0);
ObjectSet(lbls[i],OBJPROP_XDISTANCE,20);
ObjectSet(lbls[i],OBJPROP_YDISTANCE,30+(i*25));
ObjectSetText(lbls[i],"",10,"Segoe UI",PanelTextColor);
}
}
}
//+------------------------------------------------------------------+
//| Aktualizacja panelu |
//+------------------------------------------------------------------+
void UpdatePanel()
{
RefreshRates();
double ask=MarketInfo(Symbol(), MODE_ASK);
double bid=MarketInfo(Symbol(), MODE_BID);
double spread=MarketInfo(Symbol(), MODE_SPREAD);
double pnl=CurrentEAProfitUSD();
double bal=AccountBalance();
string statusIcon=gSessionActive ? "🟢" : "🔄";
color pnlColor = pnl>=0 ? clrLime : clrTomato;
color spreadColor = spread>MaxAllowedSpread ? clrRed : clrWhite;
ObjectSetText("EA_Title","💎 GoldPendingEA v17.1 PRO",12,"Segoe UI Bold",PanelTitleColor);
ObjectSetText("EA_Line1",statusIcon+" Status: "+(gSessionActive?"Aktywny":"Reset"),10,"Segoe UI",clrWhite);
ObjectSetText("EA_Line2","📉 Spread: "+DoubleToString(spread,0)+" pkt",10,"Segoe UI",spreadColor);
ObjectSetText("EA_Line3","💰 Saldo: "+DoubleToString(bal,2)+" USD",10,"Segoe UI",clrYellow);
ObjectSetText("EA_Line4","⚖️ Lot: "+DoubleToString(gLot,2),10,"Segoe UI",clrAqua);
ObjectSetText("EA_Line5","🎯 Cele: TP "+DoubleToString(gCloseAtProfitUSD,2)+" $ | SL "+DoubleToString(gCloseAtLossUSD,2)+" $",10,"Segoe UI",clrOrange);
ObjectSetText("EA_Line6","📊 P/L: "+DoubleToString(pnl,2)+" $",10,"Segoe UI",pnlColor);
ObjectSetText("EA_Line7","💹 Bid: "+DoubleToString(bid,Digits)+" | Ask: "+DoubleToString(ask,Digits),10,"Segoe UI",clrSilver);
}
//+------------------------------------------------------------------+