Expert Advisors • Indicators • Scripts • Libraries

MQL.RobotFX.org is the biggest collection of MetaTrader expert advisors (MT5 & MT4), indicators, scripts and libraries that can be used to improve trading results, minimize risks or simply automate trading tasks

Discover: Metatrader 5 Expert Advisor | KSQ CommandCenter Remote Google Sheets Trade Manager | MQL5 Code

New free code from MQL5: indicators, EAs, and scripts for traders.

Image for KSQ CommandCenter Remote Google Sheets Trade Manager
  • Timeframe: Any (H1 or higher is recommended simply to minimize chart rendering resources on your VPS).

  • External Variables Description

    • GoogleSheetWebAppURL: The deployment URL of your Google Apps Script.

      Experience adaptive trading with the Fluid Expert Advisor for MT4/MT5. Dynamic money management and trend detection. Click for info.

    • SheetPassword: A custom security string to prevent unauthorized POST requests to your sheet. This must match the password in your JavaScript backend.

    • DataPushInterval (Seconds): How frequently the EA sends your live balance and open position data to update the Google Sheet Dashboard.

    • CommandPullInterval (Seconds): How frequently the EA checks the Google Sheet for new pending commands.

    • SlippagePoints: Maximum allowed slippage for remote execution.

    • EnableLogging: Set to true to see detailed two-way communication logs in the MT5 Experts tab.


    ⚠️ CRITICAL SETUP INSTRUCTIONS FOR USERS

    This EA communicates securely with Google servers. MT5 will block it by default unless you explicitly allow the connection.

    Step 1: Whitelist the WebRequest URLs

    1. In MT5, press Ctrl + O (Tools -> Options).

    2. Go to the Expert Advisors tab.

    3. Check the box for "Allow WebRequest for listed URL".

    4. Add these two exact URLs:

    Step 2: Install the Google Sheets Backend (Auto-Setup)

    This EA requires a Google Apps Script to function as the "brain."

    1. Create a blank Google Sheet.

    2. Click Extensions > Apps Script.

    3. Paste the JavaScript code provided at the bottom of this description.

    4. Click Deploy > New Deployment (Select Web App, Execute as "Me", Access: "Anyone").

    5. Copy the Web App URL and paste it into the EA's GoogleSheetWebAppURL input parameter in MT5.

    6. Magic Setup: Within 60 seconds of attaching the EA, the script will automatically format your blank Google Sheet, build the Dashboard, and set up the Commands tab.


    Google Apps Script Backend Code

    // =========================================================================
    // KSQuants Command Center Backend (Auto-Building Version)
    // =========================================================================
    
    const PASSWORD = "Secret"; // MUST match the SheetPassword in your MT5 EA
    
    function doPost(e) {
      try {
        var payload = JSON.parse(e.postData.contents);
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        
        // 0. Auto-Setup: Build tabs and headers if they don't exist
        ensureSetup(ss);
        
        // 1. Authenticate
        if (payload.password !== PASSWORD) {
          return createJsonResponse({ error: "Authentication Failed: Incorrect Password" });
        }
        
        // 2. Route the Request
        if (payload.action === 'status_update') {
          return handleStatusUpdate(payload, ss);
        } 
        else if (payload.action === 'get_commands') {
          return handleGetCommands(payload, ss);
        } 
        else if (payload.action === 'mark_command_done') {
          return handleMarkCommandDone(payload, ss);
        }
        
        return createJsonResponse({ error: "Unknown action requested" });
        
      } catch (error) {
        return createJsonResponse({ error: "Server Error: " + error.message });
      }
    }
    
    // -------------------------------------------------------------------------
    // THE MAGIC: Auto-Build Function
    // -------------------------------------------------------------------------
    function ensureSetup(ss) {
      // 1. Setup Dashboard Tab
      var dashSheet = ss.getSheetByName("Dashboard");
      if (!dashSheet) {
        // Try to rename the default 'Sheet1' instead of making a new one
        var sheet1 = ss.getSheetByName("Sheet1");
        if(sheet1) {
          sheet1.setName("Dashboard");
          dashSheet = sheet1;
        } else {
          dashSheet = ss.insertSheet("Dashboard");
        }
        // Clear it just in case
        dashSheet.clear();
      }
    
      // 2. Setup Commands Tab
      var cmdSheet = ss.getSheetByName("Commands");
      if (!cmdSheet) {
        cmdSheet = ss.insertSheet("Commands");
        
        // Insert the required headers automatically
        var headers = [["Row", "Status", "Account", "Symbol", "Command", "TargetValue", "MT5 Feedback", "Time Completed"]];
        var headerRange = cmdSheet.getRange("A1:H1");
        
        headerRange.setValues(headers);
        headerRange.setFontWeight("bold");
        headerRange.setBackground("#d9ead3"); // Light green background
        
        // Freeze the top row so scrolling is easier
        cmdSheet.setFrozenRows(1);
        
        // Resize columns for better readability
        cmdSheet.setColumnWidth(2, 100); // Status
        cmdSheet.setColumnWidth(5, 150); // Command
        cmdSheet.setColumnWidth(7, 300); // MT5 Feedback
      }
    }
    
    // -------------------------------------------------------------------------
    // ROUTE 1: Handle Status Updates (Push from MT5)
    // -------------------------------------------------------------------------
    function handleStatusUpdate(data, ss) {
      var dashSheet = ss.getSheetByName("Dashboard");
    
      // Update Account Metrics (Top Left)
      var accountData = [
        ["KSQuants Command Center", "Live Data"],
        ["Last Sync", new Date().toLocaleString()],
        ["Account Login", data.account.login],
        ["Balance", "$" + data.account.balance],
        ["Equity", "$" + data.account.equity],
        ["Margin Level", data.account.margin_level + "%"]
      ];
      dashSheet.getRange("A1:B6").setValues(accountData);
      dashSheet.getRange("A1:B1").setFontWeight("bold").setBackground("#d9ead3");
    
      // Update Open Positions (Right Side)
      dashSheet.getRange("D1:H500").clearContent(); 
      
      var headers = ["Ticket", "Symbol", "Type", "Volume", "Profit"];
      dashSheet.getRange("D1:H1").setValues([headers]).setFontWeight("bold").setBackground("#cfe2f3");
    
      if (data.positions && data.positions.length > 0) {
        var posData = data.positions.map(function(p) {
          return [p.ticket, p.symbol, p.type, p.volume, p.profit];
        });
        dashSheet.getRange(2, 4, posData.length, 5).setValues(posData);
      } else {
        dashSheet.getRange("D2").setValue("No Open Positions");
      }
    
      return createJsonResponse({ status: "success", message: "Dashboard updated" });
    }
    
    // -------------------------------------------------------------------------
    // ROUTE 2: Send Pending Commands (Pull from MT5)
    // -------------------------------------------------------------------------
    function handleGetCommands(data, ss) {
      var cmdSheet = ss.getSheetByName("Commands");
      if (cmdSheet.getLastRow() < 2) return createJsonResponse([]); 
    
      var reqAccount = String(data.account);
      var values = cmdSheet.getRange(2, 1, cmdSheet.getLastRow() - 1, 6).getValues();
      var pendingCommands = [];
    
      for (var i = 0; i < values.length; i++) {
        var status = String(values[i][1]).toUpperCase();
        var acc = String(values[i][2]);
    
        if (status === "PENDING" && acc === reqAccount) {
           pendingCommands.push({
             row: i + 2,
             account: acc,
             symbol: String(values[i][3]),
             command: String(values[i][4]).toUpperCase(),
             targetValue: Number(values[i][5]) || 0
           });
        }
      }
      return createJsonResponse(pendingCommands);
    }
    
    // -------------------------------------------------------------------------
    // ROUTE 3: Mark Commands as Done (Acknowledge from MT5)
    // -------------------------------------------------------------------------
    function handleMarkCommandDone(data, ss) {
      var cmdSheet = ss.getSheetByName("Commands");
      var row = data.row;
      var status = data.status;   
      var details = data.details; 
    
      cmdSheet.getRange(row, 2).setValue(status); 
      cmdSheet.getRange(row, 7).setValue(details); 
      cmdSheet.getRange(row, 8).setValue(new Date().toLocaleString()); 
      
      if(status === "SUCCESS") {
         cmdSheet.getRange(row, 2).setBackground("#d9ead3"); 
      } else {
         cmdSheet.getRange(row, 2).setBackground("#f4cccc"); 
      }
    
      return createJsonResponse({ status: "cleared" });
    }
    
    // -------------------------------------------------------------------------
    // Utility Function
    // -------------------------------------------------------------------------
    function createJsonResponse(jsonObject) {
      return ContentService.createTextOutput(JSON.stringify(jsonObject))
        .setMimeType(ContentService.MimeType.JSON);
    }


    Build better strategies with RobotFX professional tools – check them out.

    71591

    Best MetaTrader Indicators + Profitable Expert Advisors