Guide

Record prices and commodities

Add a security, record its price by hand, turn on online quotes, and tidy old prices out of the price database.

Reports that show what your shares are worth, and accounts held in a foreign currency, need prices: how many dollars one share, or one euro, was worth on a day. The book keeps them in its price database, one price per commodity, currency and day. You can enter prices by hand, or let red-ale fetch them from an online quote service.

Steps

  1. Add the commodity with commodity.create (see Buy and sell shares). Currencies are already known and need no creating.
  2. Enter a price by hand with price.add: the commodity, the currency the price is in, the value (currency units per commodity unit, as an exact string) and the date. A price already stored for the same pair and day is replaced, or kept, according to which source is more trusted, as in GnuCash; outcome says what happened.
  3. Look at the prices with price.list, by commodity, currency and dates.
  4. Fetch prices online. Mark the commodity with commodity.update: quoteFlag: true and a quoteSource such as yahoo_json. Then switch on the network, which is off by default, with config.set ({"changes": {"quotes.network": true}}), and call price.fetchQuotes. It answers at once with a fetch ID; ask price.fetchStatus for the result per commodity. Until the network is switched on the call fails with network-disabled and sends nothing. Over MCP the setting cannot be changed, so a person turns it on.
  5. Tidy the database with price.removeOld: choose the commodities, a before date, which sources may go (fetched, user or app) and what to keep (the last price of each week, month or quarter, or none).

Example

Example: with a new, empty book open as book.gnucash, at 2024-07-01T12:00:00Z.

JSON-RPC

Request:

{"jsonrpc":"2.0","id":1,"method":"commodity.create","params":{"namespace":"NASDAQ","mnemonic":"AAPL","fullname":"Apple Inc"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "NASDAQ::AAPL",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":2,"method":"commodity.update","params":{"commodity":"NASDAQ::AAPL","quoteFlag":true,"quoteSource":"yahoo_json"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "quoteFlag": true,
    "quoteSource": "yahoo_json",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":3,"method":"price.add","params":{"commodity":"NASDAQ::AAPL","currency":"USD","value":"150.25","date":"2023-12-29"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "outcome": "added",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":4,"method":"price.add","params":{"commodity":"NASDAQ::AAPL","currency":"USD","value":"187.10","date":"2024-06-28"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "outcome": "added",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":5,"method":"price.list","params":{"commodity":"NASDAQ::AAPL"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": [
    {
      "date": "2024-06-28",
      "value": {
        "num": "18710",
        "denom": "100"
      },
      "…": "…"
    },
    {
      "date": "2023-12-29",
      "value": {
        "num": "15025",
        "denom": "100"
      },
      "…": "…"
    }
  ]
}

Request:

{"jsonrpc":"2.0","id":6,"method":"price.fetchQuotes","params":{}}

Response:

{
  "jsonrpc": "2.0",
  "id": 6,
  "error": {
    "code": 5000,
    "message": "…",
    "data": {
      "help": "error/network-disabled"
    }
  }
}

Request:

{"jsonrpc":"2.0","id":7,"method":"price.removeOld","params":{"commodities":["NASDAQ::AAPL"],"before":"2024-01-01","sources":["app"],"keep":"none"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "removed": [
      "…"
    ]
  }
}

Command line

red-ale exec --book book.gnucash --script - <<'EOF'
commodity.create {"namespace":"NASDAQ","mnemonic":"AAPL","fullname":"Apple Inc"}
commodity.update {"commodity":"NASDAQ::AAPL","quoteFlag":true,"quoteSource":"yahoo_json"}
price.add {"commodity":"NASDAQ::AAPL","currency":"USD","value":"150.25","date":"2023-12-29"}
price.add {"commodity":"NASDAQ::AAPL","currency":"USD","value":"187.10","date":"2024-06-28"}
price.list {"commodity":"NASDAQ::AAPL"}
price.fetchQuotes {}
price.removeOld {"commodities":["NASDAQ::AAPL"],"before":"2024-01-01","sources":["app"],"keep":"none"}
EOF

It fails with exit status 2, printing on standard error:

{
  "error": {
    "code": 5000,
    "message": "…",
    "data": {
      "help": "error/network-disabled"
    }
  }
}

MCP tool call

Tool call:

{"name":"commodity.create","arguments":{"namespace":"NASDAQ","mnemonic":"AAPL","fullname":"Apple Inc"}}

Result:

{
  "structuredContent": {
    "id": "NASDAQ::AAPL",
    "…": "…"
  }
}

Tool call:

{"name":"commodity.update","arguments":{"commodity":"NASDAQ::AAPL","quoteFlag":true,"quoteSource":"yahoo_json"}}

Result:

{
  "structuredContent": {
    "quoteFlag": true,
    "quoteSource": "yahoo_json",
    "…": "…"
  }
}

Tool call:

{"name":"price.add","arguments":{"commodity":"NASDAQ::AAPL","currency":"USD","value":"150.25","date":"2023-12-29"}}

Result:

{
  "structuredContent": {
    "outcome": "added",
    "…": "…"
  }
}

Tool call:

{"name":"price.add","arguments":{"commodity":"NASDAQ::AAPL","currency":"USD","value":"187.10","date":"2024-06-28"}}

Result:

{
  "structuredContent": {
    "outcome": "added",
    "…": "…"
  }
}

Tool call:

{"name":"price.list","arguments":{"commodity":"NASDAQ::AAPL"}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "[{\"date\":\"2024-06-28\",\"value\":{\"num\":\"18710\",\"denom\":\"100\"},\"…\":\"…\"},{\"date\":\"2023-12-29\",\"value\":{\"num\":\"15025\",\"denom\":\"100\"},\"…\":\"…\"}]"
    }
  ]
}

Tool call:

{"name":"price.fetchQuotes","arguments":{}}

Result:

{
  "isError": true,
  "structuredContent": {
    "error": {
      "code": 5000,
      "name": "network-disabled",
      "message": "…",
      "data": {
        "help": "error/network-disabled"
      }
    }
  }
}

Tool call:

{"name":"price.removeOld","arguments":{"commodities":["NASDAQ::AAPL"],"before":"2024-01-01","sources":["app"],"keep":"none"}}

Result:

{
  "structuredContent": {
    "removed": [
      "…"
    ]
  }
}