I'll post this and then wait to see if the OP want's to take it from here and post an updated improved script, or would like improvements here.
I'm no expert at this but I will give it a try with an approximate calculation and then mention ways to make it better.
I'll start with positions of the Sun, Earth, Moon and 2020SO on 01-Nov-2020 from JPL horizons in barycentric coordinates and then propagate their motion.
I am lazy so for the Sun I will just let it drift relative to the solar system barycenter. We could add the four big planets if we wanted to get the motion of the Sun better.
I haven't included photon pressure on the 2020 SO. Since it varies as $1/r^2$ just like gravity, you could add that by reducing GMsun for just the line when the Sun's gravitational acceleration on 2020 SO is calculated, but I don't think it will make much difference over six months,
Force due to photon pressure will be something like this (pointed away from the Sun)
$$F \approx f \ A \ \frac{\text{1361 W/m}^2}{c^2} \frac{\text{1 AU}^2}{r^2}$$
where $f$ is some fudge factor of order unity involving reflectivity and diffuseness of scattering and $A$ is some average cross-sectional area.
Ways to improve:
- Include relativistic corrections to the acceleration from answers to How to calculate the planets and moons beyond Newtons's gravitational force?
- Add more planets to account for their effects on the motion of these bodies
- Use actual ephemeris positions from Skyfield or Horizons or SPICE, either by calculating once and interpolating, or for Skyfield calling it repeatedly in the integration loop
- Update to the new SciPy initial value problem ODE integrator scipy.integrate.solve_ivp which handles shaped arrays (so they don't have to be flattened like this) and possibly other goodies
- Include some simple model for photon pressure

above: Earth in the center and the frame is rotating with the Earth's orbit around the Sun. below: Earth in the center and the frame doesn't rotate


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
from scipy.integrate import odeint as ODEint
def rotz(vecs, th):
x, y, z = vecs
cth, sth = np.cos(th), np.sin(th)
xrot = x * cth - y * sth
yrot = y * cth + x * sth
return np.vstack((xrot, yrot, z))
def deriv(X0, t):
x, v = X0.reshape(2, -1)
xsun, xearth, xmoon, xso = x.reshape(4, -1)
asun = np.zeros(3) # just let the Sun drift (approximation)
aearth = -GMs * (xearth-xsun) * (((xearth-xsun)**2).sum())**-1.5
aearth += -GMm * (xearth-xmoon) * (((xearth-xmoon)**2).sum())**-1.5
amoon = -GMs * (xmoon-xsun) * (((xmoon-xsun)**2).sum())**-1.5
amoon += -GMe * (xmoon-xearth) * (((xmoon-xearth)**2).sum())**-1.5
aso = -GMs * (xso-xsun) * (((xso-xsun)**2).sum())**-1.5
aso += -GMe * (xso-xearth) * (((xso-xearth)**2).sum())**-1.5
aso += -GMm * (xso-xmoon) * (((xso-xmoon)**2).sum())**-1.5
acc = np.hstack((asun, aearth, amoon, aso))
return np.hstack((v, acc))
# initial state vectors from JPL Horizons JD=2459154.500000000 (A.D. 2020-Nov-01 00:00:00.0000)
x0 = [-9.310337316714592E+05, 9.481788919374773E+05, 1.382575687749073E+04,
1.148762587112595E+08, 9.386327656117186E+07, 9.411282390393317E+03,
1.151732738477067E+08, 9.413906042360909E+07, -1.276638399431854E+04,
1.164364627893544E+08, 9.471022406041500E+07, -2.793366484529004E+05]
v0 = [-1.242704706611964E-02, -9.038092487749897E-03, 3.763127777363607E-04,
-1.913151322927344E+01, 2.310482932662013E+01, -1.501188465050873E-03,
-1.979573309672475E+01, 2.381249918077239E+01, 6.837768022510993E-02,
-1.954880640404515E+01, 2.295580439951134E+01, 6.207646654113397E-02]
X0 = np.array(x0 + v0) * 1000. # convert kilometers to meters
GMs = 1.32712440018E+20
GMe = 3.986004418E+14
GMm = 4.9048695E+12
# sample at 0.1 day intervals (integrator timesteps are variable and internal)
days = np.arange(0, 180.1, 0.1) # 181
times = days * 3600 * 24
# learn to use the newer scipy.integrate.solve_ivp later
answer, info = ODEint(deriv, X0, times, full_output=True)
positions, velocities = answer.T.reshape(2, 4, 3, -1)
sunpos, earthpos, moonpos, SOpos = positions
r_SO_moon = np.sqrt(((SOpos - moonpos)**2).sum(axis=0))
r_SO_earth = np.sqrt(((SOpos - earthpos)**2).sum(axis=0))
r_moon_earth = np.sqrt(((moonpos - earthpos)**2).sum(axis=0))
plt.figure()
#plt.plot(days, r_SO_moon/1000.)
#plt.plot(days, r_SO_earth/1000.)
#plt.plot(days, r_moon_earth/1000.)
## modified for legend
plt.plot(days, r_SO_moon/1000., label='2020 SO to Moon')
plt.plot(days, r_SO_earth/1000., label='2020 SO to Earth')
plt.plot(days, r_moon_earth/1000., label='Moon to Earth')
plt.xlabel('days since 01-Nov-2020')
plt.ylabel('distance (km)')
plt.title('Separation between 2020 SO, Moon & Earth')
plt.legend(title='distance') ## added for legend title
plt.show()
x, y, z = earthpos
theta = np.arctan2(y, x)
sunpos_rot, earthpos_rot, moonpos_rot, SOpos_rot = [rotz(thing, -theta)
for thing in positions]
plt.figure()
plt.plot([0], [0], 'ob')
x, y, z = moonpos_rot - earthpos_rot
plt.plot(x, y, '-g')
x, y, z = SOpos_rot - earthpos_rot
plt.plot(x, y, '-r')
plt.gca().set_aspect('equal')
plt.show()
plt.figure()
plt.plot([0], [0], 'ob')
x, y, z = moonpos - earthpos
plt.plot(x, y, '-g')
x, y, z = SOpos - earthpos
plt.plot(x, y, '-r')
plt.gca().set_aspect('equal')
plt.show()
Setup for Horizons to obtain initial state vectors in the script:

above: solar system barycenter. below: Type-2 state vectors, km, km/sec units, ecliptic and mean equinox, etc.
