Without the code, it is just a guess. But reducing the 180M rows down to a smaller number before running through them will be key.
There might be an index on the Ledger that can be used. Date or Status come to mind. Might be the earliest date on the small side, or open status on the Ledger.
An Exists query is something I have used at times to tackle similar issues.
If you thought indexes got a big improvement, you might find a lot more yet to come. And when they say ‘row by agonizing row’ with a cursor, you really can feel the pain.