You could modify Conseil in order to support the extraction of voting related info.
Another approach is to use the tzscan codebase, which also fills a database with information from the Tezos node.
Last but not least, you can use RPC calls to /chains/main/blocks/head/context/raw/json/.. to explore the raw context for every block.
<block_id> - is a hash or a level of the block at which you ask for balance.
If you want to get a simple balance at the specific point in the cycle:
(this is pseudocode, I hope you figure it out)
var cycle = 60;
var p1 = (cycle * 4096 + 1) + 0; //beginning of the cycle
var p2 = (cycle * 4096 + 1) + 4095; //end of the cycle
var balance_at_p1 = get('...
tzkt.io offers a websocket based listener that can be used for the scenario mentioned by you.
Alternatively, you can run a cron job that checks for changes in the contract storage (tzkt's API can be used once again) and records the same in the DB.