//+------------------------------------------------------------------+ //| Gold_Sekanas_v1.07.mq4 | //| Copyright 2026, AYDIN SARIHAN | //| https://www.mql5.com/en/users/aydinsarihan | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, AYDIN SARIHAN" #property link "https://www.mql5.com/en/users/aydinsarihan" #property version "1.07" #property strict //================================================================== // SECTION 1: INCLUDES & LIBRARIES //================================================================== #include #include //================================================================== // SECTION 2: INPUT PARAMETERS //================================================================== //--- Strategy Permissions extern bool InpAllowBuy = true; // Allow Buy Trades extern bool InpAllowSell = true; // Allow Sell Trades extern bool InpEAMakesFirstOrder = true; // EA Makes First Order extern bool InpOpenOrderOnTrend = true; // Open Pending on Trend extern int InpStartHour = 3; // Start Trading Hour extern int InpEndHour = 24; // End Trading Hour //--- Grid Settings (Sekanas) extern double InpFirstStep = 1.0; // First Step (Sekanas) extern double InpMinPriceDist = 1.5; // Min Price Distance (Sekanas) extern double InpMoveStep = 2.0; // Move Step (Sekanas) extern double InpDistBetweenOrders = 2.0; // Distance Between Orders (Sekanas) //--- Risk & Lot Management extern double InpOrderLotsize = 0.01; // Base Lot Size extern double InpIncreaseLotsizeBy = 0.0; // Increase Lot By (Add) extern double InpMultiplyLotsizeBy = 1.06; // Multiply Lot By (Martingale) extern int InpRoundLotDecimals = 2; // Lot Decimal Rounding extern double InpMaxAllowedLoss = 26.0; // Max Allowed Loss (Sekanas) extern double InpCloseLossByDD = 100.0; // Close on Drawdown (Sekanas) //--- Take Profit Settings (Sekanas) extern double InpProfitClose2Dir = 5.0; // Profit Close Both Directions (Sekanas) extern double InpProfitClose1Dir = 10.0; // Profit Close One Direction (Sekanas) extern double InpAutoCalcProfit = 0.0; // Auto Calculate Profit (Sekanas) extern double InpLossForClosing = 500.0; // Hard Stop Loss (Sekanas) //--- Trailing Stop (Sekanas) extern bool InpUseTrailing = true; // Use Trailing Stop extern double InpTrailingStep = 2.0; // Trailing Step (Sekanas) extern double InpMinTrailingProfit = 0.5; // Min Profit to Start Trail (Sekanas) //--- Indicator Settings (RSI) extern string InpIndSettings = "RSI"; // Indicator Name (Info) extern bool InpUseIndEntry = true; // Use Indicator for Entry extern int InpOversoldZone = 15; // RSI Oversold Level extern int InpOverboughtZone = 85; // RSI Overbought Level extern int InpRsiPeriod = 5; // RSI Period extern int InpTimeframeInd = 0; // RSI Timeframe (0 = Current) //--- Visual Panel Settings extern int InpPanelX = 20; // Panel X Position extern int InpPanelY = 30; // Panel Y Position extern color InpColorHeader = clrGold; // Header Color //--- Other Settings extern bool InpDeleteOrders = true; // Delete Pending Orders at Time extern int InpDeleteHour = 20; // Deletion Hour extern int InpMagic = 113; // Magic Number extern double InpFixedSL = 0.0; // Fixed SL (Sekanas) extern double InpFixedTP = 0.0; // Fixed TP (Sekanas) //--- Performance & Protection extern double InpModifyThreshold = 0.5; // Modification Threshold (Sekanas) extern int InpOrderTimeGap = 5; // Time Gap Between Orders (Seconds) //================================================================== // SECTION 3: GLOBAL VARIABLES & CONSTANTS //================================================================== #define EA_COMMENT_TAG "SGold_v1.07" #define PANEL_W 260 #define PANEL_H 300 #define COLOR_BG C'25,30,35' #define COLOR_PANE C'40,45,50' #define COLOR_TXT clrWhiteSmoke #define COLOR_ACCENT clrGold #define COLOR_PROFIT clrLimeGreen #define COLOR_LOSS clrTomato datetime g_lastDeleteTime = 0; string g_PanelPrefix = "SGold_v1.07_"; double g_TickValue = 0; double g_Point = 0; int g_StopLevel = 0; //================================================================== // SECTION 4: CLASSES & DATA STRUCTURES //================================================================== //--- SEKANAS MANAGER --- class CSekanasManager { private: double m_contract_size; public: void Init() { m_contract_size = MarketInfo(Symbol(), MODE_LOTSIZE); } int ToPoints(double sekanas) { if(sekanas <= 0) return 0; double price = (Ask + Bid) / 2.0; double val = (sekanas * (price * 0.0001)) / Point; return (int)val; } double ToPriceDelta(double sekanas) { if(sekanas <= 0) return 0.0; double price = (Ask + Bid) / 2.0; return sekanas * (price * 0.0001); } double ToMoney(double sekanas, double volume) { if(sekanas <= 0 || volume <= 0) return 0.0; return ToPriceDelta(sekanas) * m_contract_size * volume; } double MoneyToSekanas(double money, double volume) { if(volume <= 0) return 0.0; double price = (Ask + Bid) / 2.0; double oneSekanasVal = (price * 0.0001) * m_contract_size * volume; return (oneSekanasVal == 0) ? 0 : money / oneSekanasVal; } }; CSekanasManager g_sekanas; //--- MARKET STATISTICS --- struct MarketStats { int buyCount, sellCount, buyStopCount, sellStopCount; double buyLots, sellLots, buyProfit, sellProfit, dailyProfit; double highestBuyPrice, lowestBuyPrice, highestSellPrice, lowestSellPrice; double buyWeightedPriceSum, sellWeightedPriceSum; int buyStopTicket, sellStopTicket; double buyStopPrice, sellStopPrice; void Reset() { buyCount = 0; sellCount = 0; buyStopCount = 0; sellStopCount = 0; buyLots = 0; sellLots = 0; buyProfit = 0; sellProfit = 0; dailyProfit = 0; highestBuyPrice = 0; lowestBuyPrice = 0; highestSellPrice = 0; lowestSellPrice = 0; buyWeightedPriceSum = 0; sellWeightedPriceSum = 0; buyStopTicket = 0; sellStopTicket = 0; buyStopPrice = 0; sellStopPrice = 0; } }; class CGridStats { private: double CalculateDailyProfit() { double profit = 0.0; int historyTotal = OrdersHistoryTotal(); datetime startOfDay = iTime(Symbol(), PERIOD_D1, 0); for(int i = 0; i < historyTotal; i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic) { if(OrderCloseTime() >= startOfDay) { if(OrderType() <= OP_SELL) // Only closed trades { profit += OrderProfit() + OrderCommission() + OrderSwap(); } } } } } return profit; } public: MarketStats stats; void Update() { stats.Reset(); stats.dailyProfit = CalculateDailyProfit(); int total = OrdersTotal(); for(int i = 0; i < total; i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() != Symbol() || OrderMagicNumber() != InpMagic) continue; int type = OrderType(); double volume = OrderLots(); double priceOpen = OrderOpenPrice(); // Active Positions if(type == OP_BUY) { double profit = OrderProfit() + OrderSwap() + OrderCommission(); stats.buyCount++; stats.buyLots += volume; stats.buyProfit += profit; stats.buyWeightedPriceSum += priceOpen * volume; if(priceOpen > stats.highestBuyPrice || stats.highestBuyPrice == 0) stats.highestBuyPrice = priceOpen; if(priceOpen < stats.lowestBuyPrice || stats.lowestBuyPrice == 0) stats.lowestBuyPrice = priceOpen; } else if(type == OP_SELL) { double profit = OrderProfit() + OrderSwap() + OrderCommission(); stats.sellCount++; stats.sellLots += volume; stats.sellProfit += profit; stats.sellWeightedPriceSum += priceOpen * volume; if(priceOpen > stats.highestSellPrice || stats.highestSellPrice == 0) stats.highestSellPrice = priceOpen; if(priceOpen < stats.lowestSellPrice || stats.lowestSellPrice == 0) stats.lowestSellPrice = priceOpen; } // Pending Orders else if(type == OP_BUYSTOP) { stats.buyStopCount++; stats.buyStopTicket = OrderTicket(); stats.buyStopPrice = priceOpen; if(priceOpen > stats.highestBuyPrice || stats.highestBuyPrice == 0) stats.highestBuyPrice = priceOpen; } else if(type == OP_SELLSTOP) { stats.sellStopCount++; stats.sellStopTicket = OrderTicket(); stats.sellStopPrice = priceOpen; if(priceOpen < stats.highestSellPrice || stats.highestSellPrice == 0) stats.highestSellPrice = priceOpen; } } } } }; //--- TRAILING STOP LOGIC --- class CTrailing { public: double CalculateLevel(int direction, double currentPrice) { if(!InpUseTrailing) return 0.0; double trailPoints = g_sekanas.ToPriceDelta(InpTrailingStep); return (direction == 1) ? NormalizeDouble(currentPrice - trailPoints, Digits) : NormalizeDouble(currentPrice + trailPoints, Digits); } }; //--- DISPLAY PANEL --- class CDisplay { public: void Init() { CreateRect("Bg", InpPanelX, InpPanelY, PANEL_W, PANEL_H, COLOR_BG, BORDER_FLAT); CreateLabel("Header", "SEKANAS GOLD 1.07", InpPanelX + 15, InpPanelY + 10, COLOR_ACCENT, 11, true); CreateLabel("Ver", "v1.07", InpPanelX + PANEL_W - 40, InpPanelY + 12, clrGray, 7); int y = InpPanelY + 40; int xLeft = InpPanelX + 15, xRight = InpPanelX + PANEL_W - 15; CreateRect("P_Bal", InpPanelX + 10, y, PANEL_W - 20, 45, COLOR_PANE); CreateLabel("L_DP", "DAILY PROFIT", xLeft, y+5, clrSilver, 8); CreateLabel("V_DP", "0.00 $", xRight, y+5, COLOR_TXT, 10, true, ANCHOR_RIGHT_UPPER); CreateLabel("L_Bal", "Balance:", xLeft, y+25, clrGray, 7); CreateLabel("V_Bal", "0", xLeft + 50, y+25, clrSilver, 7); y += 55; int wHalf = (PANEL_W - 25) / 2; CreateRect("P_Mkt1", InpPanelX + 10, y, wHalf, 40, COLOR_PANE); CreateRect("P_Mkt2", InpPanelX + 10 + wHalf + 5, y, wHalf, 40, COLOR_PANE); CreateLabel("L_Spr", "SPREAD", xLeft, y+5, clrSilver, 7); CreateLabel("V_Spr", "0", xLeft, y+20, COLOR_ACCENT, 10, true); CreateLabel("L_Dir", "DIRECTION", InpPanelX + 10 + wHalf + 10, y+5, clrSilver, 7); CreateLabel("V_Dir", "NEUTRAL", InpPanelX + 10 + wHalf + 10, y+20, clrWhite, 9, true); y += 50; CreateRect("P_Vol", InpPanelX + 10, y, PANEL_W - 20, 50, COLOR_PANE); CreateLabel("L_BuyV", "BUY LOTS", xLeft, y+5, clrSkyBlue, 8); CreateLabel("V_BuyV", "0.00", xLeft, y+25, clrWhite, 10, true); CreateLabel("V_BuyC", "(0)", xLeft + 60, y+27, clrGray, 7); CreateLabel("L_SelV", "SELL LOTS", xRight, y+5, clrTomato, 8, false, ANCHOR_RIGHT_UPPER); CreateLabel("V_SelV", "0.00", xRight, y+25, clrWhite, 10, true, ANCHOR_RIGHT_UPPER); CreateLabel("V_SelC", "(0)", xRight - 60, y+27, clrGray, 7, false, ANCHOR_RIGHT_UPPER); y += 60; CreateRect("P_PL", InpPanelX + 10, y, PANEL_W - 20, 45, COLOR_PANE); CreateLabel("L_PL", "CURRENT P/L", InpPanelX + (PANEL_W/2), y+5, clrSilver, 8, false, ANCHOR_UPPER); CreateLabel("V_PL", "0.00 $", InpPanelX + (PANEL_W/2), y+20, clrWhite, 14, true, ANCHOR_UPPER); CreateLabel("L_St", "System Active", InpPanelX + (PANEL_W/2), InpPanelY + PANEL_H - 20, clrGray, 7, false, ANCHOR_CENTER); } void Update(const MarketStats &stats, double balance, double rsiValue) { ObjectSetString(0, g_PanelPrefix + "V_DP", OBJPROP_TEXT, DoubleToString(stats.dailyProfit, 2) + " $"); ObjectSetInteger(0, g_PanelPrefix + "V_DP", OBJPROP_COLOR, (stats.dailyProfit >= 0) ? COLOR_PROFIT : COLOR_LOSS); ObjectSetString(0, g_PanelPrefix + "V_Bal", OBJPROP_TEXT, DoubleToString(balance, 2)); ObjectSetString(0, g_PanelPrefix + "V_Spr", OBJPROP_TEXT, IntegerToString((int)MarketInfo(Symbol(), MODE_SPREAD))); string dirTxt = "RANGE"; color dirCol = clrGray; if(stats.buyLots > stats.sellLots) { dirTxt = "UP TREND"; dirCol = clrSkyBlue; } else if(stats.sellLots > stats.buyLots) { dirTxt = "DOWN TREND"; dirCol = clrTomato; } else { if(rsiValue < 30) { dirTxt = "OVERSOLD"; dirCol = clrLime; } else if(rsiValue > 70) { dirTxt = "OVERBOUGHT"; dirCol = clrOrange; } } ObjectSetString(0, g_PanelPrefix + "V_Dir", OBJPROP_TEXT, dirTxt); ObjectSetInteger(0, g_PanelPrefix + "V_Dir", OBJPROP_COLOR, dirCol); ObjectSetString(0, g_PanelPrefix + "V_BuyV", OBJPROP_TEXT, DoubleToString(stats.buyLots, 2)); ObjectSetString(0, g_PanelPrefix + "V_BuyC", OBJPROP_TEXT, "(" + IntegerToString(stats.buyCount) + ")"); ObjectSetString(0, g_PanelPrefix + "V_SelV", OBJPROP_TEXT, DoubleToString(stats.sellLots, 2)); ObjectSetString(0, g_PanelPrefix + "V_SelC", OBJPROP_TEXT, "(" + IntegerToString(stats.sellCount) + ")"); double totalPL = stats.buyProfit + stats.sellProfit; ObjectSetString(0, g_PanelPrefix + "V_PL", OBJPROP_TEXT, (totalPL > 0 ? "+" : "") + DoubleToString(totalPL, 2) + " $"); ObjectSetInteger(0, g_PanelPrefix + "V_PL", OBJPROP_COLOR, (totalPL >= 0) ? COLOR_PROFIT : COLOR_LOSS); UpdateBreakevenLines(stats); } private: void CreateRect(string name, int x, int y, int w, int h, color c, int border=BORDER_FLAT) { string objName = g_PanelPrefix + name; if(ObjectFind(objName) < 0) ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, objName, OBJPROP_XSIZE, w); ObjectSetInteger(0, objName, OBJPROP_YSIZE, h); ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, c); ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, border); ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, objName, OBJPROP_BACK, false); } void CreateLabel(string name, string text, int x, int y, color c, int size=9, bool bold=false, int anchor=ANCHOR_LEFT_UPPER) { string objName = g_PanelPrefix + name; if(ObjectFind(objName) < 0) ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, y); ObjectSetString(0, objName, OBJPROP_TEXT, text); ObjectSetInteger(0, objName, OBJPROP_COLOR, c); ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, size); ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, objName, OBJPROP_ANCHOR, anchor); ObjectSetString(0, objName, OBJPROP_FONT, bold ? "Calibri Bold" : "Calibri"); } void UpdateBreakevenLines(const MarketStats &stats) { if(stats.buyCount > 0 && stats.buyLots > 0) UpdateLine("SLb", NormalizeDouble(stats.buyWeightedPriceSum / stats.buyLots, Digits), 220, clrSkyBlue); else ObjectDelete("SLb"); if(stats.sellCount > 0 && stats.sellLots > 0) UpdateLine("SLs", NormalizeDouble(stats.sellWeightedPriceSum / stats.sellLots, Digits), 220, clrTomato); else ObjectDelete("SLs"); } void UpdateLine(string name, double price, int code, color col) { if(ObjectFind(name) < 0) { ObjectCreate(0, name, OBJ_ARROW, 0, TimeCurrent(), price); ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code); ObjectSetInteger(0, name, OBJPROP_COLOR, col); } else { ObjectMove(0, name, 0, TimeCurrent(), price); } } }; //================================================================== // SECTION 5: HELPER FUNCTIONS //================================================================== bool CheckLicenseValidity() { if(TimeCurrent() >= D'2026.05.01 00:00:00') { Alert("License Expired!"); return false; } return true; } bool IsTradingHours() { if(InpStartHour == 0 && InpEndHour == 24) return true; int h = TimeHour(TimeCurrent()); if(h == 0) h = 24; return (InpStartHour < InpEndHour) ? (h >= InpStartHour && h < InpEndHour) : (h >= InpStartHour || h < InpEndHour); } //--- Execution Wrappers to mimic CTrade simplicity bool ExecuteOrder(int type, double volume, double price, string comment) { int ticket = OrderSend(Symbol(), type, volume, price, 30, 0, 0, comment, InpMagic, 0, clrNONE); if(ticket < 0) { Print("OrderSend Failed: ", ErrorDescription(GetLastError())); return false; } return true; } bool ModifyOrderSafe(int ticket, double price, double sl, double tp) { if(OrderSelect(ticket, SELECT_BY_TICKET)) { if(MathAbs(OrderOpenPrice()-price) < Point && MathAbs(OrderStopLoss()-sl) < Point && MathAbs(OrderTakeProfit()-tp) < Point) return true; bool res = OrderModify(ticket, price, sl, tp, 0, clrNONE); if(!res) Print("OrderModify Failed: ", ErrorDescription(GetLastError())); return res; } return false; } CGridStats g_stats; CDisplay g_display; CTrailing g_trailing; //================================================================== // SECTION 6: MAIN EVENT HANDLERS //================================================================== int init() { if(!CheckLicenseValidity()) return(INIT_FAILED); g_sekanas.Init(); g_StopLevel = (int)MarketInfo(Symbol(), MODE_STOPLEVEL); g_TickValue = MarketInfo(Symbol(), MODE_TICKVALUE); g_Point = Point; if(InpDistBetweenOrders <= 0) Alert("Sekanas Distance must be > 0"); g_display.Init(); Print("Program Started: ", WindowExpertName()); return(INIT_SUCCEEDED); } void deinit() { ObjectsDeleteAll(0, g_PanelPrefix); ObjectsDeleteAll(0, "SLb"); ObjectsDeleteAll(0, "SLs"); Print("Program Stopped."); } int start() { // 1. Time based logic (Order deletion) datetime now = TimeCurrent(); int currentHour = TimeHour(now); if(InpDeleteOrders && currentHour == InpDeleteHour) { if(g_lastDeleteTime < (now - (now % 3600))) { DeletePendingOrders(0); g_lastDeleteTime = now; } } // 2. Update Stats g_stats.Update(); // 3. Logic Execution ManagePositions(); CheckProfitLossClosing(); // 4. Indicator Calculation double rsiVal = iRSI(NULL, InpTimeframeInd, InpRsiPeriod, PRICE_CLOSE, 0); ManageBuyEntry(rsiVal); ManageSellEntry(rsiVal); // 5. UI Update g_display.Update(g_stats.stats, AccountBalance(), rsiVal); return(0); } //================================================================== // SECTION 7: STRATEGY LOGIC & TRADE MANAGEMENT //================================================================== void ManagePositions() { int total = OrdersTotal(); for(int i = 0; i < total; i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() != Symbol() || OrderMagicNumber() != InpMagic) continue; int type = OrderType(); int ticket = OrderTicket(); double sl = OrderStopLoss(); double tp = OrderTakeProfit(); double openPrice = OrderOpenPrice(); double newSL = sl, newTP = tp; double fixedSLPoints = (InpFixedSL > 0) ? g_sekanas.ToPriceDelta(InpFixedSL) : 0; double fixedTPPoints = (InpFixedTP > 0) ? g_sekanas.ToPriceDelta(InpFixedTP) : 0; if(type == OP_BUY) { double calcSL = (fixedSLPoints > 0) ? openPrice - fixedSLPoints : sl; double calcTP = (fixedTPPoints > 0) ? openPrice + fixedTPPoints : tp; if(MathAbs(calcSL - sl) > Point || MathAbs(calcTP - tp) > Point) { if(ModifyOrderSafe(ticket, openPrice, NormalizeDouble(calcSL, Digits), NormalizeDouble(calcTP, Digits))) newSL = calcSL; } if(InpUseTrailing) { double level = g_trailing.CalculateLevel(1, Bid); double avgPrice = (g_stats.stats.buyLots > 0) ? g_stats.stats.buyWeightedPriceSum / g_stats.stats.buyLots : 0; if(level >= avgPrice + g_sekanas.ToPriceDelta(InpMinTrailingProfit) && level > newSL + g_sekanas.ToPriceDelta(InpTrailingStep)) { if((Bid - level) > g_StopLevel * Point) ModifyOrderSafe(ticket, openPrice, level, tp); } } } else if(type == OP_SELL) { double calcSL = (fixedSLPoints > 0) ? openPrice + fixedSLPoints : sl; double calcTP = (fixedTPPoints > 0) ? openPrice - fixedTPPoints : tp; if(MathAbs(calcSL - sl) > Point || MathAbs(calcTP - tp) > Point) { if(ModifyOrderSafe(ticket, openPrice, NormalizeDouble(calcSL, Digits), NormalizeDouble(calcTP, Digits))) newSL = calcSL; } if(InpUseTrailing) { double level = g_trailing.CalculateLevel(-1, Ask); double avgPrice = (g_stats.stats.sellLots > 0) ? g_stats.stats.sellWeightedPriceSum / g_stats.stats.sellLots : 0; if(level <= avgPrice - g_sekanas.ToPriceDelta(InpMinTrailingProfit) && (newSL == 0 || level < newSL - g_sekanas.ToPriceDelta(InpTrailingStep))) { if((level - Ask) > g_StopLevel * Point) ModifyOrderSafe(ticket, openPrice, level, tp); } } } } } } void CheckProfitLossClosing() { double netCloseDDMoney = -1.0 * g_sekanas.ToMoney(InpCloseLossByDD, (g_stats.stats.buyLots + g_stats.stats.sellLots)); double closeLossMoney = -1.0 * g_sekanas.ToMoney(InpLossForClosing, (g_stats.stats.buyLots + g_stats.stats.sellLots)); double autoProfitBuy = 0, autoProfitSell = 0; if(InpAutoCalcProfit > 0) { autoProfitBuy = g_sekanas.ToMoney(InpAutoCalcProfit, (g_stats.stats.buyLots > 0 ? g_stats.stats.buyLots : InpOrderLotsize)); autoProfitSell = g_sekanas.ToMoney(InpAutoCalcProfit, (g_stats.stats.sellLots > 0 ? g_stats.stats.sellLots : InpOrderLotsize)); } else { autoProfitBuy = g_sekanas.ToMoney(InpProfitClose1Dir, g_stats.stats.buyLots); autoProfitSell = g_sekanas.ToMoney(InpProfitClose1Dir, g_stats.stats.sellLots); } double profit2DirMoney = g_sekanas.ToMoney(InpProfitClose2Dir, g_stats.stats.buyLots + g_stats.stats.sellLots); if(g_stats.stats.buyProfit > netCloseDDMoney && g_stats.stats.sellProfit > netCloseDDMoney) { if(g_stats.stats.buyProfit >= autoProfitBuy && g_stats.stats.buyLots > 0) CloseAll(1); if(g_stats.stats.sellProfit >= autoProfitSell && g_stats.stats.sellLots > 0) CloseAll(-1); } else { if((g_stats.stats.buyProfit + g_stats.stats.sellProfit >= profit2DirMoney) && profit2DirMoney > 0) CloseAll(0); } if(g_stats.stats.buyProfit <= closeLossMoney && g_stats.stats.buyLots > 0) CloseAll(1); if(g_stats.stats.sellProfit <= closeLossMoney && g_stats.stats.sellLots > 0) CloseAll(-1); } void ManageBuyEntry(double rsiVal) { if(!InpAllowBuy) return; double maxLossMoney = g_sekanas.ToMoney(InpMaxAllowedLoss, g_stats.stats.buyLots); if(g_stats.stats.buyProfit <= -1.0 * maxLossMoney && g_stats.stats.buyLots > 0) return; double firstStepPrice = g_sekanas.ToPriceDelta(InpFirstStep); double minPriceDist = g_sekanas.ToPriceDelta(InpMinPriceDist); double distOrders = g_sekanas.ToPriceDelta(InpDistBetweenOrders); if(g_stats.stats.buyStopCount == 0) { double entryPrice = 0; if(g_stats.stats.buyCount == 0) { if(rsiVal < InpOversoldZone || !InpUseIndEntry) entryPrice = NormalizeDouble(Ask + firstStepPrice, Digits); } else { entryPrice = NormalizeDouble(Ask + minPriceDist, Digits); if(entryPrice < NormalizeDouble(g_stats.stats.lowestBuyPrice - distOrders, Digits)) entryPrice = NormalizeDouble(Ask + distOrders, Digits); } bool trendCond = (g_stats.stats.buyCount == 0) || (g_stats.stats.highestBuyPrice != 0 && entryPrice >= NormalizeDouble(g_stats.stats.highestBuyPrice + distOrders, Digits) && InpOpenOrderOnTrend) || (g_stats.stats.lowestBuyPrice != 0 && entryPrice <= NormalizeDouble(g_stats.stats.lowestBuyPrice - distOrders, Digits)); if(entryPrice != 0 && trendCond) { double lot = (g_stats.stats.buyCount == 0) ? InpOrderLotsize : NormalizeDouble(InpOrderLotsize * MathPow(InpMultiplyLotsizeBy, g_stats.stats.buyCount) + g_stats.stats.buyCount * InpIncreaseLotsizeBy, InpRoundLotDecimals); if(IsTradingHours() && (InpEAMakesFirstOrder || g_stats.stats.buyCount > 0)) { static datetime lastOrderTime = 0; if(TimeCurrent() - lastOrderTime < InpOrderTimeGap) return; if(ExecuteOrder(OP_BUYSTOP, lot, entryPrice, EA_COMMENT_TAG)) lastOrderTime = TimeCurrent(); } } } else if(g_stats.stats.buyStopTicket > 0) { double targetPrice = (g_stats.stats.buyCount == 0) ? NormalizeDouble(Ask + firstStepPrice, Digits) : NormalizeDouble(Ask + minPriceDist, Digits); double currentPending = g_stats.stats.buyStopPrice; if(NormalizeDouble(currentPending - g_sekanas.ToPriceDelta(InpMoveStep), Digits) > targetPrice) { double distCheckLow = (g_stats.stats.lowestBuyPrice != 0) ? NormalizeDouble(g_stats.stats.lowestBuyPrice - distOrders, Digits) : 999999; if(targetPrice <= distCheckLow) { if(MathAbs(currentPending - targetPrice) < g_sekanas.ToPriceDelta(InpModifyThreshold)) return; static datetime lastModifyTime = 0; if(TimeCurrent() - lastModifyTime < InpOrderTimeGap) return; if(ModifyOrderSafe(g_stats.stats.buyStopTicket, targetPrice, 0, 0)) lastModifyTime = TimeCurrent(); } } } } void ManageSellEntry(double rsiVal) { if(!InpAllowSell) return; double maxLossMoney = g_sekanas.ToMoney(InpMaxAllowedLoss, g_stats.stats.sellLots); if(g_stats.stats.sellProfit <= -1.0 * maxLossMoney && g_stats.stats.sellLots > 0) return; double firstStepPrice = g_sekanas.ToPriceDelta(InpFirstStep); double minPriceDist = g_sekanas.ToPriceDelta(InpMinPriceDist); double distOrders = g_sekanas.ToPriceDelta(InpDistBetweenOrders); if(g_stats.stats.sellStopCount == 0) { double entryPrice = 0; if(g_stats.stats.sellCount == 0) { if(rsiVal > InpOverboughtZone || !InpUseIndEntry) entryPrice = NormalizeDouble(Bid - firstStepPrice, Digits); } else { entryPrice = NormalizeDouble(Bid - minPriceDist, Digits); if(entryPrice < NormalizeDouble(g_stats.stats.lowestSellPrice + distOrders, Digits)) entryPrice = NormalizeDouble(Bid - distOrders, Digits); } bool trendCond = (g_stats.stats.sellCount == 0) || (g_stats.stats.highestSellPrice != 0 && entryPrice <= NormalizeDouble(g_stats.stats.highestSellPrice - distOrders, Digits) && InpOpenOrderOnTrend) || (g_stats.stats.lowestSellPrice != 0 && entryPrice >= NormalizeDouble(g_stats.stats.lowestSellPrice + distOrders, Digits)); if(entryPrice != 0 && trendCond) { double lot = (g_stats.stats.sellCount == 0) ? InpOrderLotsize : NormalizeDouble(InpOrderLotsize * MathPow(InpMultiplyLotsizeBy, g_stats.stats.sellCount) + g_stats.stats.sellCount * InpIncreaseLotsizeBy, InpRoundLotDecimals); if(IsTradingHours() && (InpEAMakesFirstOrder || g_stats.stats.sellCount > 0)) { if(ExecuteOrder(OP_SELLSTOP, lot, entryPrice, EA_COMMENT_TAG)) {} } } } else if(g_stats.stats.sellStopTicket > 0) { double targetPrice = (g_stats.stats.sellCount == 0) ? NormalizeDouble(Bid - firstStepPrice, Digits) : NormalizeDouble(Bid - minPriceDist, Digits); double currentPending = g_stats.stats.sellStopPrice; if(NormalizeDouble(currentPending + g_sekanas.ToPriceDelta(InpMoveStep), Digits) < targetPrice) { double distCheckHigh = (g_stats.stats.lowestSellPrice != 0) ? NormalizeDouble(g_stats.stats.lowestSellPrice + distOrders, Digits) : 0; if(targetPrice >= distCheckHigh) { if(MathAbs(currentPending - targetPrice) < g_sekanas.ToPriceDelta(InpModifyThreshold)) return; static datetime lastModifyTime = 0; if(TimeCurrent() - lastModifyTime < InpOrderTimeGap) return; if(ModifyOrderSafe(g_stats.stats.sellStopTicket, targetPrice, 0, 0)) lastModifyTime = TimeCurrent(); } } } } void CloseAll(int direction) { int total = OrdersTotal(); for(int i = total - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic) { int type = OrderType(); // Close Positions if(type <= OP_SELL) { if(direction == 0 || (direction == 1 && type == OP_BUY) || (direction == -1 && type == OP_SELL)) { // 1. Fiyatları güncelle (Döngü içinde kritik öneme sahiptir) RefreshRates(); // 2. Kapanış fiyatını belirle double closePrice = (OrderType() == OP_BUY) ? Bid : Ask; // 3. İşlem sonucunu bir değişkene ata (Hata düzeltmesi buradadır) bool result = OrderClose(OrderTicket(), OrderLots(), closePrice, 30, clrGray); // 4. Eğer kapanmazsa hatayı yazdır if(!result) Print("Kapanış Başarısız. Hata Kodu: ", GetLastError()); } } } } } DeletePendingOrders(direction); } void DeletePendingOrders(int direction) { int total = OrdersTotal(); for(int i = total - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagic) { int type = OrderType(); // Bekleyen Emirleri (Pending) Silme İşlemi if(type > OP_SELL) { bool isBuy = (type == OP_BUYSTOP || type == OP_BUYLIMIT); bool isSell = (type == OP_SELLSTOP || type == OP_SELLLIMIT); if(direction == 0 || (direction == 1 && isBuy) || (direction == -1 && isSell)) { // HATA DÜZELTME: Dönüş değeri 'res' değişkenine atanıp kontrol ediliyor bool res = OrderDelete(OrderTicket()); // Eğer silinemezse günlüğe hata yazdır if(!res) Print("Bekleyen emir silinemedi. Hata Kodu: ", GetLastError()); } } } } } } //+------------------------------------------------------------------+