# Fx cross rate compute

`fx-cross-rate-compute` · version 1.0.0 · Money & pricing · free, no key needed

Derive a cross exchange rate and its inverse from two quoted rates that share one currency, at a stated scale.

**Use when you need to: cross rate from two exchange rates · derive GBP/JPY from USD/JPY and GBP/USD · triangulate currency rate via euro.**

## Decide before calling

Read the [versioned contract](/v1/tools/fx-cross-rate-compute/versions/1.0.0) and the supported scope below. Reuse `fx-cross-rate-compute@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `fx-cross-rate-compute@1.0.0` for cross rate from two exchange rates. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- cross rate from two exchange rates
- derive GBP/JPY from USD/JPY and GBP/USD
- triangulate currency rate via euro
- DEM to FRF from euro conversion rates
- inverse exchange rate rounded to 6 decimals
- what is the EUR/GBP rate if I know USD/EUR and USD/GBP
- synthetic cross rate calculation
- derive the rate between two currencies through a common pivot

## Not supported

- fetching live or historical exchange rates
- converting an amount of money between currencies
- chains of more than two quotes
- bid/ask spreads or fees

## Behavior

- Quote convention: {base: X, quote: Y, rate: r} means 1 X = r Y (EUR/USD 1.0843: 1 EUR = 1.0843 USD). Currency codes are opaque strings matching ^[A-Z0-9]{3,5}$ (upper-case only, no case folding, no ISO lookup), so historic and non-ISO codes (DEM, FRF, USDT) are accepted. rates holds exactly 2 quotes; each rate is a positive decimal (zero is invalid_input, reason rate_zero); base equal to quote is invalid_input (reason same_currency).
- The two quotes must share exactly one currency, reported as via; no shared currency or the same pair twice is invalid_input with reason no_common_currency. The target must be exactly the two non-shared currencies in either order, else invalid_input with reason target_mismatch.
- Computed on exact rationals. If p(X) is the amount of the shared currency worth 1 X (r for a quote X/shared, 1/r for shared/X), then for target {base T, quote U} rate = p(T)/p(U) and inverse_rate = p(U)/p(T). Example: EUR/DEM 1.95583 and EUR/FRF 6.55957 give DEM/FRF 3.353855 at scale 6.
- rate and inverse_rate are each rounded once from the exact rational at scale (0..20) with the given mode; the inverse is not derived from the rounded rate. Both are fixed-scale strings and may round to zero. exact is true iff neither needed rounding.
- The ten rounding modes: half_even, half_up (ties away from zero), half_down, half_ceiling, half_floor, up, down, ceiling, floor, and unnecessary (if either value is inexact the call is not_computable, reason rounding_necessary).
- A rate string over 62 characters is limit_exceeded, checked before the syntax; more than 60 digits or 40 fraction digits is invalid_input. base and quote in the output echo the target; the tool holds no rate data and has no clock or network.
- Disclaimer: arithmetic calculation only; not financial, tax, legal, or investment advice.

## Input

- `rates` (array of object, required): min items 2; max items 2; Exactly two quotes that share exactly one currency. Each says: 1 base = rate quote.
- `target` (object, required): The requested pair: 1 base = ? quote. Must be the two currencies that are NOT shared by the given quotes (either order).
- `scale` (integer, required): min 0; max 20; Fraction digits of the output rates.
- `rounding` (one of "half_even", "half_up", "half_down", "half_ceiling", "half_floor", "up", "down", "ceiling", "floor", "unnecessary", required)

## Output

- `base` (string, required): min length 3; max length 5; pattern `^[A-Z0-9]{3,5}$`
- `quote` (string, required): min length 3; max length 5; pattern `^[A-Z0-9]{3,5}$`
- `rate` (string, required): min length 1; max length 400; pattern `^(0|[1-9][0-9]*)(\.[0-9]+)?$`; Units of `quote` per 1 `base`, fixed scale.
- `inverse_rate` (string, required): min length 1; max length 400; pattern `^(0|[1-9][0-9]*)(\.[0-9]+)?$`; Units of `base` per 1 `quote`, computed from the exact rational (not by inverting the rounded rate), fixed scale.
- `via` (string, required): min length 3; max length 5; pattern `^[A-Z0-9]{3,5}$`; The shared (pivot) currency.
- `exact` (boolean, required): true iff neither rate needed rounding.

## Limits

- max decimal chars: 62
- max decimal digits: 60
- max fraction digits: 40
- max scale: 20
- quotes: 2

## Example

Request input:

```json
{
  "rates": [
    {
      "base": "EUR",
      "quote": "DEM",
      "rate": "1.95583"
    },
    {
      "base": "EUR",
      "quote": "FRF",
      "rate": "6.55957"
    }
  ],
  "target": {
    "base": "DEM",
    "quote": "FRF"
  },
  "scale": 6,
  "rounding": "half_even"
}
```

Response:

```json
{
  "result": {
    "base": "DEM",
    "quote": "FRF",
    "rate": "3.353855",
    "inverse_rate": "0.298164",
    "via": "EUR",
    "exact": false
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "fx-cross-rate-compute",
  "version": "1.0.0",
  "input": {
    "rates": [
      {
        "base": "EUR",
        "quote": "DEM",
        "rate": "1.95583"
      },
      {
        "base": "EUR",
        "quote": "FRF",
        "rate": "6.55957"
      }
    ],
    "target": {
      "base": "DEM",
      "quote": "FRF"
    },
    "scale": 6,
    "rounding": "half_even"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/fx-cross-rate-compute/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"rates":[{"base":"EUR","quote":"DEM","rate":"1.95583"},{"base":"EUR","quote":"FRF","rate":"6.55957"}],"target":{"base":"DEM","quote":"FRF"},"scale":6,"rounding":"half_even"}'
```

The machine-readable contract is at [/v1/tools/fx-cross-rate-compute/versions/1.0.0](/v1/tools/fx-cross-rate-compute/versions/1.0.0).

### CLI

```sh
node cli.mjs run fx-cross-rate-compute 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Money convert at rate](/tools/money-convert-at-rate): Convert an amount between two ISO 4217 currencies at a caller-supplied rate with explicit quote direction and rounding.
- [Percent compute](/tools/percent-compute): Exact percentage of, ratio, change, increase, decrease and reverse percentage, rounded once at a chosen scale.
- [Price margin compute](/tools/price-margin-compute): Solve cost, price, profit, gross margin and markup from any two of cost, price, margin percent or markup percent.
- [Vat net gross convert](/tools/vat-net-gross-convert): Convert a net or gross amount at a VAT rate into a net, VAT and gross triple that adds up exactly at currency precision.
- [Currency lookup](/tools/currency-lookup): Look up an ISO 4217 alphabetic or numeric currency code: name, minor-unit exponent, entities, active or withdrawn.
- [Decimal divide](/tools/decimal-divide): Divide two decimal strings exactly, rounding the quotient once to a fixed scale, and report the exact remainder.
