It's worth noting that using a fixed time step and making it independent of the frame rate means that you care much less about the frame rate as the logic itself it always going to be done in the same step of time and therefore limits can be set based on expected values.
Interpolation is probably the most complicated step.
First thing I notice is that you're moving the actual position of the circle based on the alpha. This movement should only be done as part of the update. The only thing that should be done outside of the update is 'temporary' adjustment for the render.
So, you could move it, draw it and move it back.
Interpolation, by the way should be on actual positions. That is, to do it, you require the current position, its previous position and the length of time that the frame took.
You take the alpha as already you did well.
Then, interpolate between the previous and current position.
Note that it's easier to store the information separate to the circle.
Maybe something like this:
// setup
sf::Vector2f position(0, window.getSize().y / 2); // this is the position of the circle that you are moving
// within main loop
sf::Vector2f previousPosition();
// within fixed step update
previousPosition = position;
position += direction * speed; // we now have both a current position and a previous position and they're different
// interpolation (still within main loop, before drawing)
sf::Vector2f interpolatedPosition((position - previousPosition) * alpha); // you already have an "alpha" value ;)
circle.setPosition(interpolationPosition);
Note that this means your interpolated position is always slightly behind the actual position giving up to a frame of lag. This is explained in Fix You Timestep.
Saving the position and previous position is a good way to understand how the interpolation works because for everything that updates, there needs to be a current and previous version. Side note: the current and previous values are spoken of as "states" in Fix Your Timestep so the current state is
all of the current values and previous states is
all of their equivalent previous values.
Note that extrapolation is different because, although it removes the lag, it does so by
guessing where it's going to go. If it changes direction, the extrapolation was wrong and the movement jerks.
Interpolation is the way to go for sure
![Smiley :)](https://www.sfml-dev.org/forums/Smileys/default/smiley.gif)
Side note: the previous values should be updated in the timestep loop as shown so that the alpha should always be within the range of a fixed step (0 - 1).