TickAtlas
Tutorial 11 min read · March 28, 2026

Google Sheets as a Trading Journal with Live API Data

Build a powerful trading journal in Google Sheets that automatically pulls live indicator data, tracks performance, and calculates key metrics using Apps Script.

CG
By the TickAtlas team

Why a Spreadsheet Trading Journal?

Most traders know they should keep a journal but find it tedious. The solution: automate the data collection. When you log a trade, the sheet automatically fetches the indicator state at entry, calculates R-multiples, and updates your performance dashboard.

Google Sheets with Apps Script can call the TickAtlas API directly. No server needed, no deployment -- just a spreadsheet that gets smarter over time.

Sheet Structure

Set up three tabs:

Trades

Columns: Date, Symbol, Direction, Entry, Stop Loss, Take Profit, Exit, P/L, R-Multiple, RSI at Entry, MACD at Entry, Notes

Dashboard

Win rate, average R, profit factor, max drawdown, equity curve chart, best/worst pairs

Live Prices

Auto-refreshing current prices and indicator values for your watchlist

Apps Script: Fetching Indicator Data

Open your Google Sheet, go to Extensions > Apps Script, and add this code:

javascript
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://tickatlas.com/v1";

/**
 * Fetch a technical indicator value.
 * Usage: =CLAW_INDICATOR("EURUSD", "RSI_14", "H4")
 */
function CLAW_INDICATOR(symbol, indicator, timeframe) {
  const url = \`\${BASE_URL}/indicator?symbol=\${symbol}\` +
    \`&indicator=\${indicator}&timeframe=\${timeframe}\

Auto-Fill Indicators on Trade Entry

javascript
/**
 * When a new trade is logged, auto-fill indicator columns.
 * Triggered by an onEdit event on the Trades sheet.
 */
function onTradeEntry(e) {
  const sheet = e.source.getActiveSheet();
  if (sheet.getName() !== "Trades") return;

  const row = e.range.getRow();
  const col = e.range.getColumn();

  // Column B = Symbol (trigger when symbol is entered)
  if (col !== 2 || row < 2) return;

  const symbol = sheet.getRange(row, 2).getValue();
  if (!symbol) return;

  // Fetch RSI and MACD at the time of entry
  const rsi = CLAW_INDICATOR(symbol, "RSI_14", "H4");
  const macd = CLAW_INDICATOR(symbol, "MACD", "H4");

  // Write to RSI column (K) and MACD column (L)
  sheet.getRange(row, 11).setValue(rsi);
  sheet.getRange(row, 12).setValue(macd);
}

// Install the trigger
function createTrigger() {
  ScriptApp.newTrigger("onTradeEntry")
    .forSpreadsheet(SpreadsheetApp.getActive())
    .onEdit()
    .create();
}

Live Watchlist with Auto-Refresh

javascript
/**
 * Refresh all prices on the Live Prices tab.
 * Set up a time-driven trigger to run every 5 minutes.
 */
function refreshWatchlist() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("Live Prices");
  const symbols = sheet.getRange("A2:A20").getValues().flat().filter(Boolean);

  for (let i = 0; i < symbols.length; i++) {
    const row = i + 2;
    const symbol = symbols[i];

    try {
      const price = CLAW_PRICE(symbol);
      const rsi = CLAW_INDICATOR(symbol, "RSI_14", "H4");
      const atr = CLAW_INDICATOR(symbol, "ATR_14", "H4");

      sheet.getRange(row, 2).setValue(price);   // Column B: Price
      sheet.getRange(row, 3).setValue(rsi);     // Column C: RSI
      sheet.getRange(row, 4).setValue(atr);     // Column D: ATR
      sheet.getRange(row, 5).setValue(new Date()); // Column E: Last Update
    } catch (err) {
      sheet.getRange(row, 2).setValue("ERR");
    }
  }
}

// Set up auto-refresh every 5 minutes
function createRefreshTrigger() {
  ScriptApp.newTrigger("refreshWatchlist")
    .timeBased()
    .everyMinutes(5)
    .create();
}

Performance Metrics Formulas

Use these formulas on the Dashboard tab to calculate key trading metrics:

Win Rate:
=COUNTIF(Trades!H2:H, ">"&0) / COUNTA(Trades!H2:H)

Average R-Multiple:
=AVERAGE(Trades!I2:I)

Profit Factor:
=SUMIF(Trades!H2:H, ">"&0) / ABS(SUMIF(Trades!H2:H, "<"&0))

Max Consecutive Losses:
(Use Apps Script for this -- too complex for a formula)

Expectancy:
=(Win Rate * Average Win) - ((1 - Win Rate) * Average Loss)

Tips for Effective Journaling

Log the indicator state, not just the trade

Recording RSI, MACD, and ATR at entry lets you later analyze which indicator conditions produce your best trades.

Use R-multiples, not dollar amounts

A trade that made 2R is meaningful regardless of whether R was $50 or $500. R-multiples normalize your performance across varying position sizes.

Review weekly, not daily

Daily reviews encourage overtrading and emotional reactions. Weekly reviews give you enough data for pattern recognition.

Related Reading

Try this with live data

Every account gets $2.50 in free PAYG credits. No card required — paste your API key and run the code above against live broker data.