To get the direction of movement, you need to take the difference between the current and previous value and, if the result is positive you’re increasing, negative you’re decreasing.
Keeping a copy of the previous value is exactly what Bome’s “global variables” are designed to do, and unfortunately Traktor has no ability to keep information around about the earlier state of a controller, so Bome’s is your friend here.
Interestingly, taking the difference between two values in a sequence is exactly the same as calculating the derivative of a discrete function (“discrete” because it comes in individual steps instead of being a continuous value). All the normal rules of Calculus can then be applied, so taking the difference will calculate the “velocity” (direction of change) of your movement and the difference between velocities will give you the “acceleration” (speed of change). This way you can tell not only which direction the controller moved, but also how “hard” you moved it.
Might be useful for putting some expression into a knob movement - tweak the filter cutoff in proportion to the speed of a change will give you an interesting “blurp” on fast movements. Not a convincing example, but something to play with!
You might also want to investigate filtering the resulting velocity and acceleration values. Keep a rolling buffer of the last , say, 4 values and return the sum of them. This doesn’t work quite how you think it should as MIDI doesn’t generate events when there’s no movement, but it will tell you what the cumulative acceleration is.
The best filter would sum all events over slices of time, called buckets. Divide time into sections using a regular timer that fires a rule to move all buckets one step to the left. You then sum all the buckets. If you get lots of events in a burst you get a bucket full of events. No movement, you get an empty bucket. That’s proper time-filtered response with a quick ramp up as events flood in and a smooth fall off as the buckets slowly empty out. Just like VU meter falloff.
You can shape the falloff by doing a weighted sum of events. First bucket is 60% of the power, second bucket is 20%, third bucket is 8% etc, e.g.
A * 0.8 + b * 0.6 + c * 0.08 + …
Now you have entered the world of FIR (Finite Impulse Response) filters…