Point-in-time valuation
The canonical statement of why historical portfolio values on this chain are usually wrong.
The arithmetic
Valuing a stock token position at block N requires three terms, and the middle one is time-dependent.
value_at(N) = balanceOf(addr, N) × uiMultiplier_at(N) ← everyone skips this × price_at(N)Why it is skipped
Because raw balances are static across corporate actions, nothing looks wrong. A provider returns balanceOf(addr, N), multiplies by a current price, and produces a number that is confidently, invisibly incorrect for any instrument that has since split or paid a dividend.
After a 4-for-1 split, applying today's multiplier to a pre-split block overstates the position by exactly four times. The error does not decay; it compounds with each subsequent action.
How we do it
Every historical endpoint requires an as_of block or timestamp and applies the multiplier valid at that point. A historical request without as_of returns 400, not a quietly-current answer. Every response carries the multiplier used and the block it became effective, so you can check our arithmetic.
curl -s https://api.robinhoodrpc.io/v1/accounts/0xabc.../positions \ -H "Authorization: Bearer $RHRPC_KEY" \ -G --data-urlencode "as_of_block=4200000" \ | jq '.positions[] | { token_symbol, balance_raw, balance_ui, multiplier_applied, multiplier_effective_block }'Correctness
This is testable against any provider. Ask for a wallet's position value at a block preceding a corporate action, then check whether the multiplier applied is the one from that block or from today. It reproduces or it does not.