It’s technically possible, but requires a whole bunch of manual setup.
One of the ways you can do it, is by not using randomness and instead using completely predictable looping values for simulation. Setting manual seeds can be very helpful here. You can set the seed based on the id of a particle and loop the id using modulo for example.
Any thing that is manually animated using curves will also be loopable by making sure the curves align.
Lastly, the first loop might not be loopable due to not having the particle from the previous loop available. A warmup time at least equal to the loop can be helpful here.
Hope that helps.