A timestamp is a useful piece of metadata. It's not -- as you've discovered -- a reliable ordering criterion. Imagine you come up with some solution on your machine, but now have to use two machines? Can you keep their clocks synchronized within a nanosecond? Less?
In event sourcing, the typical guarantee is only that events are sorted within a single stream, e.g. one aggregate. This is your transaction guarantee anyway. Why not just use an integer to track each event's sequence within a stream? Your aggregate can generate it, since it's been tracking all events anyway.
If you want ordering across streams, you'll have to either generate that sequence number centrally (with the coupling that represents), or accept that multiple reads of multiple streams will not always return events within the same order, just that events within one stream should be sorted.