--- applyTo: "**/MQL4/Scripts/_Thivyam/**/*.mq4" --- # Instructions for _Thivyam MQL4 Scripts ## CRITICAL: MQL4 Syntax Compliance **Before writing any MQL4 code, read and follow:** `mql4-syntax-critical.instructions.md` Key mandatory rules for scripts: - Declare loop variables BEFORE for-loop: `int i; for(i=0; i 0) message += " with Magic Number " + IntegerToString(InpMagicNumber); message += "?"; int result = MessageBox(message, "Confirm Close All", MB_YESNO | MB_ICONWARNING); if(result != IDYES) { Print("Operation cancelled"); return; } } // Close all orders (iterate backwards) int total = OrdersTotal(); int i; for(i = total - 1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; // Filter by symbol if(OrderSymbol() != Symbol()) continue; // Filter by magic number if(InpMagicNumber > 0 && OrderMagicNumber() != InpMagicNumber) continue; bool closed = false; int ticket = OrderTicket(); if(OrderType() == OP_BUY) { closed = OrderClose(ticket, OrderLots(), Bid, 3, clrRed); } else if(OrderType() == OP_SELL) { closed = OrderClose(ticket, OrderLots(), Ask, 3, clrRed); } else // Pending orders { closed = OrderDelete(ticket, clrRed); } if(closed) { totalClosed++; Print("Closed ticket #", ticket); } else { totalFailed++; int error = GetLastError(); Print("Failed to close ticket #", ticket, " Error: ", error); } } // Report results string message = "Closed: " + IntegerToString(totalClosed); if(totalFailed > 0) message += " | Failed: " + IntegerToString(totalFailed); Print(message); MessageBox(message, "Close All Complete", MB_OK | MB_ICONINFORMATION); } int CountOrders(int magicNumber) { int count = 0; int total = OrdersTotal(); int i; for(i = 0; i < total; i++) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderSymbol() != Symbol()) continue; if(magicNumber > 0 && OrderMagicNumber() != magicNumber) continue; count++; } return count; } ``` --- ### 2. Delete All Objects Script ```mql4 #property show_inputs input bool InpConfirm = true; // Ask confirmation input string InpPrefix = ""; // Object prefix (empty = all) void OnStart() { int totalDeleted = 0; // Count objects int totalObjects = ObjectsTotal(0); if(totalObjects == 0) { Print("No objects to delete"); return; } // Ask confirmation if(InpConfirm) { string message = "Delete " + IntegerToString(totalObjects) + " chart objects"; if(InpPrefix != "") message += " with prefix '" + InpPrefix + "'"; message += "?"; int result = MessageBox(message, "Confirm Delete All", MB_YESNO | MB_ICONWARNING); if(result != IDYES) { Print("Operation cancelled"); return; } } // Delete all objects (iterate backwards) int i; for(i = totalObjects - 1; i >= 0; i--) { string objName = ObjectName(0, i); // Filter by prefix if specified if(InpPrefix != "") { if(StringFind(objName, InpPrefix) != 0) continue; } if(ObjectDelete(0, objName)) { totalDeleted++; } } // Redraw chart ChartRedraw(0); Print("Deleted ", totalDeleted, " objects"); MessageBox("Deleted " + IntegerToString(totalDeleted) + " objects", "Delete Complete", MB_OK | MB_ICONINFORMATION); } ``` --- ### 3. Modify All Orders Script ```mql4 #property show_inputs input int InpMagicNumber = 0; // Magic Number (0 = all) input int InpNewStopLossPips = 0; // New SL in pips (0 = no change) input int InpNewTakeProfitPips = 0; // New TP in pips (0 = no change) input bool InpConfirm = true; // Ask confirmation void OnStart() { if(InpNewStopLossPips == 0 && InpNewTakeProfitPips == 0) { Print("ERROR: No modification specified"); MessageBox("Please specify SL or TP modification", "Error", MB_OK | MB_ICONERROR); return; } int totalModified = 0; int totalFailed = 0; // Count orders int totalOrders = CountOrders(InpMagicNumber); if(totalOrders == 0) { Print("No orders to modify"); return; } // Ask confirmation if(InpConfirm) { string message = "Modify " + IntegerToString(totalOrders) + " orders?"; if(InpNewStopLossPips > 0) message += "\nNew SL: " + IntegerToString(InpNewStopLossPips) + " pips"; if(InpNewTakeProfitPips > 0) message += "\nNew TP: " + IntegerToString(InpNewTakeProfitPips) + " pips"; int result = MessageBox(message, "Confirm Modify All", MB_YESNO | MB_ICONQUESTION); if(result != IDYES) { Print("Operation cancelled"); return; } } // Modify all orders int total = OrdersTotal(); int i; for(i = 0; i < total; i++) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderSymbol() != Symbol()) continue; if(InpMagicNumber > 0 && OrderMagicNumber() != InpMagicNumber) continue; // Only modify market positions if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue; int ticket = OrderTicket(); double openPrice = OrderOpenPrice(); double newSL = OrderStopLoss(); double newTP = OrderTakeProfit(); // Calculate new SL if(InpNewStopLossPips > 0) { if(OrderType() == OP_BUY) newSL = openPrice - InpNewStopLossPips * Point * 10; else newSL = openPrice + InpNewStopLossPips * Point * 10; newSL = NormalizeDouble(newSL, Digits); } // Calculate new TP if(InpNewTakeProfitPips > 0) { if(OrderType() == OP_BUY) newTP = openPrice + InpNewTakeProfitPips * Point * 10; else newTP = openPrice - InpNewTakeProfitPips * Point * 10; newTP = NormalizeDouble(newTP, Digits); } // Modify order bool modified = OrderModify(ticket, openPrice, newSL, newTP, 0, clrBlue); if(modified) { totalModified++; Print("Modified ticket #", ticket, " SL: ", newSL, " TP: ", newTP); } else { totalFailed++; int error = GetLastError(); Print("Failed to modify ticket #", ticket, " Error: ", error); } } // Report results string message = "Modified: " + IntegerToString(totalModified); if(totalFailed > 0) message += " | Failed: " + IntegerToString(totalFailed); Print(message); MessageBox(message, "Modify Complete", MB_OK | MB_ICONINFORMATION); } int CountOrders(int magicNumber) { int count = 0; int total = OrdersTotal(); int i; for(i = 0; i < total; i++) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderSymbol() != Symbol()) continue; if(magicNumber > 0 && OrderMagicNumber() != magicNumber) continue; if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue; count++; } return count; } ``` --- ### 4. Account Information Script ```mql4 void OnStart() { string info = ""; info += "========================================\n"; info += "ACCOUNT INFORMATION\n"; info += "========================================\n\n"; info += "Account Number: " + IntegerToString(AccountNumber()) + "\n"; info += "Account Name: " + AccountName() + "\n"; info += "Account Server: " + AccountServer() + "\n"; info += "Account Company: " + AccountCompany() + "\n"; info += "Account Currency: " + AccountCurrency() + "\n"; info += "Account Leverage: 1:" + IntegerToString(AccountLeverage()) + "\n\n"; info += "Balance: " + DoubleToString(AccountBalance(), 2) + "\n"; info += "Equity: " + DoubleToString(AccountEquity(), 2) + "\n"; info += "Margin: " + DoubleToString(AccountMargin(), 2) + "\n"; info += "Free Margin: " + DoubleToString(AccountFreeMargin(), 2) + "\n"; info += "Margin Level: " + DoubleToString(AccountMargin() > 0 ? (AccountEquity() / AccountMargin() * 100) : 0, 2) + "%\n\n"; info += "Profit: " + DoubleToString(AccountProfit(), 2) + "\n"; info += "Credit: " + DoubleToString(AccountCredit(), 2) + "\n\n"; info += "Open Positions: " + IntegerToString(CountOpenPositions()) + "\n"; info += "Pending Orders: " + IntegerToString(CountPendingOrders()) + "\n"; info += "========================================\n"; // Print to journal Print(info); // Create file int handle = FileOpen("AccountInfo_" + TimeToString(TimeCurrent(), TIME_DATE) + ".txt", FILE_WRITE | FILE_TXT); if(handle != INVALID_HANDLE) { FileWriteString(handle, info); FileClose(handle); Print("Account info saved to file"); } // Show message MessageBox(info, "Account Information", MB_OK | MB_ICONINFORMATION); } int CountOpenPositions() { int count = 0; int total = OrdersTotal(); int i; for(i = 0; i < total; i++) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderType() == OP_BUY || OrderType() == OP_SELL) count++; } return count; } int CountPendingOrders() { int count = 0; int total = OrdersTotal(); int i; for(i = 0; i < total; i++) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderType() > OP_SELL) count++; // Pending orders } return count; } ``` --- ### 5. Draw Support/Resistance Lines Script ```mql4 #property show_inputs input int InpLookbackBars = 100; // Bars to analyze input int InpMinTouches = 2; // Minimum touches input color InpSupportColor = clrGreen; input color InpResistanceColor = clrRed; void OnStart() { // Delete old lines DeleteOldLines(); // Find support/resistance levels double support[], resistance[]; FindLevels(support, resistance); // Draw support lines int i; for(i = 0; i < ArraySize(support); i++) { DrawHLine("Support_" + IntegerToString(i), support[i], InpSupportColor, STYLE_SOLID); } // Draw resistance lines for(i = 0; i < ArraySize(resistance); i++) { DrawHLine("Resistance_" + IntegerToString(i), resistance[i], InpResistanceColor, STYLE_SOLID); } ChartRedraw(0); Print("Drew ", ArraySize(support), " support and ", ArraySize(resistance), " resistance lines"); } void FindLevels(double &support[], double &resistance[]) { // Simplified logic - find swing highs/lows ArrayResize(support, 0); ArrayResize(resistance, 0); int i; for(i = 2; i < InpLookbackBars - 2; i++) { // Check for swing high (resistance) if(iHigh(Symbol(), PERIOD_CURRENT, i) > iHigh(Symbol(), PERIOD_CURRENT, i-1) && iHigh(Symbol(), PERIOD_CURRENT, i) > iHigh(Symbol(), PERIOD_CURRENT, i-2) && iHigh(Symbol(), PERIOD_CURRENT, i) > iHigh(Symbol(), PERIOD_CURRENT, i+1) && iHigh(Symbol(), PERIOD_CURRENT, i) > iHigh(Symbol(), PERIOD_CURRENT, i+2)) { double level = iHigh(Symbol(), PERIOD_CURRENT, i); AddLevel(resistance, level); } // Check for swing low (support) if(iLow(Symbol(), PERIOD_CURRENT, i) < iLow(Symbol(), PERIOD_CURRENT, i-1) && iLow(Symbol(), PERIOD_CURRENT, i) < iLow(Symbol(), PERIOD_CURRENT, i-2) && iLow(Symbol(), PERIOD_CURRENT, i) < iLow(Symbol(), PERIOD_CURRENT, i+1) && iLow(Symbol(), PERIOD_CURRENT, i) < iLow(Symbol(), PERIOD_CURRENT, i+2)) { double level = iLow(Symbol(), PERIOD_CURRENT, i); AddLevel(support, level); } } } void AddLevel(double &levels[], double price) { int size = ArraySize(levels); ArrayResize(levels, size + 1); levels[size] = NormalizeDouble(price, Digits); } void DrawHLine(string name, double price, color lineColor, int style) { ObjectDelete(0, name); ObjectCreate(0, name, OBJ_HLINE, 0, 0, price); ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); ObjectSetInteger(0, name, OBJPROP_STYLE, style); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); ObjectSetInteger(0, name, OBJPROP_SELECTABLE, true); } void DeleteOldLines() { int total = ObjectsTotal(0); int i; for(i = total - 1; i >= 0; i--) { string name = ObjectName(0, i); if(StringFind(name, "Support_") == 0 || StringFind(name, "Resistance_") == 0) { ObjectDelete(0, name); } } } ``` --- ## Best Practices for Scripts ### 1. User Confirmation Always ask for confirmation before destructive operations: ```mql4 if(InpConfirm) { int result = MessageBox("Are you sure?", "Confirm", MB_YESNO | MB_ICONWARNING); if(result != IDYES) return; } ``` ### 2. Progress Reporting Report progress for long operations: ```mql4 int total = 1000; int i; for(i = 0; i < total; i++) { if(i % 100 == 0) { Comment("Processing: ", (i * 100 / total), "%"); } // Process... } Comment(""); // Clear comment ``` ### 3. Error Handling Handle errors gracefully: ```mql4 bool success = OrderClose(ticket, lots, price, slippage); if(!success) { int error = GetLastError(); Print("Error closing order: ", error, " - ", ErrorDescription(error)); // Continue or abort? } ``` ### 4. File Operations Save results to files when appropriate: ```mql4 int handle = FileOpen("results.csv", FILE_WRITE | FILE_CSV); if(handle != INVALID_HANDLE) { FileWrite(handle, "Date", "Value"); // Write data... FileClose(handle); Print("Results saved to files folder"); } ``` --- ## Summary: MQL4 Script Best Practices 1. ✅ Use `OnStart()` function (executes once) 2. ✅ Set `#property show_inputs` to show input dialog 3. ✅ Ask confirmation for destructive operations 4. ✅ Report progress for long operations 5. ✅ Handle errors with GetLastError() 6. ✅ Provide clear feedback to user (MessageBox, Print) 7. ✅ Clean up resources (close files, etc.) 8. ✅ Test thoroughly before deployment 9. ✅ Document script functionality clearly 10. ✅ Follow MQL4 syntax rules from critical instructions Scripts are powerful utilities for traders - make them user-friendly and safe!