Bharat AI Saathi
ServicesIndustriesSetupsHow we workGuidesFounderVPS HostingContactGlobal (USD)
WhatsApp +91 77352 68199
support@bharataisaathi.com
Mon–Sat 10:00–19:00 IST
Trading & Fintech Tech · Global catalog

How to Automate Google Sheets for Prop Firm Breach Logs

How to automate Google Sheets so MT5 breach alerts land as timestamped rows through a webhook, giving you a full audit trail of near-misses and blocks.

Trading & Fintech Tech

To automate Google Sheets for a trading audit trail, publish an Apps Script web app, point your MT5 breach alerts at its URL as a webhook, and append one timestamped row per event. No copying from the terminal log, no screenshots. Every near-miss, block and hard breach ends up in a sheet you can filter, chart and review later.

Why a sheet beats the terminal log

The MT5 Experts and Journal tabs roll over, get cleared, and live on one machine. If you trade a VPS, a laptop and a phone, the evidence of what yur rules did on Tuesday is scattered. A Google Sheet is the opposite: one place, searchable, shareable with a mentor, and still there after you rebuild the VPS.

In our Prop-Firm Guardian EA setup, the EA is configured to your firm's exact limits: daily loss, max drawdown, news blackout and lot caps. It sends a breach alert whenever one of those rules fires. The webhook step described here sits right after that alert. The EA enforces, the webhook records, and the sheet is where you look afterward to see how close you were running to each limit.

Build your review form free

What the webhook payload looks like

An alert is only useful in a sheet if each field has its own column. Send flat JSON, not a text blob. Here is an illustrative payload; the exact field names get agreed with you during setup.

{
  "event_id": "5012345-20261028-143207-01",
  "account": 5012345,
  "server_time": "2026-10-28 14:32:07",
  "event": "BLOCK",
  "rule": "daily_loss",
  "limit": 500.00,
  "value": 462.10,
  "pct_of_limit": 92.4,
  "action": "entry_blocked",
  "symbol": "XAUUSD",
  "token": "replace-with-your-secret"
}

The columns map one to one:

Column Source Why it earns a column
received_at Apps Script new Date() Proves when the sheet got it, independent of broker clock
event_id EA Dedupe key if the EA retries
account EA Lets one sheet cover several challenge accounts
server_time EA Broker time, the clock your firm's rules use
event EA WARN (near-miss), BLOCK, or BREACH
rule EA daily_loss, max_drawdown, news_blackout, lot_cap
limit and value EA The numbers behind the decision
pct_of_limit EA Sortable measure of how close you came
action EA What the EA actually did

Keep both timestamps. Broker server time is what matters for daily loss resets, and received_at tells you whether delivery lagged.

Step by step: from alert to row

  1. Create the sheet. Name a tab events and put the column headers from the table in row 1. Open Extensions, then Apps Script, from inside this sheet so the script is bound to it.
  2. Paste the receiver. Use the script below. It checks a shared token, ignores repeats of the saje event_id, and appends one row.
  3. Store the token. In Project Settings, add a script property named TOKEN with a long random string. Put the same string in the EA's webhook settings.
  4. Deploy. Choose Deploy, New deployment, type Web app. Execute as yourself, access set to Anyone. Copy the /exec URL.
  5. Allow the URL in MT5. Under Tools, Options, Expert Advisors, tick Allow WebRequest for listed URL and add https://script.google.com. MT5 blocks WebRequest calls to anything not on that list.
  6. Send a test event. Have the EA fire a test alert, or POST the sample payload with curl, and confirm the row appears.
function doPost(e) {
  const lock = LockService.getScriptLock();
  lock.waitLock(10000);
  try {
    const body = JSON.parse(e.postData.contents);
    const token = PropertiesService.getScriptProperties().getProperty('TOKEN');
    if (body.token !== token) return ContentService.createTextOutput('denied');

    const tab = (e.parameter && e.parameter.tab) || 'events';
    const sh = SpreadsheetApp.getActive().getSheetByName(tab);

    const seen = sh.getRange('B:B').createTextFinder(body.event_id)
      .matchEntireCell(true).findNext();
    if (seen) return ContentService.createTextOutput('dup');

    sh.appendRow([
      new Date(), body.event_id, body.account, body.server_time,
      body.event, body.rule, body.limit, body.value,
      body.pct_of_limit, body.action, body.symbol
    ]);
    return ContentService.createTextOutput('ok');
  } finally {
    lock.releaseLock();
  }
}

