---
title: Sync
description: "One command refreshes the outside data firma depends on: live stock prices from Finnhub and historical FX rates from FRED. Because the scope is derived from the data you've already logged, firma asks each API only for what is missing."
---

export const scopeFeatures = [
  {
    icon: '📈',
    title: 'Prices, based on active holdings',
    desc: 'Only tickers with a non-zero net position, computed from your transactions, are fetched from Finnhub. Sell a position down to 0 and it disappears from the next sync. If you hold 4 stocks, sync makes 4 Finnhub calls, not 400.',
  },
  {
    icon: '💱',
    title: 'FX history, based on your earliest entry',
    desc: 'On the first run, firma scans transactions, balances, and flow entries to find your earliest date, then backfills FX rates from there through today, usually in about 5 FRED calls and 10 seconds. After that, it only fetches dates beyond your latest cached rate, which is usually sub-second.',
  },
];

export const briefExchange = [{
  user: "Sync everything and give me today's brief.",
  ai: <>
    <p>
      <code>sync</code> ✓ &nbsp; <code>get_brief</code> ✓
    </p>
    <p style={{ marginTop: '0.5rem' }}>
      Portfolio is up <code>+$1,820 (+1.1%)</code> today. NVDA leads at <code>+4.3%</code>.
      Macro is risk-on (5/5), stress low (4/100). MSFT earnings hits Apr 29.
      Anything you want to dig into?
    </p>
  </>,
}];

<Section label="firma sync">
By default, this syncs prices for your active holdings and FX history for the
eight supported currencies: KRW, JPY, EUR, CNY, GBP, HKD, INR, and TWD. Both happen in one run.

<div className="terminal">
  <div className="terminal-line">
    <span className="term-prompt">$</span>
    <span className="term-cmd">firma sync</span>
  </div>
  <pre className="term-pre">{`◇  Updated 4 stocks
◇  Synced 9525 FX rates across 8 currencies`}</pre>
</div>

  <Note>
    Requires both <code>finnhub-key</code> (for prices) and <code>fred-key</code> (for FX history).
    Run <code>firma config set finnhub-key &lt;key&gt;</code> and{' '}
    <code>firma config set fred-key &lt;key&gt;</code> first.
  </Note>
</Section>

<Section label="Scope is Derived from Your Data">
firma never asks the APIs for more than it needs. The sync scope is computed from the
local SQLite database:

  <FeatureList items={scopeFeatures} />

This means **you should add your data first, then sync**. If the database is
empty, sync has nothing to work from and does nothing.
</Section>

<Section label="firma sync fx">
This refreshes FX history only. It's useful when you import an older transaction
that predates the current FX cache, or when you want updated historical rates
without re-fetching prices.

<div className="terminal">
  <div className="terminal-line">
    <span className="term-prompt">$</span>
    <span className="term-cmd">firma sync fx</span>
  </div>
  <pre className="term-pre">{`◇  Synced 9525 FX rates across 8 currencies`}</pre>
</div>

  <Note>
    Same incremental logic. Pulls from{' '}
    <a href="https://fred.stlouisfed.org" target="_blank" rel="noopener noreferrer">FRED</a>{' '}
    via the corresponding daily series (<code>DEXKOUS</code>, <code>DEXJPUS</code>,{' '}
    <code>DEXCHUS</code>, <code>DEXUSEU</code>, <code>DEXUSUK</code>, <code>DEXHKUS</code>,{' '}
    <code>DEXINUS</code>, <code>DEXTAUS</code>) and stores
    uniform direction (foreign per 1 USD) in <code>~/.firma/firma.db</code>{' '}
    <code>fx_rates</code> table.
  </Note>
</Section>

<Section label="Why Historical FX Matters">
Without a historical FX cache, past balances shown in a non-USD currency use
*today's* exchange rate. That means "what was my net worth in KRW in 2018?" gets
the wrong answer. Firma converts each entry using the FX rate from its own date,
so historical figures reflect what you actually had at that time.

Anything tagged with a date uses the historical rate. Anything that represents
current value, such as portfolio market value, the brief's MACRO TODAY section,
or FX impact since yesterday, stays on live rates from <code>open.er-api.com</code>.
</Section>

<Section label="Daily Routine">
After the initial setup, the morning ritual is two commands or one Claude prompt:

<div className="terminal">
  <div className="terminal-line">
    <span className="term-prompt">$</span>
    <span className="term-cmd">firma sync &amp;&amp; firma brief</span>
  </div>
</div>

Or, in Claude:

  <ChatDemo header="Claude Desktop · firma MCP connected" exchanges={briefExchange} />
</Section>
