I agree with ehpeeeye, a very good approach would be to use the system.account storage function or leverage the features an indexer provides. The Substrate-ETL dataset would provide granular information for balances in BigQuery.
Here's some code to get you started for your specific question, in Python:
from substrateinterface import SubstrateInterface
import time
substrate = SubstrateInterface(url="wss://rpc.polkadot.io")
def format_balance(amount: int):
amount = format(amount / 10**substrate.properties.get('tokenDecimals', 0), ".15g")
return f"{amount} {substrate.properties.get('tokenSymbol', 'UNIT')}"
for block_number in range(17370000, 17379181, 1000):
block_hash = substrate.get_block_hash(block_number)
result = substrate.query(
"System", "Account", ["14uufggn6CkHWpDUeyNEDjZMkYLb7waWtcrLC57sUfEwVPQa"], block_hash=block_hash
)
balance = (result.value["data"]["free"] + result.value["data"]["reserved"])
print(f"Balance @ {block_number}: {format_balance(balance)}")
# Being nice
time.sleep(1)
It's also listed as example in PySubstrateInterface here.
There are possible optimizations instead of looping through all the blocks if you're willing to sacrifice precision to gain speed. Another optimization could be as simple as connecting to multiple RPC's at the same time and query them in parallel.
Either way, I hope this helps.