Use trading accounts
Turn on the Use Trading Accounts book option so every transaction that mixes currencies balances in each currency, and see the Trading accounts it creates.
A transaction in two currencies balances in value, but each currency taken alone does not: you gave up 108.50 dollars and
received 100.00 euros. Trading accounts fix that. With the option on, red-ale adds balancing splits to a hidden tree of
TRADING accounts (Trading:CURRENCY:USD, Trading:CURRENCY:EUR), so that the splits in each currency sum to zero on
their own. The Trading account for each currency then shows how much of it you have bought or sold, which is what
accountants use to find a currency gain or loss.
It is a book option, so it is stored in the book and GnuCash honours it when it opens the file.
Steps
- Turn it on with book.setOptions and
useTradingAccounts: true. No existing transaction changes; only transactions you post or edit afterwards get trading splits. book.options shows the current setting. - Post as usual with transaction.post. Give the transaction's
currency, and anamounton each split whose account is in another commodity (see Multiple currencies). red-ale adds the trading splits itself. - Look at the result. The transaction has two more splits than you sent. account.list now
includes the
Tradingaccounts, which are placeholders: do not post to them yourself.
Turning the option off stops new trading splits from being added, but keeps the ones already there.
Example
Example: with a new, empty book open as book.gnucash, at 2024-07-15T12:00:00Z.
JSON-RPC
Request:
{"jsonrpc":"2.0","id":1,"method":"book.setOptions","params":{"useTradingAccounts":true}}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"useTradingAccounts": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":2,"method":"account.create","params":{"name":"Checking","type":"BANK","commodity":"USD"}}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":3,"method":"account.create","params":{"name":"Euro Bank","type":"BANK","commodity":"EUR"}}
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":4,"method":"transaction.post","params":{"datePosted":"2024-07-02","description":"Buy euros","currency":"USD","splits":[{"account":"Euro Bank","value":"108.50","amount":"100.00"},{"account":"Checking","value":"-108.50"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"balanced": true,
"splits": [
{
"accountName": "Euro Bank",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:USD",
"…": "…"
},
{
"accountName": "Checking",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:EUR",
"value": {
"num": "-10850",
"denom": "100"
},
"amount": {
"num": "-10000",
"denom": "100"
},
"…": "…"
}
],
"…": "…"
}
}
Command line
red-ale exec --book book.gnucash --script - <<'EOF'
book.setOptions {"useTradingAccounts":true}
account.create {"name":"Checking","type":"BANK","commodity":"USD"}
account.create {"name":"Euro Bank","type":"BANK","commodity":"EUR"}
transaction.post {"datePosted":"2024-07-02","description":"Buy euros","currency":"USD","splits":[{"account":"Euro Bank","value":"108.50","amount":"100.00"},{"account":"Checking","value":"-108.50"}]}
EOF
It prints:
[
{
"useTradingAccounts": true,
"…": "…"
},
"…",
"…",
{
"balanced": true,
"splits": [
{
"accountName": "Euro Bank",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:USD",
"…": "…"
},
{
"accountName": "Checking",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:EUR",
"value": {
"num": "-10850",
"denom": "100"
},
"amount": {
"num": "-10000",
"denom": "100"
},
"…": "…"
}
],
"…": "…"
}
]
MCP tool call
Tool call:
{"name":"book.setOptions","arguments":{"useTradingAccounts":true}}
Result:
{
"structuredContent": {
"useTradingAccounts": true,
"…": "…"
}
}
Tool call:
{"name":"account.create","arguments":{"name":"Checking","type":"BANK","commodity":"USD"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"account.create","arguments":{"name":"Euro Bank","type":"BANK","commodity":"EUR"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"transaction.post","arguments":{"datePosted":"2024-07-02","description":"Buy euros","currency":"USD","splits":[{"account":"Euro Bank","value":"108.50","amount":"100.00"},{"account":"Checking","value":"-108.50"}]}}
Result:
{
"structuredContent": {
"balanced": true,
"splits": [
{
"accountName": "Euro Bank",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:USD",
"…": "…"
},
{
"accountName": "Checking",
"…": "…"
},
{
"accountName": "Trading:CURRENCY:EUR",
"value": {
"num": "-10850",
"denom": "100"
},
"amount": {
"num": "-10000",
"denom": "100"
},
"…": "…"
}
],
"…": "…"
}
}