Apps Script web apps cannot read request headers, which is why the token travels in the body. Responses also come back through a redirect, so have the EA treat any HTTP 200 or 302 as delivered and ignore the body. The row is written before the redirect happens.

Add the human side with a short form

Logs tell you what the EA did. They do not tell you why you were pushing a position at 92% of your daily loss. That part you have to write down, and a form is the easiest way to make it happen right after a block.

Qwenvo is a completely free form builder that our team builds, and it fits here beacuse webhooks, hidden fields and custom domains are all free on every account. Make a three question form: what were you trying to do, what state were you in, what will you change. Add event_id and account as hidden fields, and link to the foorm with those values in the URL so the review attaches to the exact event. Then point the form's webhook at the same Apps Script URL with ?tab=reviews on the end, and the answers land in a second tab you can join to events on event_id.

One honest note: Qwenvo's one-click Google Sheets connection is still being rolled out, so today you use the webhook route shpwn here. The form to Google Sheets guide covers the options. Check the payload format in the webhooks help page and adjust the appendRow call for the reviews tab to match.

See how Qwenvo webhooks work

Keeping the sheet reliable

Most failures come from a small set of causes, so check these first.

  • Nothing arrives. The URL is missing from the MT5 WebRequest allowlist. MT5 then returns an error code in the Experts tab instead of sending.
  • Rows stop after you edit the script. Edits do not go live until you redeploy. Use Manage deployments and edit the existing one to a new version, so the URL stays the same.
  • Duplicates. If the EA retries after a timeout, the same event arrives twice. The event_id check in the script handles it.
  • Missing rows during a Google outage. Treat the sheet as a mirror. Enforcement should never wait on it, and the EA's own journal stays the fallback you backfill from.
  • Slow trades. WebRequest is synchronous in MT5, so alerts should fire on events, never on every tick, with a short timeout.
  • Wrong day in reports. Group by server_time, not received_at, when you total daily loss.

What to measure

Once rows accumulate, a few pivot tables carry most of the value. Count WARN events per rule per week to see which limit you keep approaching. Sort by pct_of_limit to find your closest calls. Filter BLOCK events by hour to see whether trouble clusters around the news blackout window or the end of the session. Compare the reviews tab against the same event_ids to see whether the days you wrote honest notes were followed by fewer warnings.

For a funded account, a clean log also works as a record that your rules ran and what they did on a given day, which is handy if you ever need to discuss an incident with your firm.

Alternatives to Apps Script

You do not have to write the receiver yourself. Any webhook trigger wprks, and Zapier, Make and n8n all accept one and can add a row to a sheet.

Route Good for Trade-off
Apps Script web app Full control, no extra service, token and dedupe in code You maintain a small script
Zapier, Make or n8n webhook No code, easy to branch to Telegram or email One more service in the path, plus its plan limits
Qwenvo form webhook Human review notes next to the machine log Not a source for EA events, and the one-click Sheets connection is not live yet

Questions teams ask

Can I send alerts to Telegram or email as well as the sheet?

Yes. Keep the sheet as the permanent record and let a second route handle live pings. In Zapier, Make or n8n, one webhook trigger can fan out to both. Either way, the sheet row should be written first.

Does this work for several challenge accounts at once?

Yes, because every row carries the account number. Run one EA per account, point them all at the same URL, and filter by account in the sheet. If you want separate sheets per account, deploy one script per sheet.

Is it safe to leave the web app open to Anyone?

The URL is unguessable but not secret forever, so the shared token matters. Keep it in script properties, rotate it if the EA settings ever leak, and never put account passwords in the payload.

How do we get this set up on our own limits?

The Prop-Firm Guardian EA is a $149 setup plus a $19 monthly care plan, installed and walked through in 3 days, configured to your firm's exact limits and breach alerts.

Next step

Create the events tab today, paste the script, and deploy it. Then fire one test POST with curl before you connect anything live, and check that the row, btoh timestamps and the dedupe all behave. Once that works, the EA side is only a URL and a token.

Start your review form free

This system

Prop-Firm Guardian EA

$149 setup
+ $19/month care plan

Third-party platform and model usage billed to you directly. No lock-in. Live in 3 days.

More on Prop-Firm Guardian EA